commons-math-2.2-src/test-jar.xml100644 1750 1750 11516 11532241247 14365 0ustar 0 0 JAVA ENVIRONMENT **************************Java runtime version***************************** ${java.runtime.version} **************************Java class path********************************** ${java.class.path} **************************Java home**************************************** ${java.home} *************************Java library path******************************* Java library path: ${java.library.path} =========================================================================== ================================= WARNING ================================ Junit isn't present in your ${ANT_HOME}/lib directory. Tests not executed. ========================================================================== commons-math-2.2-src/LICENSE.txt100644 1750 1750 45633 11532241247 13744 0ustar 0 0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. APACHE COMMONS MATH DERIVATIVE WORKS: The Apache commons-math library includes a number of subcomponents whose implementation is derived from original sources written in C or Fortran. License terms of the original sources are reproduced below. =============================================================================== For the lmder, lmpar and qrsolv Fortran routine from minpack and translated in the LevenbergMarquardtOptimizer class in package org.apache.commons.math.optimization.general Original source copyright and license statement: Minpack Copyright Notice (1999) University of Chicago. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the University of Chicago, as Operator of Argonne National Laboratory. Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. 5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. =============================================================================== Copyright and license statement for the odex Fortran routine developed by E. Hairer and G. Wanner and translated in GraggBulirschStoerIntegrator class in package org.apache.commons.math.ode.nonstiff: Copyright (c) 2004, Ernst Hairer 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 OR 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. =============================================================================== Copyright and license statement for the original lapack fortran routines translated in EigenDecompositionImpl class in package org.apache.commons.math.linear: Copyright (c) 1992-2008 The University of Tennessee. All rights reserved. $COPYRIGHT$ Additional copyrights may follow $HEADER$ 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 listed in this license in the documentation and/or other materials provided with the distribution. - Neither the name of the copyright holders 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR 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. =============================================================================== Copyright and license statement for the original Mersenne twister C routines translated in MersenneTwister class in package org.apache.commons.math.random: Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR 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. commons-math-2.2-src/license-header.txt100644 1750 1750 1443 11532241247 15501 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ commons-math-2.2-src/NOTICE.txt100644 1750 1750 5325 11532241247 13615 0ustar 0 0 Apache Commons Math Copyright 2001-2011 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). =============================================================================== The BracketFinder (package org.apache.commons.math.optimization.univariate) and PowellOptimizer (package org.apache.commons.math.optimization.general) classes are based on the Python code in module "optimize.py" (version 0.5) developed by Travis E. Oliphant for the SciPy library (http://www.scipy.org/) Copyright © 2003-2009 SciPy Developers. =============================================================================== The LinearConstraint, LinearObjectiveFunction, LinearOptimizer, RelationShip, SimplexSolver and SimplexTableau classes in package org.apache.commons.math.optimization.linear include software developed by Benjamin McCann (http://www.benmccann.com) and distributed with the following copyright: Copyright 2009 Google Inc. =============================================================================== This product includes software developed by the University of Chicago, as Operator of Argonne National Laboratory. The LevenbergMarquardtOptimizer class in package org.apache.commons.math.optimization.general includes software translated from the lmder, lmpar and qrsolv Fortran routines from the Minpack package Minpack Copyright Notice (1999) University of Chicago. All rights reserved =============================================================================== The GraggBulirschStoerIntegrator class in package org.apache.commons.math.ode.nonstiff includes software translated from the odex Fortran routine developed by E. Hairer and G. Wanner. Original source copyright: Copyright (c) 2004, Ernst Hairer =============================================================================== The EigenDecompositionImpl class in package org.apache.commons.math.linear includes software translated from some LAPACK Fortran routines. Original source copyright: Copyright (c) 1992-2008 The University of Tennessee. All rights reserved. =============================================================================== The MersenneTwister class in package org.apache.commons.math.random includes software translated from the 2002-01-26 version of the Mersenne-Twister generator written in C by Makoto Matsumoto and Takuji Nishimura. Original source copyright: Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved =============================================================================== The complete text of licenses and disclaimers associated with the the original sources enumerated above at the time of code translation are in the LICENSE.txt file. commons-math-2.2-src/pom.xml100644 1750 1750 25654 11532241414 13433 0ustar 0 0 org.apache.commons commons-parent 18 4.0.0 org.apache.commons commons-math 2.2 Commons Math 2003 The Math project is a library of lightweight, self-contained mathematics and statistics components addressing the most common practical problems not immediately available in the Java programming language or commons-lang. http://commons.apache.org/math/ jira http://issues.apache.org/jira/browse/MATH scm:svn:http://svn.apache.org/repos/asf/commons/proper/math/trunk scm:svn:https://svn.apache.org/repos/asf/commons/proper/math/trunk http://svn.apache.org/viewvc/commons/proper/math/trunk people.apache.org Commons Math scp://people.apache.org/www/commons.apache.org/math Mikkel Meyer Andersen mikl mikl at apache dot org Bill Barker billbarker billbarker at apache dot org Albert Davidson Chou achou achou at apache dot org Mark Diggory mdiggory mdiggory at apache dot org Robert Burrell Donkin rdonkin rdonkin at apache dot org Tim O'Brien tobrien tobrien at apache dot org Luc Maisonobe luc luc at apache dot org J. Pietschmann pietsch j3322ptm at yahoo dot de Dimitri Pourbaix dimpbx dimpbx at apache dot org Phil Steitz psteitz psteitz at apache dot org Brent Worden brentworden brentworden at apache dot org Gilles Sadowski erans erans at apache dot org C. Scott Ananian Mark Anderson Rémi Arntzen Michael Bjorkegren John Bollinger Cyril Briquet Paul Cowan Benjamin Croizet Larry Diamond Rodrigo di Lorenzo Lopes Hasan Diwan Ted Dunning John Gant Ken Geis Bernhard Grünewaldt Elliotte Rusty Harold Matthias Hummel Ismael Juma Eugene Kirpichov Piotr Kochanski Bob MacCallum Jake Mannix Benjamin McCann J. Lewis Muir Fredrik Norin Sujit Pal Todd C. Parnell Andreas Rieger Bill Rossi Matthew Rowles Joni Salonen Christopher Schuck Christian Semrau David Stefka Mauro Talevi Kim van der Linde Jörg Weimar Xiaogang Zhang junit junit 4.4 test math 2.2 RC6 MATH 12310485 1.5 1.5 UTF-8 UTF-8 info org.apache.maven.plugins maven-surefire-plugin **/*Test.java **/*TestBinary.java **/*TestPermutations.java **/*AbstractTest.java maven-assembly-plugin 2.2-beta-4 src/main/assembly/src.xml src/main/assembly/bin.xml org.codehaus.mojo clirr-maven-plugin 2.3 ${basedir} META-INF NOTICE.txt LICENSE.txt ${basedir}/src/main/resources/META-INF/localization META-INF/localization org.codehaus.mojo findbugs-maven-plugin 2.1 Normal Default ${basedir}/findbugs-exclude-filter.xml org.apache.maven.plugins maven-changes-plugin 2.3 ${basedir}/src/site/xdoc/changes.xml %URL%/%ISSUE% templates changes-report org.apache.maven.plugins maven-checkstyle-plugin 2.3 ${basedir}/checkstyle.xml false ${basedir}/license-header.txt org.codehaus.mojo clirr-maven-plugin 2.2.3 ${minSeverity} commons-math-2.2-src/RELEASE-NOTES.txt100644 1750 1750 26731 11532241247 14626 0ustar 0 0 Apache Commons Math 2.2 RELEASE NOTES This is primarily a maintenance release, but it also includes new features and enhancements. Users of version 2.1 are encouraged to upgrade to 2.2, as this release includes some important bug fixes. See the detailed list of changes below for full description of all bug fixes and enhancements. This release contains some minor compatibility breaks with version 2.1 in some internal classes but none of them are in APIs likely to be accessed by user code: the MessagesResources_fr class has been removed (replaced by a properties file); the arguments of the EventState.reinitializeBegin method have changed; some protected fields which already had public accessors in AbstractStepInterpolator have been replaced. There is a behavior change that users of the multiple regression classes should be aware of. In version 2.1, there was no way to estimate models without intercept terms, and, while this was not clear from the documentation, design (X) matrices needed to include initial unitary columns. In 2.2, initial unitary columns are not necessary and whether or not models include intercept terms is configurable. See the change log and javadoc for the classes in org.apache.commons.math.stat.regression for details. The major new features are: a new FastMath class, both faster, more accurate and with a few additional functions than StrictMath and Math; a new package for floating point arbitrary precision computing, including high level functions like exponential, sine, square root ...; new linear and tricubic interpolators; a new Gaussian curve fitter; a new erfc function; characteristic support for distributions; a set of new Well Equidistributed Long-period Linear (WELL) random generators. Changes in this version include: New features: o MATH-364: Added complementary error function, erfc. Thanks to Christian Winter. o MATH-385: Added characteristic support to distributions, including methods to return numerical estimates of the mean and variance and upper and lower bounds of support. In version 2.2, methods returning distribution characteristics have been added only to the implementation classes. In version 3, supporting methods have been added to the abstract base classes and distribution interfaces. o MATH-440: Created "MathUserException" class to convey cause of failure between layers of user code separated by a layer of Commons-Math code. o MATH-419: Added new random number generators from the Well Equidistributed Long-period Linear (WELL). o MATH-412: Added the dfp library providing arbitrary precision floating point computation in the spirit of IEEE 854-1987 (not exactly as it uses base 1000 instead of base 10). In addition to finite numbers, infinities and NaNs are available (but there are no subnormals). All IEEE 854-1987 rounding modes and signaling flags are supported. The available operations are +, -, *, / and the available functions are sqrt, sin, cos, tan, asin, acos, atan, exp, log. Thanks to Bill Rossi. o MATH-375: Added faster and more accurate version of traditional mathematical functions in a FastMath class intended to be a drop-in replacement for java.util.Math at source-level. Some functions still directly delegates to Math but this will improve with time. Some functions like exp may be twice as fast (even 3 times faster on some processors). Sine, cosine or power functions show typical speedups of 1.5 times faster or more. Thanks to Bill Rossi. o MATH-400: Added support for Gaussian curve fitting. Thanks to J. Lewis Muir. o MATH-388: Added a feature allowing error estimation to be computed only on a subset of Ordinary Differential Equations, considered as the main set, the remaining equations being considered only as an extension set that should not influence the ODE integration algorithm o MATH-379: Created "MultidimensionalCounter" class. o MATH-378: Implementation of linear interpolation. Thanks to Matthew Rowles. o MATH-370: Added new "equalsIncludingNaN" methods that have the same semantics as the old "equals" methods. The semantics of the old methods will be modified (in the next major release) such that NaNs are not considered equal (to be more compliant with IEEE754). o MATH-366: Implementation of tricubic interpolation. Fixed Bugs: o MATH-505: TestUtils is thread-hostile. Deprecate the getters and setters. o MATH-471: MathUtils.equals(double, double) does not work properly for floats - add equivalent (float, float) methods and basic tests o MATH-467: Fixed an awkward statement that triggered a false positive warning. o MATH-456: Modified erf (and erfc) to return extreme values for x with abs(x) > 40. For these arguments, the true value is indistinguishable from an extrema as a double. o MATH-414: Modified NormalDistributionImpl.cumulativeProbability to return 0 or 1, respectively for values more than 40 standard deviations from the mean. For these values, the actual probability is indistinguishable from 0 or 1 as a double. Top coding improves performance for extreme values and prevents convergence exceptions. o MATH-380: Deprecated the whole ode.jacobians package. It is clumsy and difficult to use. It will be replaced by a completely rewritten implementation in 3.0, which will be more tightly bound to the top level ode package o MATH-426: Added a normalization feature to transform samples so they have zero mean and unit standard deviation Thanks to Erik van Ingen. o MATH-429: Fixed k-means++ to add several strategies to deal with empty clusters that may appear during iterations o MATH-391: Fixed an error preventing zero length vectors to be built by some constructors o MATH-421: Fixed an error preventing ODE solvers to be restarted after they have been stopped by a discrete event o MATH-415: Fixed lost cause in MathRuntimeException.createInternalError. Note that the message is still the default message for internal errors asking to report a bug to commons-math JIRA tracker. In order to retrieve the message from the root cause, one has to get the cause itself by getCause(). o MATH-411: Modified multiple regression newSample methods to ensure that by default in all cases, regression models are estimated with intercept terms. Prior to the fix for this issue, newXSampleData(double[][]), newSampleData(double[], double[][]) and newSampleData(double[], double[][], double[][]) all required columns of "1's" to be inserted into the x[][] arrays to create a model with an intercept term; while newSampleData(double[], int, int) created a model including an intercept term without requiring the unitary column. All methods have been changed to eliminate the need for users to add unitary columns to specify regression models. Users of OLSMultipleLinearRegression or GLSMultipleLinearRegression versions 2.0 or 2.1 should either verify that their code either does not use the first set of data loading methods above or set the noIntercept property to true on estimated models to get the previous behavior. o MATH-386: Added R-squared and adjusted R-squared statistics to OLSMultipleLinearRegression. o MATH-392: Corrected the formula used for Y variance returned by calculateYVariance and associated methods in multiple regression classes (AbstractMultipleLinearRegression, OLSMultipleLinearRegression, GLSMultipleLinearRegression). These methods previously returned estimates of the variance in the model error term. New "calulateErrorVariance" methods have been added to compute what was previously returned by calculateYVariance. Thanks to Mark Devaney. o MATH-406: Bug fixed in Levenberg-Marquardt (handling of weights). o MATH-405: Bug fixed in Levenberg-Marquardt (consistency of current). o MATH-377: Bug fixed in chi-square computation in AbstractLeastSquaresOptimizer. o MATH-395: Fixed several bugs in "BrentOptimizer". o MATH-393: Fixed inconsistency in return values in "MultiStartUnivariateRealOptimizer". o MATH-382: Fixed bug in precondition check (method "setMicrosphereElements"). o MATH-361: Improved localization of error messages. o MATH-376: Allow multiple optimizations with a default simplex. o MATH-352: Added a setQRRankingThreshold method to Levenberg-Marquardt optimizer to improve robustness of rank determination. o MATH-362: Fixed Levenberg-Marquardt optimizer that did not use the vectorial convergence checker. Now this optimizer can use either the general vectorial convergence checker or its own specialized convergence settings. o MATH-371: Fixed loss of significance error in PersonsCorrelation p-value computation causing p-values smaller than the machine epsilon (~1E-16) to be reported as 0. Thanks to Kevin Childs. o MATH-369: Fix NullPointerException in BisectionSolver.solve(f, min, max, initial) Thanks to Sasun Pundev. o MATH-368: Fix spelling of getSparcity [sic] method of OpenMapRealVector o MATH-367: Fix problem with the default sparseIterator when a RealVector has exactly one non-zero entry Thanks to Albert Huang. Changes: o MATH-384: Added a constructor and addValues(double[]) methods allowing DescriptiveStatistics to be initialized with values from a double[] array. Similarly enhanced ResizeableDoubleArray. o MATH-448: Added a getUniqueCount() method to Frequency to return the number of unique values included in the frequency table. Thanks to Patrick Meyer. o MATH-420: Added toString() override to StatisticalSummaryValues. o MATH-417: Improved Percentile performance by using a selection algorithm instead of a complete sort, and by allowing caching data array and pivots when several different percentiles are desired o MATH-409: Made intercept / no intercept configurable in multiple regression classes. By default, regression models are estimated with an intercept term. When the "noIntercept" property is set to true, regression models are estimated without intercepts. o MATH-361: Created package "exception" to contain the new exceptions hierarchy. Created package "exception.util": utilities for the exception classes (e.g. managing the localization of error messages). Default policy for dealing with invalid null references: raise a "NullArgumentException" (subclass of "IllegalArgumentException"). o MATH-310: Added random data generation methods to RandomDataImpl for the remaining distributions in the distributions package. Added a generic nextInversionDeviate method that takes a discrete or continuous distribution as argument and generates a random deviate from the distribution. Also added sampling methods based on the implementations in RandomDataImpl to distributions. o MATH-365: Deprecated SmoothingBicubicSplineInterpolator and SmoothingBicubicSplineInterpolatorTest. Added BicubicSplineInterpolator and BicubicSplineInterpolatorTest. Added SmoothingPolynomialBicubicSplineInterpolator and SmoothingPolynomialBicubicSplineInterpolatorTest. Added method to clear the list of observations in PolynomialFitter. For complete information on Commons Math, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache Commons Math website: http://commons.apache.org/math/ commons-math-2.2-src/build.xml100644 1750 1750 33330 11532241247 13731 0ustar 0 0 commons-math-2.2-src/checkstyle.xml100644 1750 1750 15664 11532241247 15002 0ustar 0 0 commons-math-2.2-src/findbugs-exclude-filter.xml100644 1750 1750 25167 11532241247 17356 0ustar 0 0 commons-math-2.2-src/src/ 40755 1750 1750 0 11532241247 12560 5ustar 0 0 commons-math-2.2-src/src/test/ 40755 1750 1750 0 11532241244 13534 5ustar 0 0 commons-math-2.2-src/src/test/R/ 40755 1750 1750 0 11532241241 15142 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/ 40755 1750 1750 0 11532241244 16756 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/ 40755 1750 1750 0 11532241244 17545 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/ 40755 1750 1750 0 11532241244 20766 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/ 40755 1750 1750 0 11532241244 22441 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/math/ 40755 1750 1750 0 11532241244 23372 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/math/random/ 40755 1750 1750 0 11532241244 24652 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/ 40755 1750 1750 0 11532241244 24345 5ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/ 40755 1750 1750 0 11532241244 25256 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/ 40755 1750 1750 0 11532241241 15662 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/ 40755 1750 1750 0 11532241241 16451 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/ 40755 1750 1750 0 11532241241 17672 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/ 40755 1750 1750 0 11532241241 21345 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ 40755 1750 1750 0 11532241244 22301 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/ 40755 1750 1750 0 11532241243 24454 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/random/ 40755 1750 1750 0 11532241241 23556 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/ 40755 1750 1750 0 11532241243 23552 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/ 40755 1750 1750 0 11532241242 24100 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/ 40755 1750 1750 0 11532241243 23253 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/data/ 40755 1750 1750 0 11532241243 24164 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/clustering/ 40755 1750 1750 0 11532241243 25432 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/ 40755 1750 1750 0 11532241243 25574 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/ 40755 1750 1750 0 11532241243 27271 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/ 40755 1750 1750 0 11532241243 26527 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/ 40755 1750 1750 0 11532241243 27073 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/ 40755 1750 1750 0 11532241243 25433 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/ 40755 1750 1750 0 11532241243 25574 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/ranking/ 40755 1750 1750 0 11532241243 24704 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/ 40755 1750 1750 0 11532241243 25211 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/ 40755 1750 1750 0 11532241242 24132 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/ 40755 1750 1750 0 11532241241 25024 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/univariate/ 40755 1750 1750 0 11532241241 27173 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/ 40755 1750 1750 0 11532241241 26470 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/linear/ 40755 1750 1750 0 11532241241 26276 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/ 40755 1750 1750 0 11532241241 26276 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/ 40755 1750 1750 0 11532241241 26441 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/ 40755 1750 1750 0 11532241242 23046 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/jacobians/ 40755 1750 1750 0 11532241242 24777 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ 40755 1750 1750 0 11532241242 24674 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/events/ 40755 1750 1750 0 11532241242 24352 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/ 40755 1750 1750 0 11532241242 24660 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/ 40755 1750 1750 0 11532241242 24275 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/util/ 40755 1750 1750 0 11532241242 25252 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/dfp/ 40755 1750 1750 0 11532241242 23050 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ 40755 1750 1750 0 11532241241 25015 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/ 40755 1750 1750 0 11532241241 24121 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/ 40755 1750 1750 0 11532241241 27010 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/ 40755 1750 1750 0 11532241241 25616 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/ 40755 1750 1750 0 11532241241 26467 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/ 40755 1750 1750 0 11532241241 26444 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ 40755 1750 1750 0 11532241242 23746 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/ 40755 1750 1750 0 11532241242 24104 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/special/ 40755 1750 1750 0 11532241241 23716 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/util/ 40755 1750 1750 0 11532241244 23256 5ustarlucluc 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/transform/ 40755 1750 1750 0 11532241243 24313 5ustarlucluc 0 0 commons-math-2.2-src/src/site/ 40755 1750 1750 0 11532241404 13517 5ustar 0 0 commons-math-2.2-src/src/site/xdoc/ 40755 1750 1750 0 11532241247 15671 5ustarlucluc 0 0 commons-math-2.2-src/src/site/xdoc/userguide/ 40755 1750 1750 0 11532241247 17665 5ustarlucluc 0 0 commons-math-2.2-src/src/site/resources/ 40755 1750 1750 0 11532241247 16746 5ustarlucluc 0 0 commons-math-2.2-src/src/site/resources/userguide/ 40755 1750 1750 0 11532241247 20742 5ustarlucluc 0 0 commons-math-2.2-src/src/site/resources/style/ 40755 1750 1750 0 11532241247 20106 5ustarlucluc 0 0 commons-math-2.2-src/src/site/resources/images/ 40755 1750 1750 0 11532241247 20213 5ustarlucluc 0 0 commons-math-2.2-src/src/main/ 40755 1750 1750 0 11532241247 13504 5ustar 0 0 commons-math-2.2-src/src/main/assembly/ 40755 1750 1750 0 11532241244 16530 5ustarlucluc 0 0 commons-math-2.2-src/src/main/resources/ 40755 1750 1750 0 11532241247 16726 5ustarlucluc 0 0 commons-math-2.2-src/src/main/resources/META-INF/ 40755 1750 1750 0 11532241247 20066 5ustarlucluc 0 0 commons-math-2.2-src/src/main/resources/META-INF/localization/ 40755 1750 1750 0 11532241247 22556 5ustarlucluc 0 0 commons-math-2.2-src/src/main/resources/templates/ 40755 1750 1750 0 11532241247 20724 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/ 40755 1750 1750 0 11532241244 15632 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/ 40755 1750 1750 0 11532241244 16421 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/ 40755 1750 1750 0 11532241244 17642 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/ 40755 1750 1750 0 11532241244 21315 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ 40755 1750 1750 0 11532241247 22251 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/ 40755 1750 1750 0 11532241245 24423 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/random/ 40755 1750 1750 0 11532241245 23527 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/ 40755 1750 1750 0 11532241245 23521 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/ 40755 1750 1750 0 11532241244 24047 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ 40755 1750 1750 0 11532241247 23224 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/ 40755 1750 1750 0 11532241246 25402 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/ 40755 1750 1750 0 11532241247 25545 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/ 40755 1750 1750 0 11532241247 27242 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/ 40755 1750 1750 0 11532241246 26477 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/ 40755 1750 1750 0 11532241247 27044 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/ 40755 1750 1750 0 11532241246 25403 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/ 40755 1750 1750 0 11532241246 25544 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/ 40755 1750 1750 0 11532241247 24655 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/ 40755 1750 1750 0 11532241247 25162 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/ 40755 1750 1750 0 11532241244 24101 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/ 40755 1750 1750 0 11532241244 24774 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/ 40755 1750 1750 0 11532241244 27143 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/ 40755 1750 1750 0 11532241244 26440 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/ 40755 1750 1750 0 11532241244 26246 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/ 40755 1750 1750 0 11532241244 26246 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/ 40755 1750 1750 0 11532241244 26411 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/ 40755 1750 1750 0 11532241246 23017 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/ 40755 1750 1750 0 11532241246 24750 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ 40755 1750 1750 0 11532241246 24645 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/ 40755 1750 1750 0 11532241246 24323 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/ 40755 1750 1750 0 11532241246 24631 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/ 40755 1750 1750 0 11532241244 24244 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/ 40755 1750 1750 0 11532241244 25221 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/ 40755 1750 1750 0 11532241246 23021 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ 40755 1750 1750 0 11532241245 24766 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/ 40755 1750 1750 0 11532241246 24073 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/ 40755 1750 1750 0 11532241245 26761 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/ 40755 1750 1750 0 11532241246 25570 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/ 40755 1750 1750 0 11532241246 26441 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/ 40755 1750 1750 0 11532241245 26415 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/ 40755 1750 1750 0 11532241246 23717 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/ 40755 1750 1750 0 11532241244 24053 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/special/ 40755 1750 1750 0 11532241245 23667 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/util/ 40755 1750 1750 0 11532241247 23226 5ustarlucluc 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/ 40755 1750 1750 0 11532241245 24262 5ustarlucluc 0 0 commons-math-2.2-src/src/test/R/ChiSquareDistributionTestCases.R100644 1750 1750 7707 11532241241 23500 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate ChiSquare distribution tests in # org.apache.commons.math.distribution.ChiSquareDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, df, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pchisq(point, df, log = FALSE) } output <- c("Distribution test df = ", df) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, df, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dchisq(point, df, log = FALSE) } output <- c("Density test df = ", df) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, df, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qchisq(point, df, log = FALSE) } output <- c("Quantile test df = ", df) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("ChiSquare Distribution test cases\n") df <- 5 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.0115379817652, 0.0415948507811, 0.0665060119842, 0.0919455953114, 0.121472591024, 0.000433630076361, 0.00412780610309, 0.00999340341045, 0.0193246438937, 0.0368460089216) distributionPoints <- c(0.210212602629, 0.554298076728, 0.831211613487, 1.14547622606, 1.61030798696, 20.5150056524, 15.0862724694, 12.8325019940, 11.0704976935, 9.23635689978) verifyQuantiles(distributionValues, distributionPoints, df, tol) verifyDistribution(distributionPoints, distributionValues, df, tol) verifyDensity(distributionPoints, densityValues, df, tol) df <- .1 distributionPoints <- c(1.16892641146e-60, 1.16892641146e-40, 1.06313237798e-32, 1.11477509638e-26, 1.16892641146e-20, 5.47291719746, 2.17525480018, 1.13434752351, 0.531864604852, 0.152634227818) verifyQuantiles(distributionValues, distributionPoints, df, tol) verifyDistribution(distributionPoints, distributionValues, df, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/chiSquareTestCases100644 1750 1750 7624 11532241241 20736 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate ChiSquare tests in # org.apache.commons.math.stat.inference.ChiSquareTestTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used #chisq.test(x, y = NULL, correct = TRUE, # p = rep(1/length(x), length(x)), # simulate.p.value = FALSE, B = 2000) #------------------------------------------------------------------------------ tol <- 1E-9 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions verifyTable <- function(counts, expectedP, expectedStat, tol, desc) { results <- chisq.test(counts) if (assertEquals(expectedP, results$p.value, tol, "p-value")) { displayPadded(c(desc," p-value test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " p-value test"), FAILED, WIDTH) } if (assertEquals(expectedStat, results$statistic, tol, "ChiSquare Statistic")) { displayPadded(c(desc, " chi-square statistic test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " chi-square statistic test"), FAILED, WIDTH) } } verifyHomogeneity <- function(obs, exp, expectedP, expectedStat, tol, desc) { results <- chisq.test(obs,p=exp,rescale.p=TRUE) chi <- results$statistic p <- results$p.value if (assertEquals(expectedP, p, tol, "p-value")) { displayPadded(c(desc, " p-value test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " p-value test"), FAILED, WIDTH) } if (assertEquals(expectedStat, chi, tol, "ChiSquare Statistic")) { displayPadded(c(desc, " chi-square statistic test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " chi-square statistic test"), FAILED, WIDTH) } } cat("ChiSquareTest test cases\n") observed <- c(10, 9, 11) expected <- c(10, 10, 10) verifyHomogeneity(observed, expected, 0.904837418036, 0.2, tol, "testChiSquare1") observed <- c(500, 623, 72, 70, 31) expected <- c(485, 541, 82, 61, 37) verifyHomogeneity(observed, expected, 0.06051952647453607, 9.023307936427388, tol, "testChiSquare2") observed <- c(2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899) expected <- c(3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0, 232921.0, 437665.75) verifyHomogeneity(observed, expected, 0, 114875.90421929007, tol, "testChiSquareLargeTestStatistic") counts <- matrix(c(40, 22, 43, 91, 21, 28, 60, 10, 22), nc = 3); verifyTable(counts, 0.000144751460134, 22.709027688, tol, "testChiSquareIndependence1") counts <- matrix(c(10, 15, 30, 40, 60, 90), nc = 3); verifyTable(counts, 0.918987499852, 0.168965517241, tol, "testChiSquareIndependence2") counts <- matrix(c(40, 0, 4, 91, 1, 2, 60, 2, 0), nc = 3); verifyTable(counts, 0.0462835770603, 9.67444662263, tol, "testChiSquareZeroCount") displayDashes(WIDTH) commons-math-2.2-src/src/test/R/anovaTestCases100644 1750 1750 5631 11532241241 20112 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Binomial distribution tests in # org.apache.commons.math.distribution.BinomialDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # anova(model) <- anova # lm(frame) <- linear model #------------------------------------------------------------------------------ tol <- 1E-12 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions options(digits=16) # override number of digits displayed # function to verify anova computations verifyAnova <- function(frame, expectedP, expectedF, frameName) { a <- anova(lm(frame)) p <- a$"Pr(>F)"[1] f <- a$"F value"[1] output <- c("P-value test frame = ", frameName) if (assertEquals(expectedP,p,tol,"P value")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("F-value test frame = ", frameName) if (assertEquals(expectedF,f,tol,"F value")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Anova test cases\n") classA <- c(93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0) classB <- c(99.0, 92.0, 102.0, 100.0, 102.0, 89.0) classC <- c(110.0, 115.0, 111.0, 117.0, 128.0, 117.0) threeClasses = data.frame(val = c(classA, classB, classC), class=c(rep("classA", length(classA)), rep("classB", length(classB)), rep("classC", length(classC)))) verifyAnova(threeClasses,6.959446e-06, 24.67361709460624, "Three classes") twoClasses = data.frame(val = c(classA, classB), class=c(rep("classA", length(classA)), rep("classB", length(classB)))) verifyAnova(twoClasses, 0.904212960464, 0.0150579150579, "Two classes") displayDashes(WIDTH)commons-math-2.2-src/src/test/R/testFunctions100644 1750 1750 6366 11532241241 20045 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # # Utility functions used in R comparison tests. # #------------------------------------------------------------------------------ # Global constants #------------------------------------------------------------------------------ WIDTH <- 80 # screen size constant for display functions SUCCEEDED <- "SUCCEEDED" FAILED <- "FAILED" options(digits=12) # display 12 digits throughout #------------------------------------------------------------------------------ # Comparison functions #------------------------------------------------------------------------------ # Tests to see if and are within of # one another in the sup norm. # # Returns 1 if no pair of corresponding non-NULL, non-NaN, non-na entries # differs by more than abs and NULLs, NaNs, na's correspond; # otherwise displays and returns 0. # Works for both vectors and scalar values. # assertEquals <- function(expected, observed, tol, message) { failed <- 0 if (any(is.na(observed) != is.na(expected))) { failed <- 1 } if (any(is.null(observed) != is.null(expected))) { failed <- 1 } if (any(is.nan(expected) != is.nan(observed))) { failed <- 1 } if (any(is.na(expected) != is.na(observed))) { failed <- 1 } if (!failed) { if(any(abs(observed - expected) > tol, na.rm = TRUE)) { failed <- 1 } } if (failed) { cat("FAILURE: ",message,"\n") cat("EXPECTED: ",expected,"\n") cat("OBSERVED: ",observed,"\n") cat("DIFF: ",observed - expected,"\n") cat("TOLERANCE: ",tol,"\n") } return(!failed) } #------------------------------------------------------------------------------ # Display functions #------------------------------------------------------------------------------ # Displays n-col dashed line. # displayDashes <- function(n) { cat(rep("-",n),"\n",sep='') return(1) } #------------------------------------------------------------------------------ # Displays ...... with enough dots in between to make cols, # followed by a new line character. Blows up if is longer than # cols by itself. # # Expects and to be strings (character vectors). # displayPadded <- function(start, end, n) { len = sum(nchar(start)) + sum(nchar(end)) cat(start, rep(".", n - len), end, "\n",sep='') return(1) } commons-math-2.2-src/src/test/R/hypergeometricTestCases100644 1750 1750 11756 11532241241 22061 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Hypergeometric distribution tests in # org.apache.commons.math.distribution.HypergeometricDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # dhyper(x, m, n, k, log = FALSE) <- density # phyper(q, m, n, k, lower.tail = TRUE, log.p = FALSE) <- distribution # qhyper(p, m, n, k, lower.tail = TRUE, log.p = FALSE) <- quantiles #------------------------------------------------------------------------------ tol <- 1E-6 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions # function to verify density computations verifyDensity <- function(points, expected, good, bad, selected, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dhyper(point, good, bad, selected) } output <- c("Density test good = ", good, ", bad = ", bad, ", selected = ",selected) if (assertEquals(expected,rDensityValues,tol,"Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify distribution computations verifyDistribution <- function(points, expected, good, bad, selected, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- phyper(point, good, bad, selected) } output <- c("Distribution test good = ", good, ", bad = ", bad, ", selected = ",selected) if (assertEquals(expected,rDistValues,tol,"Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Hypergeometric test cases\n") good <- 5 bad <- 5 selected <- 5 densityPoints <- c(-1, 0, 1, 2, 3, 4, 5, 10) densityValues <- c(0, 0.003968, 0.099206, 0.396825, 0.396825, 0.099206, 0.003968, 0) distributionValues <- c(0, .003968, .103175, .50000, .896825, .996032, 1.00000, 1) #Eliminate p=1 case because it will mess up adjustement below inverseCumPoints <- c(0, 0.001, 0.010, 0.025, 0.050, 0.100, 0.999, 0.990, 0.975, 0.950, 0.900) inverseCumValues <- c(-1, -1, 0, 0, 0, 0, 4, 3, 3, 3, 3) verifyDensity(densityPoints, densityValues, good, bad, selected, tol) verifyDistribution(densityPoints, distributionValues, good, bad, selected, tol) i <- 0 rInverseCumValues <- rep(0,length(inverseCumPoints)) for (point in inverseCumPoints) { i <- i + 1 rInverseCumValues[i] <- qhyper(point, good, bad, selected) } output <- c("Inverse Distribution test good = ", good, ", bad = ", bad, ", selected = ", selected) # R defines quantiles from the right, need to subtract one if (assertEquals(inverseCumValues, rInverseCumValues-1, tol, "Inverse Dist Values")) { displayPadded(output, SUCCEEDED, 80) } else { displayPadded(output, FAILED, 80) } # Degenerate cases good <- 5 bad <- 0 selected <- 3 densityPoints <- c(-1, 0, 1, 3, 10) densityValues <- c(0, 0, 0, 1, 0) distributionValues <- c(0, 0, 0, 1, 1) verifyDensity(densityPoints, densityValues, good, bad, selected, tol) verifyDistribution(densityPoints, distributionValues, good, bad, selected, tol) good <- 0 bad <- 5 selected <- 3 densityPoints <- c(-1, 0, 1, 3, 10) densityValues <- c(0, 1, 0, 0, 0) distributionValues <- c(0, 1, 1, 1, 1) verifyDensity(densityPoints, densityValues, good, bad, selected, tol) verifyDistribution(densityPoints, distributionValues, good, bad, selected, tol) good <- 3 bad <- 2 selected <- 5 densityPoints <- c(-1, 0, 1, 3, 10) densityValues <- c(0, 0, 0, 1, 0) distributionValues <- c(0, 0, 0, 1, 1) verifyDensity(densityPoints, densityValues, good, bad, selected, tol) verifyDistribution(densityPoints, distributionValues, good, bad, selected, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/multipleOLSRegressionTestCases100644 1750 1750 30445 11532241241 23301 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate OLS multiple regression tests in # org.apache.commons.math.stat.regression.OLSMultipleLinearRegressionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #------------------------------------------------------------------------------ tol <- 1E-8 # default error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions options(digits=16) # override number of digits displayed # function to verify OLS computations verifyRegression <- function(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expecteAdjRSquare, modelName) { betaHat <- as.vector(coefficients(model)) residuals <- as.vector(residuals(model)) errors <- as.vector(as.matrix(coefficients(summary(model)))[,2]) stdError <- summary(model)$sigma rSquare <- summary(model)$r.squared adjRSquare <- summary(model)$adj.r.squared output <- c("Parameter test dataset = ", modelName) if (assertEquals(expectedBeta,betaHat,tol,"Parameters")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("Residuals test dataset = ", modelName) if (assertEquals(expectedResiduals,residuals,tol,"Residuals")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("Errors test dataset = ", modelName) if (assertEquals(expectedErrors,errors,tol,"Errors")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("Standard Error test dataset = ", modelName) if (assertEquals(expectedStdError,stdError,tol,"Regression Standard Error")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("RSquared test dataset = ", modelName) if (assertEquals(expectedRSquare,rSquare,tol,"RSquared")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- c("Adjusted RSquared test dataset = ", modelName) if (assertEquals(expecteAdjRSquare,adjRSquare,tol,"Adjusted RSquared")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Multiple regression OLS test cases\n") # Perfect fit x1 <- c(0,2,0,0,0,0) x2 <- c(0,0,3,0,0,0) x3 <- c(0,0,0,4,0,0) x4 <- c(0,0,0,0,5,0) x5 <- c(0,0,0,0,0,6) y <- c(11, 12, 13, 14, 15, 16) model <- lm(y ~ x1 + x2 + x3 + x4 + x5) expectedBeta <- c(11.0,0.5,0.666666666666667,0.75,0.8,0.8333333333333333) expectedResiduals <- c(0,0,0,0,0,0) expectedErrors <- c(NaN,NaN,NaN,NaN,NaN,NaN) expectedStdError <- NaN expectedRSquare <- 1 expectedAdjRSquare <- NaN verifyRegression(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expectedAdjRSquare, "perfect fit") # Longley # # Data Source: J. Longley (1967) "An Appraisal of Least Squares Programs for the # Electronic Computer from the Point of View of the User", # Journal of the American Statistical Association, # vol. 62. September, pp. 819-841. # # Certified values (and data) are from NIST: # http://www.itl.nist.gov/div898/strd/lls/data/LINKS/DATA/Longley.dat # design <- matrix(c(60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962), nrow = 16, ncol = 7, byrow = TRUE) y <- design[,1] x1 <- design[,2] x2 <- design[,3] x3 <- design[,4] x4 <- design[,5] x5 <- design[,6] x6 <- design[,7] model <- lm(y ~ x1 + x2 + x3 + x4 + x5 + x6) estimates <- matrix(c(-3482258.63459582,890420.383607373, 15.0618722713733,84.9149257747669, -0.358191792925910E-01,0.334910077722432E-01, -2.02022980381683,0.488399681651699, -1.03322686717359,0.214274163161675, -0.511041056535807E-01,0.226073200069370, 1829.15146461355,455.478499142212), nrow = 7, ncol = 2, byrow = TRUE) expectedBeta <- estimates[,1] expectedErrors <- estimates[,2] expectedResiduals <- c(267.340029759711,-94.0139423988359,46.28716775752924, -410.114621930906,309.7145907602313,-249.3112153297231,-164.0489563956039, -13.18035686637081,14.30477260005235,455.394094551857,-17.26892711483297, -39.0550425226967,-155.5499735953195,-85.6713080421283,341.9315139607727, -206.7578251937366) expectedStdError <- 304.8540735619638 expectedRSquare <- 0.995479004577296 expectedAdjRSquare <- 0.992465007628826 verifyRegression(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expectedAdjRSquare, "Longley") # Model with no intercept model <- lm(y ~ 0 + x1 + x2 + x3 + x4 + x5 + x6) estimates <- matrix(c(-52.99357013868291, 129.54486693117232, 0.07107319907358, 0.03016640003786, -0.42346585566399, 0.41773654056612, -0.57256866841929, 0.27899087467676, -0.41420358884978, 0.32128496193363, 48.41786562001326, 17.68948737819961), nrow = 6, ncol = 2, byrow = TRUE) expectedBeta <- estimates[,1] expectedErrors <- estimates[,2] expectedResiduals <- c(279.90274927293092, -130.32465380836874, 90.73228661967445, -401.31252201634948, -440.46768772620027, -543.54512853774793, 201.32111639536299, 215.90889365977932, 73.09368242049943, 913.21694494481869, 424.82484953610174, -8.56475876776709, -361.32974610842876, 27.34560497213464, 151.28955976355002, -492.49937355336846) expectedStdError <- 475.1655079819517 expectedRSquare <- 0.9999670130706 expectedAdjRSquare <- 0.999947220913 verifyRegression(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expectedAdjRSquare, "Longley No Intercept") # Swiss Fertility (R dataset named "swiss") design <- matrix(c(80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33), nrow = 47, ncol = 5, byrow = TRUE) y <- design[,1] x1 <- design[,2] x2 <- design[,3] x3 <- design[,4] x4 <- design[,5] model <- lm(y ~ x1 + x2 + x3 + x4) estimates <- matrix(c(91.05542390271397,6.94881329475087, -0.22064551045715,0.07360008972340, -0.26058239824328,0.27410957467466, -0.96161238456030,0.19454551679325, 0.12441843147162,0.03726654773803), nrow = 5, ncol = 2, byrow = TRUE) expectedBeta <- estimates[,1] expectedErrors <- estimates[,2] expectedResiduals <- c(7.1044267859730512,1.6580347433531366, 4.6944952770029644,8.4548022690166160,13.6547432343186212, -9.3586864458500774,7.5822446330520386,15.5568995563859289, 0.8113090736598980,7.1186762732484308,7.4251378771228724, 2.6761316873234109,0.8351584810309354,7.1769991119615177, -3.8746753206299553,-3.1337779476387251,-0.1412575244091504, 1.1186809170469780,-6.3588097346816594,3.4039270429434074, 2.3374058329820175,-7.9272368576900503,-7.8361010968497959, -11.2597369269357070,0.9445333697827101,6.6544245101380328, -0.9146136301118665,-4.3152449403848570,-4.3536932047009183, -3.8907885169304661,-6.3027643926302188,-7.8308982189289091, -3.1792280015332750,-6.7167298771158226,-4.8469946718041754, -10.6335664353633685,11.1031134362036958,6.0084032641811733, 5.4326230830188482,-7.2375578629692230,2.1671550814448222, 15.0147574652763112,4.8625103516321015,-7.1597256413907706, -0.4515205619767598,-10.2916870903837587,-15.7812984571900063) expectedStdError <- 7.73642194433223 expectedRSquare <- 0.649789742860228 expectedAdjRSquare <- 0.6164363850373927 verifyRegression(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expectedAdjRSquare, "Swiss Fertility") # model with no intercept model <- lm(y ~ 0 + x1 + x2 + x3 + x4) estimates <- matrix(c(0.52191832900513, 0.10470063765677, 2.36588087917963, 0.41684100584290, -0.94770353802795, 0.43370143099691, 0.30851985863609, 0.07694953606522), nrow = 4, ncol = 2, byrow = TRUE) expectedBeta <- estimates[,1] expectedErrors <- estimates[,2] expectedResiduals <- c(44.138759883538249, 27.720705122356215, 35.873200836126799, 34.574619581211977, 26.600168342080213, 15.074636243026923, -12.704904871199814, 1.497443824078134, 2.691972687079431, 5.582798774291231, -4.422986561283165, -9.198581600334345, 4.481765170730647, 2.273520207553216, -22.649827853221336, -17.747900013943308, 20.298314638496436, 6.861405135329779, -8.684712790954924, -10.298639278062371, -9.896618896845819, 4.568568616351242, -15.313570491727944, -13.762961360873966, 7.156100301980509, 16.722282219843990, 26.716200609071898, -1.991466398777079, -2.523342564719335, 9.776486693095093, -5.297535127628603, -16.639070567471094, -10.302057295211819, -23.549487860816846, 1.506624392156384, -17.939174438345930, 13.105792202765040, -1.943329906928462, -1.516005841666695, -0.759066561832886, 20.793137744128977, -2.485236153005426, 27.588238710486976, 2.658333257106881, -15.998337823623046, -5.550742066720694, -14.219077806826615) expectedStdError <- 17.24710630547 expectedRSquare <- 0.946350722085 expectedAdjRSquare <- 0.9413600915813 verifyRegression(model, expectedBeta, expectedResiduals, expectedErrors, expectedStdError, expectedRSquare, expectedAdjRSquare, "Swiss Fertility No Intercept") displayDashes(WIDTH) commons-math-2.2-src/src/test/R/exponentialTestCases100644 1750 1750 7516 11532241241 21340 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate exponential distribution tests in # org.apache.commons.math.distribution.ExponentialDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #------------------------------------------------------------------------------ tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, mean, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pexp(point, 1/mean) } output <- c("Distribution test mean = ", mean) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, mean, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dexp(point, 1/mean) } output <- c("Density test mean = ", mean) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, mean, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qexp(point, 1/mean, log = FALSE) } output <- c("Quantile test mean = ", mean) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Exponential test cases\n") mean <- 5 distributionValues <- c(0, 0, 0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.2, 0.2, 0.1998, 0.198, 0.195, 0.19, 0.18, 0.000200000000000, 0.00200000000002, 0.00499999999997, 0.00999999999994, 0.0199999999999) distributionPoints <- c(0, 0, 0.00500250166792, 0.0502516792675, 0.126589039921, 0.256466471938, 0.526802578289, 34.5387763949, 23.0258509299, 18.4443972706, 14.9786613678, 11.5129254650) verifyDistribution(distributionPoints, distributionValues, mean, tol) verifyQuantiles(distributionValues, distributionPoints, mean, tol) verifyDensity(distributionPoints, densityValues, mean, tol) output <- "Probability test P(.25 < X < .75)" if (assertEquals(0.0905214480757, pexp(.75, 1/mean) - pexp(.25, 1/mean), tol, "Probability value")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } displayDashes(WIDTH) commons-math-2.2-src/src/test/R/descriptiveTestCases100644 1750 1750 7164 11532241241 21332 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate summary statistics tests in # org.apache.commons.math.stat.CertifiedDataTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # mean(x) # sd(x) #------------------------------------------------------------------------------ tol <- 1E-14 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions options(digits=15) # bump displayed digits to 15 verifyMean <- function(values, expectedMean, tol, desc) { results <- mean(values) if (assertEquals(expectedMean, results, tol, "mean")) { displayPadded(c(desc," mean test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " mean test"), FAILED, WIDTH) } } verifySigma <- function(values, expectedSigma, tol, desc) { results <- sd(values) if (assertEquals(expectedSigma, results, tol, "std")) { displayPadded(c(desc," std test"), SUCCEEDED, WIDTH) } else { displayPadded(c(desc, " std test"), FAILED, WIDTH) } } cat("Descriptive test cases\n") # Michelson data values <- c(299.85,299.74,299.90,300.07,299.93,299.85,299.95,299.98,299.98, 299.88,300.00,299.98,299.93,299.65,299.76,299.81,300.00,300.00,299.96,299.96, 299.96,299.94,299.96,299.94,299.88,299.80,299.85,299.88,299.90,299.84,299.83, 299.79,299.81,299.88,299.88,299.83,299.80,299.79,299.76,299.80,299.88,299.88, 299.88,299.86,299.72,299.72,299.62,299.86,299.97,299.95,299.88,299.91,299.85, 299.87,299.84,299.84,299.85,299.84,299.84,299.84,299.89,299.81,299.81,299.82, 299.80,299.77,299.76,299.74,299.75,299.76,299.91,299.92,299.89,299.86,299.88, 299.72,299.84,299.85,299.85,299.78,299.89,299.84,299.78,299.81,299.76,299.81, 299.79,299.81,299.82,299.85,299.87,299.87,299.81,299.74,299.81,299.94,299.95, 299.80,299.81,299.87) expectedMean <- 299.852400000000 expectedSigma <- 0.0790105478190518 verifyMean(values, expectedMean, tol, "Michelson") verifySigma(values, expectedSigma, tol, "Michelson") # Mavro data values <- c(2.00180,2.00170,2.00180,2.00190,2.00180,2.00170,2.00150,2.00140, 2.00150,2.00150,2.00170,2.00180,2.00180,2.00190,2.00190,2.00210,2.00200, 2.00160,2.00140,2.00130,2.00130,2.00150,2.00150,2.00160,2.00150,2.00140, 2.00130,2.00140,2.00150,2.00140,2.00150,2.00160,2.00150,2.00160,2.00190, 2.00200,2.00200,2.00210,2.00220,2.00230,2.00240,2.00250,2.00270,2.00260, 2.00260,2.00260,2.00270,2.00260,2.00250,2.00240) expectedMean <- 2.00185600000000 expectedSigma <- 0.000429123454003053 verifyMean(values, expectedMean, tol, "Mavro") verifySigma(values, expectedSigma, tol, "Mavro") displayDashes(WIDTH) commons-math-2.2-src/src/test/R/TDistributionTestCases.R100644 1750 1750 10244 11532241241 22025 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate T distribution tests in # org.apache.commons.math.distribution.TDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, df, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pt(point, df, log = FALSE) } output <- c("Distribution test df = ", df) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, df, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dt(point, df, log = FALSE) } output <- c("Density test df = ", df) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, df, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qt(point, df, log = FALSE) } output <- c("Quantile test df = ", df) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("T Distribution test cases\n") df <- 5 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005, 0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005) distributionPoints <- c(-5.89342953136, -3.36492999891, -2.57058183564, -2.01504837333, -1.47588404882, 5.89342953136, 3.36492999891, 2.57058183564, 2.01504837333, 1.47588404882) verifyQuantiles(distributionValues, distributionPoints, df, tol) verifyDistribution(distributionPoints, distributionValues, df, tol) verifyDensity(distributionPoints, densityValues, df, tol) df <- 1 densityValues <- c(3.14158231817e-06, 0.000314055924703, 0.00195946145194, 0.00778959736375, 0.0303958893917, 3.14158231817e-06, 0.000314055924703, 0.00195946145194, 0.00778959736375, 0.0303958893917) distributionPoints <- c(-318.308838986, -31.8205159538, -12.7062047362, -6.31375151468, -3.07768353718, 318.308838986, 31.8205159538, 12.7062047362, 6.31375151468, 3.07768353718) verifyQuantiles(distributionValues, distributionPoints, df, tol) verifyDistribution(distributionPoints, distributionValues, df, tol) verifyDensity(distributionPoints, densityValues, df, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/cauchyTestCases.R100644 1750 1750 7450 11532241241 20463 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Cauchy distribution tests in # org.apache.commons.math.distribution.CauchyDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, median, scale, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pcauchy(point, median, scale, log = FALSE) } output <- c("Distribution test median = ",median,", scale = ", scale) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, median, scale, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dcauchy(point, median, scale, log = FALSE) } output <- c("Density test median = ",median,", scale = ", scale) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, median, scale, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qcauchy(point, median, scale, log = FALSE) } output <- c("Quantile test median = ",median,", scale = ", scale) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Cauchy test cases\n") median <- 1.2 scale <- 2.1 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(1.49599158008e-06, 0.000149550440335, 0.000933076881878, 0.00370933207799, 0.0144742330437, 1.49599158008e-06, 0.000149550440335, 0.000933076881878, 0.00370933207799, 0.0144742330437) distributionPoints <- c(-667.24856187, -65.6230835029, -25.4830299460, -12.0588781808, -5.26313542807, 669.64856187, 68.0230835029, 27.8830299460, 14.4588781808, 7.66313542807) verifyDistribution(distributionPoints, distributionValues, median, scale, tol) verifyDensity(distributionPoints, densityValues, median, scale, tol) verifyQuantiles(distributionValues, distributionPoints, median, scale, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/covarianceTestCases100644 1750 1750 14166 11532241241 21143 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate covariance tests in # org.apache.commons.math.stat.correlation.CovarianceTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #------------------------------------------------------------------------------ tol <- 1E-9 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions options(digits=16) # override number of digits displayed # function to verify covariance computations verifyCovariance <- function(matrix, expectedCovariance, name) { covariance <- cov(matrix) output <- c("Covariance test dataset = ", name) if (assertEquals(expectedCovariance,covariance,tol,"Covariances")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Covariance test cases\n") # Longley longley <- matrix(c(60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962), nrow = 16, ncol = 7, byrow = TRUE) expectedCovariance <- matrix(c( 12333921.73333333246, 3.679666000000000e+04, 343330206.333333313, 1649102.666666666744, 1117681.066666666651, 23461965.733333334, 16240.93333333333248, 36796.66000000000, 1.164576250000000e+02, 1063604.115416667, 6258.666250000000, 3490.253750000000, 73503.000000000, 50.92333333333334, 343330206.33333331347, 1.063604115416667e+06, 9879353659.329166412, 56124369.854166664183, 30880428.345833335072, 685240944.600000024, 470977.90000000002328, 1649102.66666666674, 6.258666250000000e+03, 56124369.854166664, 873223.429166666698, -115378.762499999997, 4462741.533333333, 2973.03333333333330, 1117681.06666666665, 3.490253750000000e+03, 30880428.345833335, -115378.762499999997, 484304.095833333326, 1764098.133333333, 1382.43333333333339, 23461965.73333333433, 7.350300000000000e+04, 685240944.600000024, 4462741.533333333209, 1764098.133333333302, 48387348.933333330, 32917.40000000000146, 16240.93333333333, 5.092333333333334e+01, 470977.900000000, 2973.033333333333, 1382.433333333333, 32917.40000000, 22.66666666666667), nrow = 7, ncol = 7, byrow = TRUE) verifyCovariance(longley, expectedCovariance, "longley") # Swiss Fertility fertility <- matrix(c(80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33), nrow = 47, ncol = 5, byrow = TRUE) expectedCovariance <- matrix(c( 156.0424976873265, 100.1691489361702, -64.36692876965772, -79.7295097132285, 241.5632030527289, 100.169148936170251, 515.7994172062905, -124.39283071230344, -139.6574005550416, 379.9043755781684, -64.3669287696577, -124.3928307123034, 63.64662349676226, 53.5758556891767, -190.5606105457909, -79.7295097132285, -139.6574005550416, 53.57585568917669, 92.4560592044403, -61.6988297872340, 241.5632030527289, 379.9043755781684, -190.56061054579092, -61.6988297872340, 1739.2945371877890), nrow = 5, ncol = 5, byrow = TRUE) verifyCovariance(fertility, expectedCovariance, "swiss fertility") displayDashes(WIDTH)commons-math-2.2-src/src/test/R/testAll100644 1750 1750 4421 11532241241 16573 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to run all commons-math R verification tests # # To run the test, install R, put this file and all other o.a.c.math R # verification tests and the testfunctions utilities file into the same # directory, launch R from this directory and then enter # source("") # # To redirect output to a file, uncomment the following line, substituting # another file path if you like (default behavior is to write the file to the # current directory). # # sink("testResults") #------------------------------------------------------------------------------ # distribution source("binomialTestCases") source("normalTestCases") source("poissonTestCases") source("hypergeometricTestCases") source("exponentialTestCases") source("cauchyTestCases.R") source("pascalTestCases") source("TDistributionTestCases.R") source("FDistributionTestCases.R") source("GammaDistributionTestCases.R") source("WeibullDistributionTestCases.R") source("ChiSquareDistributionTestCases.R") # regression source("regressionTestCases") # inference source("chiSquareTestCases") source("anovaTestCases") # descriptive source("descriptiveTestCases") # multiple regression source("multipleOLSRegressionTestCases") # covariance source("covarianceTestCases") # correlation source("correlationTestCases") #------------------------------------------------------------------------------ # if output has been diverted, change it back if (sink.number()) { sink() } commons-math-2.2-src/src/test/R/pascalTestCases100644 1750 1750 12227 11532241241 20270 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Pascal distribution tests in # org.apache.commons.math.distribution.PascalDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # dnbinom(x, size, prob, mu, log = FALSE) <- density # pnbinom(q, size, prob, mu, lower.tail = TRUE, log.p = FALSE) <- distribution # qnbinom(p, size, prob, mu, lower.tail = TRUE, log.p = FALSE) <- quantiles #------------------------------------------------------------------------------ tol <- 1E-9 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions # function to verify density computations verifyDensity <- function(points, expected, size, p, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dnbinom(point, size, p) } output <- c("Density test size = ", size, ", p = ", p) if (assertEquals(expected,rDensityValues,tol,"Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify distribution computations verifyDistribution <- function(points, expected, size, p, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pnbinom(point, size, p) } output <- c("Distribution test size = ", size, ", p = ", p) if (assertEquals(expected,rDistValues,tol,"Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Negative Binomial test cases\n") size <- 10.0 probability <- 0.70 densityPoints <- c(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) densityValues <- c(0, 0.0282475249, 0.0847425747, 0.139825248255, 0.167790297906, 0.163595540458, 0.137420253985, 0.103065190489, 0.070673273478, 0.0450542118422, 0.0270325271053, 0.0154085404500, 0.0084046584273) distributionValues <- c(0, 0.0282475249, 0.1129900996, 0.252815347855, 0.420605645761, 0.584201186219, 0.721621440204, 0.824686630693, 0.895359904171, 0.940414116013, 0.967446643119, 0.982855183569, 0.991259841996) inverseCumPoints <- c( 0, 0.001, 0.010, 0.025, 0.050, 0.100, 0.999, 0.990, 0.975, 0.950, 0.900) inverseCumValues <- c(-1, -1, -1, -1, 0, 0, 13, 10, 9, 8, 7) verifyDensity(densityPoints,densityValues,size,probability,tol) verifyDistribution(densityPoints, distributionValues, size, probability, tol) i <- 0 rInverseCumValues <- rep(0,length(inverseCumPoints)) for (point in inverseCumPoints) { i <- i + 1 rInverseCumValues[i] <- qnbinom(point, size, probability) } output <- c("Inverse Distribution test n = ", size, ", p = ", probability) # R defines quantiles from the right, need to subtract one if (assertEquals(inverseCumValues, rInverseCumValues-1, tol, "Inverse Dist Values")) { displayPadded(output, SUCCEEDED, 80) } else { displayPadded(output, FAILED, 80) } # Degenerate cases size <- 5 probability <- 0.0 densityPoints <- c(-1, 0, 1, 10, 11) # Note: commons math returns 0's below densityValues <- c(NaN, NaN, NaN, NaN, NaN) distributionPoints <- c(-1, 0, 1, 5, 10) # Note: commons math returns 0's below distributionValues <- c(NaN, NaN, NaN, NaN, NaN) output <- c("Density test n = ", size, ", p = ", probability) verifyDensity(densityPoints,densityValues,size,probability,tol) output <- c("Distribution test n = ", size, ", p = ", probability) verifyDistribution(distributionPoints,distributionValues,size,probability,tol) size <- 5 probability <- 1.0 densityPoints <- c(-1, 0, 1, 2, 5, 10) densityValues <- c(0, 1, 0, 0, 0, 0) distributionPoints <- c(-1, 0, 1, 2, 5, 10) distributionValues <- c(0, 1, 1, 1, 1, 1) output <- c("Density test n = ", size, ", p = ", probability) verifyDensity(densityPoints,densityValues,size,probability,tol) output <- c("Distribution test n = ", size, ", p = ", probability) verifyDistribution(distributionPoints,distributionValues,size,probability,tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/normalTestCases100644 1750 1750 11544 11532241241 20316 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Normal distribution tests in # org.apache.commons.math.distribution.NormalDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # pnorm(q, mean=0, sd=1, lower.tail = TRUE, log.p = FALSE) <-- distribution #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, mu, sigma, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pnorm(point, mu, sigma, log = FALSE) } output <- c("Distribution test mu = ",mu,", sigma = ", sigma) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, mu, sigma, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dnorm(point, mu, sigma, log = FALSE) } output <- c("Density test mu = ",mu,", sigma = ", sigma) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Normal test cases\n") mu <- 2.1 sigma <- 1.4 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380, 0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380) distributionPoints <- c(-2.226325228634938, -1.156887023657177, -0.643949578356075, -0.2027950777320613, 0.305827808237559, 6.42632522863494, 5.35688702365718, 4.843949578356074, 4.40279507773206, 3.89417219176244) verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) verifyDensity(distributionPoints, densityValues, mu, sigma, tol) distributionValues <- c( 0.0227501319482, 0.158655253931, 0.5, 0.841344746069, 0.977249868052, 0.998650101968, 0.999968328758, 0.999999713348) densityValues <- c(0.0385649760808, 0.172836231799, 0.284958771715, 0.172836231799, 0.0385649760808, 0.00316560600853, 9.55930184035e-05, 1.06194251052e-06) distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, mu + 5 * sigma) verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) verifyDensity(distributionPoints, densityValues, mu, sigma, tol) mu <- 0 sigma <- 1 distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, mu + 5 * sigma) densityValues <- c(0.0539909665132, 0.241970724519, 0.398942280401, 0.241970724519, 0.0539909665132, 0.00443184841194, 0.000133830225765, 1.48671951473e-06) verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) verifyDensity(distributionPoints, densityValues, mu, sigma, tol) mu <- 0 sigma <- 0.1 distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, mu + 5 * sigma) densityValues <- c(0.539909665132, 2.41970724519, 3.98942280401, 2.41970724519, 0.539909665132, 0.0443184841194, 0.00133830225765, 1.48671951473e-05) verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) verifyDensity(distributionPoints, densityValues, mu, sigma, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/regressionTestCases100644 1750 1750 13200 11532241241 21175 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #----------------------------------------------------------------------- # R source file to validate Binomial distribution tests in # org.apache.commons.math.stat.regression.SimpleRegressionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # Output will be written to a file named "regTestResults" # in the directory from which R was launched # #------------------------------------------------------------------------------ tol <- 1E-8 #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions #------------------------------------------------------------------------------ # infData example cat("Regresssion test cases\n") x <- c(15.6, 26.8,37.8,36.4,35.5,18.6,15.3,7.9,0.0) y <- c(5.2, 6.1, 8.7, 8.5, 8.8, 4.9, 4.5, 2.5, 1.1) model<-lm(y~x) coef <- coefficients(summary(model)) intercept <- coef[1, 1] interceptStd <- coef[1, 2] slope <- coef[2, 1] slopeStd <- coef[2, 2] significance <- coef[2, 4] output <- "InfData std error test" if (assertEquals(0.011448491, slopeStd, tol, "Slope Standard Error") && assertEquals(0.286036932, interceptStd, tol, "Intercept Standard Error")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- "InfData significance test" if (assertEquals(4.596e-07, significance, tol, "Significance")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- "InfData conf interval test" ci<-confint(model) # ci[1,1] = lower 2.5% bound for intercept, ci[1,2] = upper 97.5% for intercept # ci[2,1] = lower 2.5% bound for slope, ci[2,2] = upper 97.5% for slope halfWidth <- ci[2,2] - slope if (assertEquals(0.0270713794287, halfWidth, tol, "Slope conf. interval half-width")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } #------------------------------------------------------------------------------ # Norris dataset from NIST examples y <- c(0.1, 338.8, 118.1, 888.0, 9.2, 228.1, 668.5, 998.5, 449.1, 778.9, 559.2, 0.3, 0.1, 778.1, 668.8, 339.3, 448.9, 10.8, 557.7, 228.3, 998.0, 888.8, 119.6, 0.3, 0.6, 557.6, 339.3, 888.0, 998.5, 778.9, 10.2, 117.6, 228.9, 668.4, 449.2, 0.2) x <- c(0.2, 337.4, 118.2, 884.6, 10.1, 226.5, 666.3, 996.3, 448.6, 777.0, 558.2, 0.4, 0.6, 775.5, 666.9, 338.0, 447.5, 11.6, 556.0, 228.1, 995.8, 887.6, 120.2, 0.3, 0.3, 556.8, 339.1, 887.2, 999.0, 779.0, 11.1, 118.3, 229.2, 669.1, 448.9, 0.5) model<-lm(y~x) coef <- coefficients(summary(model)) intercept <- coef[1, 1] interceptStd <- coef[1, 2] slope <- coef[2, 1] slopeStd <- coef[2, 2] output <- "Norris std error test" if (assertEquals(0.429796848199937E-03, slopeStd, tol, "Slope Standard Error") && assertEquals(0.232818234301152, interceptStd, tol, "Intercept Standard Error")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } #------------------------------------------------------------------------------ # infData2 -- bad fit example # x <- c(1,2,3,4,5,6) y <- c(1,0,5,2,-1,12) model<-lm(y~x) coef <- coefficients(summary(model)) intercept <- coef[1, 1] interceptStd <- coef[1, 2] slope <- coef[2, 1] slopeStd <- coef[2, 2] significance <- coef[2, 4] output <- "InfData2 std error test" if (assertEquals(1.07260253, slopeStd, tol, "Slope Standard Error") && assertEquals(4.17718672, interceptStd, tol, "Intercept Standard Error")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- "InfData2 significance test" if (assertEquals(0.261829133982, significance, tol, "Significance")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } output <- "InfData2 conf interval test" ci<-confint(model) # ci[1,1] = lower 2.5% bound for intercept, ci[1,2] = upper 97.5% for intercept # ci[2,1] = lower 2.5% bound for slope, ci[2,2] = upper 97.5% for slope halfWidth <- ci[2,2] - slope if (assertEquals(2.97802204827, halfWidth, tol, "Slope conf. interval half-width")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } #------------------------------------------------------------------------------ # Correlation example x <- c(101.0, 100.1, 100.0, 90.6, 86.5, 89.7, 90.6, 82.8, 70.1, 65.4, 61.3, 62.5, 63.6, 52.6, 59.7, 59.5, 61.3) y <- c(99.2, 99.0, 100.0, 111.6, 122.2, 117.6, 121.1, 136.0, 154.2, 153.6, 158.5, 140.6, 136.2, 168.0, 154.3, 149.0, 165.5) output <- "Correlation test" if (assertEquals(-0.94663767742, cor(x,y, method="pearson"), tol, "Correlation coefficient")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } displayDashes(WIDTH) commons-math-2.2-src/src/test/R/WeibullDistributionTestCases.R100644 1750 1750 7472 11532241241 23216 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Weibull distribution tests in # org.apache.commons.math.distribution.GammaDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, alpha, beta, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pweibull(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Distribution test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, alpha, beta, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dweibull(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Density test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, alpha, beta, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qweibull(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Quantile test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Weibull Distribution test cases\n") shape <- 1.2 scale <- 2.1 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.180535929306, 0.262801138133, 0.301905425199, 0.330899152971, 0.353441418887, 0.000788590320203, 0.00737060094841, 0.0177576041516, 0.0343043442574, 0.065664589369) distributionPoints <- c(0.00664355180993, 0.0454328283309, 0.0981162737374, 0.176713524579, 0.321946865392, 10.5115496887, 7.4976304671, 6.23205600701, 5.23968436955, 4.20790282578) verifyQuantiles(distributionValues, distributionPoints, shape, scale, tol) verifyDistribution(distributionPoints, distributionValues, shape, scale, tol) verifyDensity(distributionPoints, densityValues, shape, scale, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/GammaDistributionTestCases.R100644 1750 1750 7460 11532241241 22632 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Gamma distribution tests in # org.apache.commons.math.distribution.GammaDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, alpha, beta, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pgamma(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Distribution test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, alpha, beta, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dgamma(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Density test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, alpha, beta, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qgamma(point, shape=alpha, scale=beta, log = FALSE) } output <- c("Quantile test shape = ", shape, " scale = ", scale) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Gamma Distribution test cases\n") shape <- 4 scale <- 2 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.00427280075546, 0.0204117166709, 0.0362756163658, 0.0542113174239, 0.0773195272491, 0.000394468852816, 0.00366559696761, 0.00874649473311, 0.0166712508128, 0.0311798227954) distributionPoints <- c(0.857104827257, 1.64649737269, 2.17973074725, 2.7326367935, 3.48953912565, 26.1244815584, 20.0902350297, 17.5345461395, 15.5073130559, 13.3615661365) verifyQuantiles(distributionValues, distributionPoints, shape, scale, tol) verifyDistribution(distributionPoints, distributionValues, shape, scale, tol) verifyDensity(distributionPoints, densityValues, shape, scale, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/README.txt100644 1750 1750 16352 11532241241 16764 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ INTRODUCTION The purpose of the R programs included in this directory is to validate the target values used in Apache commons math unit tests. Success running the R and commons-math tests on a platform (OS and R version) means that R and commons-math give results for the test cases that are close in value. The tests include configurable tolerance levels; but care must be taken in changing these, since in most cases the pre-set tolerance is close to the number of decimal digits used in expressing the expected values (both here and in the corresponding commons-math unit tests). Of course it is always possible that both R and commons-math give incorrect values for test cases, so these tests should not be interpreted as definitive in any absolute sense. The value of developing and running the tests is really to generate questions (and answers!) when the two systems give different results. Contributions of additional test cases (both R and Junit code) or just R programs to validate commons-math tests that are not covered here would be greatly appreciated. SETUP 0) Download and install R. You can get R here http://www.r-project.org/ Follow the install instructions and make sure that you can launch R from this (i.e., either explitly add R to your OS path or let the install package do it for you). 1) Launch R from this directory and type > source("testAll") to an R prompt. This should produce output to the console similar to this: Binomial test cases Density test n = 10, p = 0.7...........................................SUCCEEDED Distribution test n = 10, p = 0.7......................................SUCCEEDED Inverse Distribution test n = 10, p = 0.7..............................SUCCEEDED Density test n = 5, p = 0..............................................SUCCEEDED Distribution test n = 5, p = 0.........................................SUCCEEDED Density test n = 5, p = 1..............................................SUCCEEDED Distribution test n = 5, p = 1.........................................SUCCEEDED -------------------------------------------------------------------------------- Normal test cases Distribution test mu = 2.1, sigma = 1.4................................SUCCEEDED Distribution test mu = 2.1, sigma = 1.4................................SUCCEEDED Distribution test mu = 0, sigma = 1....................................SUCCEEDED Distribution test mu = 0, sigma = 0.1..................................SUCCEEDED -------------------------------------------------------------------------------- ... WORKING WITH THE TESTS The R distribution comes with online manuals that you can view by launching a browser instance and then entering > help.start() at an R prompt. Poking about in the test case files and the online docs should bring you up to speed fairly quickly. Here are some basic things to get you started. I should note at this point that I am by no means an expert R programmer, so some things may not be implemented in the the nicest way. Comments / suggestions for improvement are welcome! All of the test cases use some basic functions and global constants (screen width and success / failure strings) defined in "testFunctions." The R "source" function is used to "import" these functions into each of the test programs. The "testAll" program pulls together and executes all of the individual test programs. You can execute any one of them by just entering > source(). The "assertEquals" function in the testFunctions file mimics the similarly named function used by Junit: assertEquals <- function(expected, observed, tol, message) { if(any(abs(expected - observed) > tol)) { cat("FAILURE: ",message,"\n") cat("EXPECTED: ",expected,"\n") cat("OBSERVED: ",observed,"\n") return(0) } else { return(1) } } The and arguments can be scalar values, vectors or matrices. If the arguments are vectors or matrices, corresponding entries are compared. The standard pattern used throughout the tests looks like this (from binomialTestCases): Start by defining a "verification function" -- in this example a function to verify computation of binomial probabilities. The argument is a vector of integer values to feed into the density function, is a vector of the computed probabilies from the commons-math Junit tests, and

are parameters of the distribution and is the error tolerance of the test. The function computes the probabilities using R and compares the values that R produces with those in the vector. verifyDensity <- function(points, expected, n, p, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dbinom(point, n, p, log = FALSE) } output <- c("Density test n = ", n, ", p = ", p) if (assertEquals(expected,rDensityValues,tol,"Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } The displayPadded function just displays its first and second arguments with enough dots in between to make the whole string WIDTH characters long. It is defined in testFunctions. Then call this function with different parameters corresponding to the different Junit test cases: size <- 10.0 probability <- 0.70 densityPoints <- c(-1,0,1,2,3,4,5,6,7,8,9,10,11) densityValues <- c(0, 0.0000, 0.0001, 0.0014, 0.0090, 0.0368, 0.1029, 0.2001, 0.2668, 0.2335, 0.1211, 0.0282, 0) ... verifyDensity(densityPoints, densityValues, size, probability, tol) If the values computed by R match the target values in densityValues, this will produce one line of output to the console: Density test n = 10, p = 0.7...........................................SUCCEEDED If you modify the value of tol set at the top of binomialTestCases to make the test more sensitive than the number of digits specified in the densityValues vector, it will fail, producing the following output, showing the failure and the expected and observed values: FAILURE: Density Values EXPECTED: 0 0 1e-04 0.0014 0.009 0.0368 0.1029 0.2001 0.2668 0.2335 0.1211 / 0.0282 0 OBSERVED: 0 5.9049e-06 0.000137781 0.0014467005 0.009001692 0.036756909 / 0.1029193452 0.200120949 0.266827932 0.2334744405 0.121060821 0.0282475249 0 Density test n = 10, p = 0.7..............................................FAILED commons-math-2.2-src/src/test/R/poissonTestCases100644 1750 1750 10212 11532241241 20507 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Poisson distribution tests in # org.apache.commons.math.distribution.PoissonDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # dpois(x, lambda, log = FALSE) <-- density # ppois(q, lambda, lower.tail = TRUE, log.p = FALSE) <-- distribution # pnorm(q, mean=0, sd=1, lower.tail = TRUE, log.p = FALSE) <-- normal dist. #------------------------------------------------------------------------------ tol <- 1E-10 #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions # function to verify density computations verifyDensity <- function(points, expected, lambda, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dpois(point, lambda, log = FALSE) } output <- c("Density test lambda = ", lambda) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify distribution computations verifyDistribution <- function(points, expected, lambda, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- ppois(point, lambda, log = FALSE) } output <- c("Distribution test lambda = ", lambda) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify normal approximation verifyNormalApproximation <- function(expected, lambda, lower, upper, tol) { rValue <- pnorm(upper, mean=lambda, sd=sqrt(lambda), lower.tail = TRUE, log.p = FALSE) - pnorm(lower, mean=lambda, sd=sqrt(lambda), lower.tail = TRUE, log.p = FALSE) output <- c("Normal approx. test lambda = ", lambda, " upper = ", upper, " lower = ", lower) if (assertEquals(expected, rValue, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } cat("Poisson distribution test cases\n") # stock tests lambda <- 4.0 densityPoints <- c(-1,0,1,2,3,4,5,10,20) densityValues <- c(0, 0.0183156388887, 0.073262555555, 0.14652511111, 0.195366814813, 0.195366814813, 0.156293451851, 0.00529247667642, 8.27746364655e-09) verifyDensity(densityPoints, densityValues, lambda, tol) distributionPoints <- c(-1, 0, 1, 2, 3, 4, 5, 10, 20) distributionValues <- c(0, 0.0183156388887, 0.0915781944437, 0.238103305554, 0.433470120367, 0.62883693518, 0.78513038703, 0.99716023388, 0.999999998077) verifyDistribution(distributionPoints, distributionValues, lambda, tol) # normal approximation tests lambda <- 100 verifyNormalApproximation(0.706281887248, lambda, 89.5, 110.5, tol) lambda <- 10000 verifyNormalApproximation(0.820070051552, lambda, 9899.5, 10200.5, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/TTestCases100644 1750 1750 10413 11532241241 17223 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate TTest tests in # org.apache.commons.math.inference.TTestImpl # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # t.test(x, y = NULL, alternative = c("two.sided", "less", "greater"), # mu = 0, paired = FALSE, var.equal = FALSE, ... ) # Arguments # x a numeric vector of data values. # y an optional numeric vector data values. # alternative a character string specifying the alternative hypothesis, # must be one of "two.sided" (default), "greater" or "less". You can specify # just the initial letter. # mu a number indicating the true value of the mean (or difference in means # if you are performing a two sample test). # paired a logical indicating whether you want a paired t-test. # var.equal a logical variable indicating whether to treat the two # variances as being equal. # If TRUE then the pooled variance is used to estimate the variance, # otherwise the Welch (or Satterthwaite) approximation to the degrees # of freedom is used. #------------------------------------------------------------------------------ tol <- 1E-10 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions #------------------------------------------------------------------------------ source("testFunctions") # utility test functions #------------------------------------------------------------------------------ # Verification function # verifyTest <- function(out,expectedP, expectedT, tol) { if (assertEquals(expectedP, out$p.value, tol, "Ttest p value")) { displayPadded(output, SUCCEEDED, 80) } else { displayPadded(output, FAILED, 80) } output <- c("t test test statistic") if (assertEquals(expectedT, out$statistic, tol, "Ttest t statistic")) { displayPadded(output, SUCCEEDED, 80) } else { displayPadded(output, FAILED, 80) } displayDashes(WIDTH) } cat("One-sample, two-sided TTest test cases \n") sample1 <- c(93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0, 88.0, 98.0, 94.0, 101.0, 92.0, 95.0) out <- t.test(sample1, mu=100.0) expectedP <- 0.0136390585873 expectedT<- -2.81976445346 verifyTest(out,expectedP, expectedT, tol) cat("One-sample, one-sided TTest test cases \n") sample1 <- c(2, 0, 6, 6, 3, 3, 2, 3, -6, 6, 6, 6, 3, 0, 1, 1, 0, 2, 3, 3) out <- t.test(sample1, mu=0.0, alternative="g") expectedP <- 0.000521637019637 expectedT<- 3.86485535541 verifyTest(out,expectedP, expectedT, tol) cat("Homoscedastic TTest test cases \n") sample1 <- c(2, 4, 6, 8, 10, 97) sample2 <- c(4, 6, 8, 10, 16) out <- t.test(sample1,sample2,var.equal = TRUE) expectedP <- 0.4833963785 expectedT<- 0.73096310086 verifyTest(out,expectedP, expectedT, tol) cat("Heteroscedastic TTest test cases \n") sample1 <- c(7, -4, 18, 17, -3, -5, 1, 10, 11, -2) sample2 <- c(-1, 12, -1, -3, 3, -5, 5, 2, -11, -1, -3) out <- t.test(sample1,sample2,var.equal = FALSE) expectedP <- 0.128839369622 expectedT<- 1.60371728768 verifyTest(out,expectedP, expectedT, tol) cat("Small sample, heteroscedastic test cases \n") sample1 <- c(1,3) sample2 <- c(4,5) out <- t.test(sample1,sample2,var.equal = FALSE) expectedP <- 0.198727388935 expectedT<- -2.2360679775 verifyTest(out,expectedP, expectedT, tol) commons-math-2.2-src/src/test/R/FDistributionTestCases.R100644 1750 1750 7735 11532241241 22002 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate F distribution tests in # org.apache.commons.math.distribution.TDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #----------------------------------------------------------------------------- tol <- 1E-9 # Function definitions source("testFunctions") # utility test functions # function to verify distribution computations verifyDistribution <- function(points, expected, numeratorDf, denominatorDf, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pf(point, numeratorDf, denominatorDf, log = FALSE) } output <- c("Distribution test numerator df = ", numeratorDf, " denominator df = ", denominatorDf) if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify density computations verifyDensity <- function(points, expected, numeratorDf, denominatorDf, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- df(point, numeratorDf, denominatorDf, log = FALSE) } output <- c("Density test numerator df = ", numeratorDf, " denominator df = ", denominatorDf) if (assertEquals(expected, rDensityValues, tol, "Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify quantiles verifyQuantiles <- function(points, expected, numeratorDf, denominatorDf, tol) { rQuantileValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rQuantileValues[i] <- qf(point, numeratorDf, denominatorDf, log = FALSE) } output <- c("Quantile test numerator df = ", numeratorDf, " denominator df = ", denominatorDf) if (assertEquals(expected, rQuantileValues, tol, "Quantile Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("F Distribution test cases\n") numeratorDf <- 5 denominatorDf <- 6 distributionValues <- c(0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900) densityValues <- c(0.0689156576706, 0.236735653193, 0.364074131941, 0.481570789649, 0.595880479994, 0.000133443915657, 0.00286681303403, 0.00969192007502, 0.0242883861471, 0.0605491314658) distributionPoints <- c(0.0346808448626, 0.0937009113303, 0.143313661184, 0.202008445998, 0.293728320107, 20.8026639595, 8.74589525602, 5.98756512605, 4.38737418741, 3.10751166664) verifyQuantiles(distributionValues, distributionPoints, numeratorDf, denominatorDf, tol) verifyDistribution(distributionPoints, distributionValues, numeratorDf, denominatorDf, tol) verifyDensity(distributionPoints, densityValues, numeratorDf, denominatorDf, tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/R/correlationTestCases100644 1750 1750 24031 11532241241 21342 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Pearson's correlation tests in # org.apache.commons.math.stat.correlation.PearsonsCorrelationTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # #------------------------------------------------------------------------------ tol <- 1E-15 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions options(digits=16) # override number of digits displayed # Verify Pearson's correlation verifyPearsonsCorrelation <- function(matrix, expectedCorrelation, name) { correlation <- cor(matrix) output <- c("Pearson's Correlation matrix test dataset = ", name) if (assertEquals(expectedCorrelation, correlation,tol,"Pearson's Correlations")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # Verify Spearman's correlation verifySpearmansCorrelation <- function(matrix, expectedCorrelation, name) { correlation <- cor(matrix, method="spearman") output <- c("Spearman's Correlation matrix test dataset = ", name) if (assertEquals(expectedCorrelation, correlation,tol,"Spearman's Correlations")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify p-values verifyPValues <- function(matrix, pValues, name) { dimension <- dim(matrix)[2] corValues <- matrix(nrow=dimension,ncol=dimension) expectedValues <- matrix(nrow=dimension,ncol=dimension) for (i in 2:dimension) { for (j in 1:(i-1)) { corValues[i,j]<-cor.test(matrix[,i], matrix[,j])$p.value corValues[j,i]<-corValues[i,j] } } for (i in 1:dimension) { corValues[i,i] <- 1 expectedValues[i,i] <- 1 } ptr <- 1 for (i in 2:dimension) { for (j in 1:(i-1)) { expectedValues[i,j] <- pValues[ptr] expectedValues[j,i] <- expectedValues[i,j] ptr <- ptr + 1 } } output <- c("Correlation p-values test dataset = ", name) if (assertEquals(expectedValues, corValues,tol,"p-values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Correlation test cases\n") # Longley ----------------------------------------------------------------- longley <- matrix(c(60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962), nrow = 16, ncol = 7, byrow = TRUE) # Pearson's expectedCorrelation <- matrix(c( 1.000000000000000, 0.9708985250610560, 0.9835516111796693, 0.5024980838759942, 0.4573073999764817, 0.960390571594376, 0.9713294591921188, 0.970898525061056, 1.0000000000000000, 0.9915891780247822, 0.6206333925590966, 0.4647441876006747, 0.979163432977498, 0.9911491900672053, 0.983551611179669, 0.9915891780247822, 1.0000000000000000, 0.6042609398895580, 0.4464367918926265, 0.991090069458478, 0.9952734837647849, 0.502498083875994, 0.6206333925590966, 0.6042609398895580, 1.0000000000000000, -0.1774206295018783, 0.686551516365312, 0.6682566045621746, 0.457307399976482, 0.4647441876006747, 0.4464367918926265, -0.1774206295018783, 1.0000000000000000, 0.364416267189032, 0.4172451498349454, 0.960390571594376, 0.9791634329774981, 0.9910900694584777, 0.6865515163653120, 0.3644162671890320, 1.000000000000000, 0.9939528462329257, 0.971329459192119, 0.9911491900672053, 0.9952734837647849, 0.6682566045621746, 0.4172451498349454, 0.993952846232926, 1.0000000000000000), nrow = 7, ncol = 7, byrow = TRUE) verifyPearsonsCorrelation(longley, expectedCorrelation, "longley") expectedPValues <- c( 4.38904690369668e-10, 8.36353208910623e-12, 7.8159700933611e-14, 0.0472894097790304, 0.01030636128354301, 0.01316878049026582, 0.0749178049642416, 0.06971758330341182, 0.0830166169296545, 0.510948586323452, 3.693245043123738e-09, 4.327782576751815e-11, 1.167954621905665e-13, 0.00331028281967516, 0.1652293725106684, 3.95834476307755e-10, 1.114663916723657e-13, 1.332267629550188e-15, 0.00466039138541463, 0.1078477071581498, 7.771561172376096e-15) verifyPValues(longley, expectedPValues, "longley") # Spearman's expectedCorrelation <- matrix(c( 1, 0.982352941176471, 0.985294117647059, 0.564705882352941, 0.2264705882352941, 0.976470588235294, 0.976470588235294, 0.982352941176471, 1, 0.997058823529412, 0.664705882352941, 0.2205882352941176, 0.997058823529412, 0.997058823529412, 0.985294117647059, 0.997058823529412, 1, 0.638235294117647, 0.2235294117647059, 0.9941176470588236, 0.9941176470588236, 0.564705882352941, 0.664705882352941, 0.638235294117647, 1, -0.3411764705882353, 0.685294117647059, 0.685294117647059, 0.2264705882352941, 0.2205882352941176, 0.2235294117647059, -0.3411764705882353, 1, 0.2264705882352941, 0.2264705882352941, 0.976470588235294, 0.997058823529412, 0.9941176470588236, 0.685294117647059, 0.2264705882352941, 1, 1, 0.976470588235294, 0.997058823529412, 0.9941176470588236, 0.685294117647059, 0.2264705882352941, 1, 1), nrow = 7, ncol = 7, byrow = TRUE) verifySpearmansCorrelation(longley, expectedCorrelation, "longley") # Swiss Fertility --------------------------------------------------------- fertility <- matrix(c(80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33), nrow = 47, ncol = 5, byrow = TRUE) # Pearson's expectedCorrelation <- matrix(c( 1, 0.3530791836199747, -0.6458827064572875, -0.663788857035069, 0.463684700651794, 0.3530791836199747, 1, -0.6865422086171366, -0.63952251894832, 0.4010950530487398, -0.6458827064572875, -0.6865422086171366, 1, 0.698415296288483, -0.572741806064167, -0.663788857035069, -0.63952251894832, 0.698415296288483, 1, -0.1538589170909148, 0.463684700651794, 0.4010950530487398, -0.572741806064167, -0.1538589170909148, 1), nrow = 5, ncol = 5, byrow = TRUE) verifyPearsonsCorrelation(fertility, expectedCorrelation, "swiss fertility") expectedPValues <- c( 0.01491720061472623, 9.45043734069043e-07, 9.95151527133974e-08, 3.658616965962355e-07, 1.304590105694471e-06, 4.811397236181847e-08, 0.001028523190118147, 0.005204433539191644, 2.588307925380906e-05, 0.301807756132683) verifyPValues(fertility, expectedPValues, "swiss fertility") # Spearman's expectedCorrelation <- matrix(c( 1, 0.2426642769364176, -0.660902996352354, -0.443257690360988, 0.4136455623012432, 0.2426642769364176, 1, -0.598859938748963, -0.650463814145816, 0.2886878090882852, -0.660902996352354, -0.598859938748963, 1, 0.674603831406147, -0.4750575257171745, -0.443257690360988, -0.650463814145816, 0.674603831406147, 1, -0.1444163088302244, 0.4136455623012432, 0.2886878090882852, -0.4750575257171745, -0.1444163088302244, 1), nrow = 5, ncol = 5, byrow = TRUE) verifySpearmansCorrelation(fertility, expectedCorrelation, "swiss fertility") displayDashes(WIDTH) commons-math-2.2-src/src/test/R/binomialTestCases100644 1750 1750 11107 11532241241 20613 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #------------------------------------------------------------------------------ # R source file to validate Binomial distribution tests in # org.apache.commons.math.distribution.BinomialDistributionTest # # To run the test, install R, put this file and testFunctions # into the same directory, launch R from this directory and then enter # source("") # # R functions used # dbinom(x, size, prob, log = FALSE) <- density # pbinom(q, size, prob, lower.tail = TRUE, log.p = FALSE) <- distribution # qbinom(p, size, prob, lower.tail = TRUE, log.p = FALSE) <- quantiles #------------------------------------------------------------------------------ tol <- 1E-4 # error tolerance for tests #------------------------------------------------------------------------------ # Function definitions source("testFunctions") # utility test functions # function to verify density computations verifyDensity <- function(points, expected, n, p, tol) { rDensityValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDensityValues[i] <- dbinom(point, n, p, log = FALSE) } output <- c("Density test n = ", n, ", p = ", p) if (assertEquals(expected,rDensityValues,tol,"Density Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } # function to verify distribution computations verifyDistribution <- function(points, expected, n, p, tol) { rDistValues <- rep(0, length(points)) i <- 0 for (point in points) { i <- i + 1 rDistValues[i] <- pbinom(point, n, p, log = FALSE) } output <- c("Distribution test n = ", n, ", p = ", p) if (assertEquals(expected,rDistValues,tol,"Distribution Values")) { displayPadded(output, SUCCEEDED, WIDTH) } else { displayPadded(output, FAILED, WIDTH) } } #-------------------------------------------------------------------------- cat("Binomial test cases\n") size <- 10.0 probability <- 0.70 densityPoints <- c(-1,0,1,2,3,4,5,6,7,8,9,10,11) densityValues <- c(0, 0.0000, 0.0001, 0.0014, 0.0090, 0.0368, 0.1029, 0.2001, 0.2668, 0.2335, 0.1211, 0.0282, 0) distributionValues <- c(0, 0.0000, 0.0001, 0.0016, 0.0106, 0.0473, 0.1503, 0.3504, 0.6172, 0.8507, 0.9718, 1, 1) inverseCumPoints <- c( 0.001, 0.010, 0.025, 0.050, 0.100, 0.999, 0.990, 0.975, 0.950, 0.900) inverseCumValues <- c(1, 2, 3, 4, 4, 9, 9, 9, 8, 8) verifyDensity(densityPoints,densityValues,size,probability,tol) verifyDistribution(densityPoints, distributionValues, size, probability, tol) i <- 0 rInverseCumValues <- rep(0,length(inverseCumPoints)) for (point in inverseCumPoints) { i <- i + 1 rInverseCumValues[i] <- qbinom(point, size, probability, log = FALSE) } output <- c("Inverse Distribution test n = ", size, ", p = ", probability) # R defines quantiles from the right, need to subtract one if (assertEquals(inverseCumValues, rInverseCumValues-1, tol, "Inverse Dist Values")) { displayPadded(output, SUCCEEDED, 80) } else { displayPadded(output, FAILED, 80) } # Degenerate cases size <- 5 probability <- 0.0 densityPoints <- c(-1, 0, 1, 10, 11) densityValues <- c(0, 1, 0, 0, 0) distributionPoints <- c(-1, 0, 1, 5, 10) distributionValues <- c(0, 1, 1, 1, 1) verifyDensity(densityPoints,densityValues,size,probability,tol) verifyDistribution(distributionPoints,distributionValues,size,probability,tol) size <- 5 probability <- 1.0 densityPoints <- c(-1, 0, 1, 2, 5, 10) densityValues <- c(0, 0, 0, 0, 1, 0) distributionPoints <- c(-1, 0, 1, 2, 5, 10) distributionValues <- c(0, 0, 0, 0, 1, 1) verifyDensity(densityPoints,densityValues,size,probability,tol) verifyDistribution(distributionPoints,distributionValues,size,probability,tol) displayDashes(WIDTH) commons-math-2.2-src/src/test/resources/org/apache/commons/math/random/emptyFile.txt100644 1750 1750 0 11532241244 27354 0ustarlucluc 0 0 commons-math-2.2-src/src/test/resources/org/apache/commons/math/random/testData.txt100644 1750 1750 43270 11532241244 27307 0ustarlucluc 0 0 4.038625496201205 3.6485326248346936 3.6651209675932845 5.814896279561131 5.384126469824717 5.251190723365563 4.465213440111648 4.736608014129308 5.566383814840726 3.8872277480629114 5.246598498086048 3.7511487364188176 6.733371385175343 5.388632419618035 6.036263402962769 3.8105605069222905 5.738599503606028 4.994552792425298 2.945504336988336 4.095314381239862 5.760924710543879 3.889753944419315 3.808861160991701 5.084302950012555 6.370292933705698 5.9615431859588455 4.8790354385481445 4.068164663649243 4.26491661935213 5.911067976258105 4.1316140545022115 4.0479985648577115 5.560425919351912 5.7777862258090265 4.6491664757229145 5.322284766164775 3.9643060017297818 3.3374606422520423 4.070818520139152 5.162814971692577 4.68959876937858 5.729533112912969 7.160010937980058 5.154920628387343 5.992604820701763 5.317279162752973 6.3388993007264 4.38451874656454 5.024014917973479 3.7534872319471946 5.042363342784924 5.528064915562473 4.645749024871185 2.5572755520373756 3.953716919712825 3.479482401208564 4.676100783445583 4.602236051449888 7.136692300563229 3.2411466558895095 4.188618724984135 3.6403999184454445 3.4104206071160776 4.807963390662261 4.039073733966207 4.201017826594899 4.381868005163936 5.0635235098658935 5.9840760229548735 4.195400406346137 5.649256144660377 4.679088153774095 4.169683379901892 5.671299804360453 6.159089864893807 5.315685219074694 6.3327786025390305 5.57348047674858 6.124073677151904 4.599177837977919 4.792320274522308 5.670142645005109 5.479531549270221 4.7740747976996705 4.99464290442364 5.474337090086012 5.232353744280737 6.411298157619626 4.757268066271138 5.217779158748026 5.07395379944902 5.5759984176628965 4.521182520094989 5.738026445940142 4.742204968903384 4.670762511507285 4.884925361512115 3.2573282568729462 4.548387675110013 4.337950021352034 3.7875587274144618 3.6055586455442974 7.361861332197413 4.834945622163155 6.019473054836964 4.453304225895349 3.258695681592217 5.794572588445252 3.706438851580378 6.079300672323756 4.828008457182361 5.315261102210712 3.981847695058188 4.039767325290114 5.790863349525503 5.160671471128728 4.835236459763434 4.405281184174698 6.036293520404953 5.889067983920324 4.645514887430352 4.347244670972515 6.447181244432997 6.564267268399325 5.1013992003059885 4.123378901103389 2.7101740954226283 4.209200680057913 5.085704888132955 4.26810090240086 5.54254381015526 4.721081268239747 6.890088385585999 3.9983110493877954 5.321006894021748 4.316867375040024 3.694764624577479 5.453875921043777 3.7798857421649927 3.7228653199742623 4.807698651287013 3.953745662132547 4.821189486606762 4.453489509051613 6.4517275696030225 4.823034188588044 4.722822481625316 5.810689805246644 2.79248319144007 4.928162269110059 4.661918219482871 4.574123379557206 5.241478194631993 5.8345087395944155 7.024415739565572 3.5536052565954 6.095523994939967 5.714650096778455 4.846741263282074 6.002769586957791 5.982356840660745 5.045480762532407 6.461077219605347 4.806649266171423 6.350848113862498 6.402679936682352 3.8190196431210914 4.189064677946727 4.868517260374518 2.145198341547173 5.9469461091347 5.88772432287321 4.258280909990726 6.740134075161574 4.6047650031608445 3.9273659909763774 4.291244045368331 5.183827109845055 5.696810583954774 3.608472134466666 4.169004030425733 3.9965477474540467 3.7571221568428017 5.575534565152322 5.0764208309825065 5.3185446180363485 5.157450995663762 4.961815558094033 5.687338919107788 4.185906295178724 4.382007991332045 3.5280961455873676 4.531506809760329 4.5870808989545635 4.1932173503939625 7.213813469684956 3.1814836225682908 4.647297462243001 5.223975935315364 5.585001659776854 5.120918864744974 5.026571594328509 6.348097968923147 6.50023470519147 5.712556147497515 5.206026515338916 5.749621140061565 3.0714726650374033 6.576852312067237 7.873101351668455 6.565410149266118 6.42923283018875 4.576910183319347 4.891822273316748 6.059357175219146 3.5324494806223328 5.02539429500825 6.078049839679652 4.395054417468175 5.710022806162443 5.577091376894232 3.131753802875934 5.4869998928318 6.413992453090146 6.368380820674971 6.052068461844252 5.480278219624535 7.051236227914206 4.748415087916627 4.559239556696287 4.780665068784505 5.349223485326002 4.522305152002386 5.678473361027541 6.734219964637535 6.713281662687456 6.22214905332774 5.716102543806569 6.336616632829493 4.8399311234283635 5.811391244308217 4.3965755331585905 5.297963707368242 5.021726117260926 4.497125082388555 4.735667209277485 6.048804114181307 4.264048138073914 7.181013762432201 4.781684059171574 5.779533272721499 4.164421460389599 3.6986809242837757 4.8415576143236185 4.924528568365373 4.758045335351253 5.628351489493518 5.7967639104855415 4.491988822693669 2.776750089391839 4.704679957076673 4.039607278211126 5.660350110077993 4.955611684289963 3.0641653090331107 4.896101875253389 3.6528358436331603 5.552472713484715 4.857203367367906 6.698826102960048 4.485176970803183 3.359916665137426 4.036570806638963 3.48793689188148 4.19214761961293 3.9792199677002866 6.760873252923419 4.333561067615548 5.018626873497648 3.377671327382937 4.426183834007672 8.806961710969402 5.2068790380550265 5.483008251803699 4.287267636533901 5.931330465014387 5.257260104496106 4.623908313559696 4.365112456604631 5.600514050451817 6.184093404453588 4.9116883675838485 6.019780977080248 7.485280872899538 3.5982660410679284 4.232210941334369 5.446496617538108 6.487976163896015 3.3960660696641156 4.733884295853101 5.352545256764909 4.107747627715545 3.949506252011129 5.017847997679714 4.24906287118262 6.720303792581198 5.832137142236708 5.010377506040941 6.458070081692352 6.501223021355141 4.612768564431788 3.801740464538825 4.469721893125596 5.061713024524103 6.872685648715577 6.145993249521355 4.638532388190405 4.70471535512485 6.417576222531886 4.118577249932789 4.431328683019108 4.747884983644578 4.495605382683923 3.5972439735401767 5.210796056817244 2.9160129894156026 3.4596190721900797 3.972452277026154 5.5237190584690214 6.104711796147512 4.787324556447702 4.548676032231089 6.356843891618192 3.6148998030697816 4.760679260180754 4.698041709266617 4.244003753086054 5.595546833817678 3.2784025595193267 5.326657347561453 6.213858447402109 5.213011705084566 7.232075882741927 4.806572191866972 4.680144670146755 3.946663831660007 3.6143084085883554 7.789315918667734 7.099181638561095 3.672742516732736 5.953845998789752 6.28847712720666 6.946689084108734 6.325454389782429 4.334133006331358 3.039424552213366 4.847328734611504 4.249781519880862 6.126424188695286 3.3823135936253257 6.3280255743100025 6.150431997847958 5.4226742397784005 5.94864601826791 4.425906835511732 4.897545227095195 6.26027333638832 3.647858418615367 5.276322437292433 4.176876069581277 4.346107259567459 3.1384418250329995 4.212957347421948 4.637757894698186 6.535589923573854 5.193072556110316 5.017309492685374 5.1750466093509 4.6381038872450375 6.071604634493695 4.357240286904764 5.122391923621759 6.556903940099011 3.8006848201076036 4.522363890394659 6.2456602471550635 5.829300589393535 4.452647643620209 5.371890862621703 4.948677662633424 5.661113800822228 5.773629402623548 6.139823333391851 6.093004328053013 5.362399773949667 6.915042845179306 5.394739321037944 5.141451574018252 5.053294383161769 4.9834920876470665 6.812746808763125 3.5705971688428266 4.664119854301202 6.310596552569324 5.674835228932813 3.4639740645984807 4.788956793299906 5.1005488900135845 4.534989910256703 3.931742089464332 3.572625977535623 5.374511045697475 3.859408179493194 5.767053789854141 5.1414168750827285 4.7490168496463525 7.481142748403815 4.5189492261011575 5.40235395980428 6.700234279658992 3.5063554778412183 3.9690452319798735 3.00630763890251 7.23611608840341 5.018006325958164 4.523410620276403 4.076684362167451 5.916234395538267 7.047286572236027 3.8682363461132017 4.390658924201581 4.5292330092964255 5.07906584568947 4.671213490610071 4.095193931403399 4.054590162572947 3.2227278245030027 6.132646335444107 2.8407359953623814 4.7279370282096655 5.593872406613741 3.382542536766184 5.85844025043303 6.461000354065181 3.4994741020969773 4.132683344034104 5.647894883473891 5.011301190267978 4.401435886120444 3.3496957519609927 6.119687677370172 4.644762759286699 4.5205629205178735 3.0320051244977195 4.596487037061894 5.14520534308978 5.282269168918912 5.761372455401502 4.148416743583162 6.372742039103559 5.649143130777574 5.084494528193606 4.811163551671385 3.9806520282362476 4.411511792047385 4.670987670787611 5.768451736319585 3.984558689428816 5.3293696591099975 5.413539058295544 6.40970782426591 5.481145473625602 4.36515208836978 5.161811987273001 3.963554978392394 5.098946908474979 7.786683053797615 4.927631219070586 5.524180021898693 4.523736107490982 3.557364094609177 6.128701594561169 4.2509207146594115 3.944944115965259 4.966138264389299 5.394430219583224 6.77531735530901 4.128069102169693 5.2683457909620355 3.8872836447608496 4.486696800422189 6.5335585640393825 4.916400608546338 4.270979919569207 4.311416898242187 4.498167295277512 6.132808180917634 5.1041291367018875 5.498388642491546 5.584526454067219 6.142894025331306 4.944671156061267 4.1686843376349945 4.818977261651865 6.235820918635881 3.3212806573760028 5.68435151611855 6.189749316228399 3.591267557367338 5.043902793214377 7.818905185451641 4.768708643560666 5.669288800286096 6.398657810380692 5.3717200778027605 5.2573487416126525 4.822935237131512 6.182572962936934 5.6072955002277105 3.9675191626756288 6.350858167126948 6.283995295688788 4.445782391191543 6.877548745307459 5.3208290700871315 6.09847688940267 6.434994026138841 4.32779758193763 7.2924037238697 5.419935895280957 4.288818201810987 7.242433265647824 4.947890367713541 5.916218606455959 6.490437527083841 4.617582424838291 7.957708355752131 4.879357620439287 6.103294400805588 5.639488259504568 4.335236791293937 5.202542624850618 5.4406339076225505 5.782530244910674 4.055314639567904 5.552293301411749 5.290496801505254 4.022580394801182 4.625571974654451 5.5086593656510825 4.913637297182931 4.906396844626936 6.439485089212817 5.7942799739945325 7.158136207286507 4.280431104751667 3.9206066719991517 5.127791240556268 6.70098532482022 4.657147097255419 4.524267698037553 4.647534545829241 4.839690189371444 6.798322548455047 5.094754599613737 5.916399329150566 5.767837713902285 5.294550523894544 4.161295164684424 5.233358678928891 5.546871474458429 4.897048191655597 3.939430251326603 5.005888208270397 3.2926576330038655 4.0159694347757835 5.056229917378723 6.568879235955665 4.497327615853924 4.690014685240942 4.746884105330737 4.841384111334085 4.14796180246966 5.461902744235217 5.869304766250897 3.52354738655413 5.582741221891035 4.997825621424692 5.439611672191855 4.819402835865619 5.76136287301575 6.143090288547951 5.976125217642891 6.157007787875113 4.912778652906766 6.540414953620538 3.8210262932626495 4.727149320768898 4.955255599543759 5.7983414047818265 5.167409288825197 5.059246623397723 6.965380962189423 5.531311904089661 5.4022568784996885 4.344352255655229 5.745261070226892 5.118820012265567 4.960430609470355 4.487905086804239 3.8537512154805835 4.839114062528739 5.367538410451759 6.202050661574205 4.001800559371117 6.119617239220475 3.236283913097008 5.610134770285298 5.757041556538514 4.083399027093518 5.055588718117847 4.580930359877383 6.545516697552579 5.916270431823864 3.761559453909257 6.037777237143994 7.29718541816528 4.8965176227762734 3.941358569293476 3.9289815988008847 3.2604315357316436 4.639329221347256 6.570997662310685 3.851958625190621 5.859087244914328 4.647365626452129 6.076778087850363 4.627936340272149 4.422345848512504 6.2183675417422 5.243889853389288 5.90909311946919 6.09260484846961 6.0271781583360475 6.913810502971691 5.285845705409185 5.318460367681083 5.179580543035928 4.6834977896331615 5.382546996207003 4.606307320228796 4.038858683454586 6.271279252908354 6.0668723017439365 5.713564644555386 5.144428649779485 5.2496039700779615 3.8392027391676207 4.7050632415088876 7.137275712725372 4.208879180827962 4.81480733241727 4.699941077536472 4.423440083005291 5.742161495602944 4.592506326637019 6.224046541049566 4.611093653533141 6.1166037746546165 5.904004955760586 5.589433336321981 4.57489510266225 5.500028469975376 4.382479722617695 4.257470376496386 6.373209588018213 5.375461447759072 2.8662337475774584 4.699832117278568 3.102810935311515 6.501460955698313 4.550333534073201 7.944860661426514 5.69020177364993 4.006199611798767 5.11813341012065 4.896479097282944 4.816212778128475 4.940296064591277 5.419056166663748 3.4659391357743616 7.246324501631043 5.907112751874067 5.614502217435809 4.750614593197476 7.0951293897280205 4.3819944682346055 4.958360318480322 4.962367933857186 5.715499159595656 5.220101872658552 6.088622700649866 5.491586360474799 4.656477235994459 3.8695533953710326 3.7143742249025538 3.7411936672155304 6.603415889834424 5.62928670505705 5.5959396553858785 5.6577330557176095 6.003846653929077 4.508563176717718 5.549881486113916 4.953305865372426 6.203554032873964 5.612208234244517 4.854464793588011 5.263585016371758 3.897600440182904 5.981235398882815 5.531277293213279 4.8817070690071445 3.712544699529063 3.513432242611217 5.006035295792077 7.124520658535316 3.4782033127607037 4.829578059223972 5.742892584711905 4.361333503197903 4.601687049512891 6.035189727259647 4.711273209758127 4.272043208125593 4.447702393976457 5.17487393756583 4.741015989802225 4.953808452791662 4.6645084492292765 4.276788530554644 7.325515154525428 4.602597440231014 5.082884146093998 3.068409439905545 4.809983425115099 3.8747882947708083 4.893233436073575 5.376932606908371 6.239910432522629 6.041695571547008 5.317735375674715 5.160517819092331 5.283748111202239 6.5357867130743745 5.537247902605441 5.4185896683530235 5.287616337544387 5.981700012459223 5.992385624329782 5.758772999982491 4.599744432168506 5.7237660286844605 2.5862937961454855 4.319918124665613 7.566860260437548 3.202784785619934 6.67642720284947 5.215802050091852 5.452814592454087 4.192858032386887 5.299199379721475 3.291677765243241 4.632695766333648 5.115714853147839 4.996260485718097 3.5271286032511773 4.659715887897552 6.587392147323261 5.989132075359954 3.8378063660060056 4.975951043892332 3.90853196371359 5.708783809093124 6.591895462100242 5.653528117636727 3.665428787393319 4.324537690925271 6.234413976864244 4.053504794002944 5.713371183460703 4.670243561862966 3.352660528859447 4.020147292531281 5.121933145078237 4.282377411958472 4.088770874857499 4.275716553910016 4.284046155337823 6.449567142111275 3.3275914286077084 4.837717853228399 5.261182985672333 6.073443097165901 5.40483608136289 4.690566013556853 4.222184746341714 5.790245443382679 5.020060832906476 5.576527321711127 5.340393035828579 5.301460661931292 5.076040366457228 6.296482877500045 3.037720796600903 6.321850760102656 5.701339165316606 4.991940459105436 5.758970102557518 4.322111367356909 5.721255109646473 5.511881303620453 4.9563635195228954 6.861001584068987 3.8299029968884195 4.322974731453332 5.3047403550360634 6.0756269754391825 6.117153630436378 4.5085862451026495 4.832132638553977 4.699215334058029 7.982648077178181 3.303778194960711 6.845166964779691 5.175136241842978 5.611538016661082 4.293354218279116 6.2617605857039775 4.646868778200023 5.596211970851805 6.4731028962866635 5.9737535333484795 6.411386536458501 2.7695062051965302 3.5560570906765894 5.451690061978083 6.503535887841675 4.695530301460264 4.706120568510652 2.800841111510871 5.364729318170148 5.1911558656154835 5.947415408072919 4.777513714112934 4.596459418828304 5.043317097051506 5.174749896541634 5.258257882159918 3.887023257269741 5.131383317673293 5.843231353166214 6.472487193651527 5.763704927517821 6.024396779444038 4.926879229092987 6.558645082464584 5.447575064546803 4.286751335276036 3.9071252303818644 4.618489035299945 5.088217807208579 3.808752600228301 5.861810119867259 4.033532296400091 5.74542761207288 4.925806147050348 3.679404591586196 4.05604604887352 5.87881882930846 4.513573760688276 4.915009783906388 3.654483449601882 4.912095784340134 3.3774256594506396 4.188548007093734 5.4860540834510445 4.483111427918742 6.091604204270534 4.913639044459108 6.347957296069254 5.777137740280461 4.996625717628335 3.357832000765961 4.529640780144531 6.655383658310578 5.187418414545693 5.275067584707507 5.50723064248028 4.636201988408981 4.947416066568987 7.027581910469225 4.570962245627946 5.947355941474328 4.7057667163042245 4.786943520378938 5.615852784022176 4.645129057815488 5.263882354785195 3.844951724466573 5.554260404852657 4.684091248268045 5.13336102667963 3.417837773686996 4.392489033666552 6.270027300253521 6.102372796945901 4.219653651099504 5.076173402237902 4.383422445264855 3.0437995085361025 5.377941796580727 6.276975902314367 4.315133675763909 5.507204150696545 4.886780791403244 7.147240935203286 3.900457465197911 5.102470142455588 7.084247234995372 5.457300111792919 4.60867925423519 6.2840312118540815 7.236947706509271 7.133509547170027 4.3015318378968 5.043756433592529 5.108881706267525 5.5240023845728645 5.858632364389344 5.981971317600007 6.259948473084726 4.062783955426871 5.218852203995356 3.8038254404258813 4.758585778361602 4.376196481713867 4.458880802424765 3.96326498727664 3.6778134622710104 4.374934998721925 7.489468914416122 5.700987063590436 3.3100952240676955 5.1696122166092415 6.541584919841012 4.4595571152023465 4.366611842258099 5.382259676070623 4.7794428978336825 3.757838857759169 6.545307984939696 4.881890171568036 5.7063933726311165 4.7730257133517116 3.873677842944983 3.840259191338565 4.593661080441791 4.511107632929962 5.5385052402039605 5.441167937479936 5.984890322415174 5.403820054129332 5.148546201719365 4.838476271562129 6.2440438844133075 3.9741885421050913 6.327490860577795 4.633940514497735 5.232122748521683 4.456999940494487 5.576626928088951 3.2818610857426584 5.134684374559793 4.602466559265273 5.891324885962796 5.517816321593768 6.624687761337339 5.2683180340267874 4.662418552035468 4.622236368091395 5.536060664096081 3.272870360657461 3.9899131914173696 5.121549579739896 5.928806028927443 4.259133981719825 5.313734011651727 5.635277610987355 4.524627655490917 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/Lew.txt100644 1750 1750 7025 11532241244 26647 0ustarlucluc 0 0 ##################################################################### # Dataset Name: Lew (Beam Deflection Data) # # Description: This is an observed/"real world" data set # consisting of 200 deflections of a steel-concrete # beam while subjected to periodic pressure. # The experimenter was H. S. Lew of the # Center for Building Technology at NIST. # We here use this data to test accuracy # in summary statistics calculations. # # Stat Category: Univariate: Summary Statistics # # Reference: http://www.itl.nist.gov/div898/strd/univ/lew.html # # Data: "Real World" # 1 Response : y = beam deflection # 0 Predictors # 200 Observations # # Model: Lower Level of Difficulty # 2 Parameters : mu, sigma # 1 Response Variable : y # 0 Predictor Variables # y = mu + e ##################################################################### ##################################################################### # # Certified Values # ##################################################################### n = 200 mean = -177.435000000000 standardDeviation = 277.332168044316 autocorrelationCoefficient = -0.307304800605679 ##################################################################### # # R Generated Values # ##################################################################### variance = 76913.13143 max = 300 min = -579 sum = -35487 ##################################################################### # # Data # ##################################################################### -213 -564 -35 -15 141 115 -420 -360 203 -338 -431 194 -220 -513 154 -125 -559 92 -21 -579 -52 99 -543 -175 162 -457 -346 204 -300 -474 164 -107 -572 -8 83 -541 -224 180 -420 -374 201 -236 -531 83 27 -564 -112 131 -507 -254 199 -311 -495 143 -46 -579 -90 136 -472 -338 202 -287 -477 169 -124 -568 17 48 -568 -135 162 -430 -422 172 -74 -577 -13 92 -534 -243 194 -355 -465 156 -81 -578 -64 139 -449 -384 193 -198 -538 110 -44 -577 -6 66 -552 -164 161 -460 -344 205 -281 -504 134 -28 -576 -118 156 -437 -381 200 -220 -540 83 11 -568 -160 172 -414 -408 188 -125 -572 -32 139 -492 -321 205 -262 -504 142 -83 -574 0 48 -571 -106 137 -501 -266 190 -391 -406 194 -186 -553 83 -13 -577 -49 103 -515 -280 201 300 -506 131 -45 -578 -80 138 -462 -361 201 -211 -554 32 74 -533 -235 187 -372 -442 182 -147 -566 25 68 -535 -244 194 -351 -463 174 -125 -570 15 72 -550 -190 172 -424 -385 198 -218 -536 96 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/NumAcc3.txt100644 1750 1750 32664 11532241244 27400 0ustarlucluc 0 0 File Name: NumAcc3.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 1061 (= 1001) Dataset Name: NumAcc3 Description: This is a constructed/fabricated data set to test accuracy in summary statistic calculations. The numbers are 8-digit floating point values and differ only in the last decimal place. Note--by construction, this data set has sample mean = 1000000.2 (exact) sample standard dev. = 0.1 (exact) sample autocorr. coef. = -0.999 (exact) Stat Category: Univariate: Summary Statistics Reference: Simon, Stephen D. and Lesage, James P. (1989). Assessing the Accuracy of ANOVA Caluclations in Statistical Software", Computational Statistics & data Analysis, 8, pp. 325-332. Data: Constructed 1 Response : y 0 Predictors 1001 Observations Model: Average Level of Difficulty 2 Parameters : mu, sigma 1 Response Variable : y 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 1000000.2 Sample Standard Deviation (denom. = n-1) s: 0.1 Sample Autocorrelation Coefficient (lag 1) r(1): -0.999 Number of Observations: 1001 Data: Y ------------- 1000000.2 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 1000000.1 1000000.3 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/PiDigits.txt100644 1750 1750 120645 11532241244 27700 0ustarlucluc 0 0 File Name: PiDigits.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 5060 (= 5000) Dataset Name: PiDigits Description: This is a constructed/fabricated data set to test accuracy in summary statistic calculations. The numbers are the first 5000 digits of the mathematical constant pi (= 3.1415926535897932384...). Stat Category: Univariate Reference: Mathematics of Computation. January 1962, page 76. Data: Constructed Variable --> 1 Response : y = pi digits --> 0 Predictors --> 5000 Observations Model: Lower Level of Difficulty --> 2 Parameters : mu, sigma --> 1 Response Variable : y --> 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 4.53480000000000 Sample Standard Deviation (denom. = n-1) s: 2.86733906028871 Sample Autocorrelation Coefficient (lag 1) r(1): -0.00355099287237972 Number of Observations: 5000 Data: Y --------- 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 1 6 9 3 9 9 3 7 5 1 0 5 8 2 0 9 7 4 9 4 4 5 9 2 3 0 7 8 1 6 4 0 6 2 8 6 2 0 8 9 9 8 6 2 8 0 3 4 8 2 5 3 4 2 1 1 7 0 6 7 9 8 2 1 4 8 0 8 6 5 1 3 2 8 2 3 0 6 6 4 7 0 9 3 8 4 4 6 0 9 5 5 0 5 8 2 2 3 1 7 2 5 3 5 9 4 0 8 1 2 8 4 8 1 1 1 7 4 5 0 2 8 4 1 0 2 7 0 1 9 3 8 5 2 1 1 0 5 5 5 9 6 4 4 6 2 2 9 4 8 9 5 4 9 3 0 3 8 1 9 6 4 4 2 8 8 1 0 9 7 5 6 6 5 9 3 3 4 4 6 1 2 8 4 7 5 6 4 8 2 3 3 7 8 6 7 8 3 1 6 5 2 7 1 2 0 1 9 0 9 1 4 5 6 4 8 5 6 6 9 2 3 4 6 0 3 4 8 6 1 0 4 5 4 3 2 6 6 4 8 2 1 3 3 9 3 6 0 7 2 6 0 2 4 9 1 4 1 2 7 3 7 2 4 5 8 7 0 0 6 6 0 6 3 1 5 5 8 8 1 7 4 8 8 1 5 2 0 9 2 0 9 6 2 8 2 9 2 5 4 0 9 1 7 1 5 3 6 4 3 6 7 8 9 2 5 9 0 3 6 0 0 1 1 3 3 0 5 3 0 5 4 8 8 2 0 4 6 6 5 2 1 3 8 4 1 4 6 9 5 1 9 4 1 5 1 1 6 0 9 4 3 3 0 5 7 2 7 0 3 6 5 7 5 9 5 9 1 9 5 3 0 9 2 1 8 6 1 1 7 3 8 1 9 3 2 6 1 1 7 9 3 1 0 5 1 1 8 5 4 8 0 7 4 4 6 2 3 7 9 9 6 2 7 4 9 5 6 7 3 5 1 8 8 5 7 5 2 7 2 4 8 9 1 2 2 7 9 3 8 1 8 3 0 1 1 9 4 9 1 2 9 8 3 3 6 7 3 3 6 2 4 4 0 6 5 6 6 4 3 0 8 6 0 2 1 3 9 4 9 4 6 3 9 5 2 2 4 7 3 7 1 9 0 7 0 2 1 7 9 8 6 0 9 4 3 7 0 2 7 7 0 5 3 9 2 1 7 1 7 6 2 9 3 1 7 6 7 5 2 3 8 4 6 7 4 8 1 8 4 6 7 6 6 9 4 0 5 1 3 2 0 0 0 5 6 8 1 2 7 1 4 5 2 6 3 5 6 0 8 2 7 7 8 5 7 7 1 3 4 2 7 5 7 7 8 9 6 0 9 1 7 3 6 3 7 1 7 8 7 2 1 4 6 8 4 4 0 9 0 1 2 2 4 9 5 3 4 3 0 1 4 6 5 4 9 5 8 5 3 7 1 0 5 0 7 9 2 2 7 9 6 8 9 2 5 8 9 2 3 5 4 2 0 1 9 9 5 6 1 1 2 1 2 9 0 2 1 9 6 0 8 6 4 0 3 4 4 1 8 1 5 9 8 1 3 6 2 9 7 7 4 7 7 1 3 0 9 9 6 0 5 1 8 7 0 7 2 1 1 3 4 9 9 9 9 9 9 8 3 7 2 9 7 8 0 4 9 9 5 1 0 5 9 7 3 1 7 3 2 8 1 6 0 9 6 3 1 8 5 9 5 0 2 4 4 5 9 4 5 5 3 4 6 9 0 8 3 0 2 6 4 2 5 2 2 3 0 8 2 5 3 3 4 4 6 8 5 0 3 5 2 6 1 9 3 1 1 8 8 1 7 1 0 1 0 0 0 3 1 3 7 8 3 8 7 5 2 8 8 6 5 8 7 5 3 3 2 0 8 3 8 1 4 2 0 6 1 7 1 7 7 6 6 9 1 4 7 3 0 3 5 9 8 2 5 3 4 9 0 4 2 8 7 5 5 4 6 8 7 3 1 1 5 9 5 6 2 8 6 3 8 8 2 3 5 3 7 8 7 5 9 3 7 5 1 9 5 7 7 8 1 8 5 7 7 3 0 5 3 2 1 7 1 2 2 6 8 0 6 6 1 3 0 0 1 9 2 7 8 7 6 6 1 1 1 9 5 9 0 9 2 1 6 4 2 0 1 9 8 9 3 8 0 9 5 2 5 7 2 0 1 0 6 5 4 8 5 8 6 3 2 7 8 8 6 5 9 3 6 1 5 3 3 8 1 8 2 7 9 6 8 2 3 0 3 0 1 9 5 2 0 3 5 3 0 1 8 5 2 9 6 8 9 9 5 7 7 3 6 2 2 5 9 9 4 1 3 8 9 1 2 4 9 7 2 1 7 7 5 2 8 3 4 7 9 1 3 1 5 1 5 5 7 4 8 5 7 2 4 2 4 5 4 1 5 0 6 9 5 9 5 0 8 2 9 5 3 3 1 1 6 8 6 1 7 2 7 8 5 5 8 8 9 0 7 5 0 9 8 3 8 1 7 5 4 6 3 7 4 6 4 9 3 9 3 1 9 2 5 5 0 6 0 4 0 0 9 2 7 7 0 1 6 7 1 1 3 9 0 0 9 8 4 8 8 2 4 0 1 2 8 5 8 3 6 1 6 0 3 5 6 3 7 0 7 6 6 0 1 0 4 7 1 0 1 8 1 9 4 2 9 5 5 5 9 6 1 9 8 9 4 6 7 6 7 8 3 7 4 4 9 4 4 8 2 5 5 3 7 9 7 7 4 7 2 6 8 4 7 1 0 4 0 4 7 5 3 4 6 4 6 2 0 8 0 4 6 6 8 4 2 5 9 0 6 9 4 9 1 2 9 3 3 1 3 6 7 7 0 2 8 9 8 9 1 5 2 1 0 4 7 5 2 1 6 2 0 5 6 9 6 6 0 2 4 0 5 8 0 3 8 1 5 0 1 9 3 5 1 1 2 5 3 3 8 2 4 3 0 0 3 5 5 8 7 6 4 0 2 4 7 4 9 6 4 7 3 2 6 3 9 1 4 1 9 9 2 7 2 6 0 4 2 6 9 9 2 2 7 9 6 7 8 2 3 5 4 7 8 1 6 3 6 0 0 9 3 4 1 7 2 1 6 4 1 2 1 9 9 2 4 5 8 6 3 1 5 0 3 0 2 8 6 1 8 2 9 7 4 5 5 5 7 0 6 7 4 9 8 3 8 5 0 5 4 9 4 5 8 8 5 8 6 9 2 6 9 9 5 6 9 0 9 2 7 2 1 0 7 9 7 5 0 9 3 0 2 9 5 5 3 2 1 1 6 5 3 4 4 9 8 7 2 0 2 7 5 5 9 6 0 2 3 6 4 8 0 6 6 5 4 9 9 1 1 9 8 8 1 8 3 4 7 9 7 7 5 3 5 6 6 3 6 9 8 0 7 4 2 6 5 4 2 5 2 7 8 6 2 5 5 1 8 1 8 4 1 7 5 7 4 6 7 2 8 9 0 9 7 7 7 7 2 7 9 3 8 0 0 0 8 1 6 4 7 0 6 0 0 1 6 1 4 5 2 4 9 1 9 2 1 7 3 2 1 7 2 1 4 7 7 2 3 5 0 1 4 1 4 4 1 9 7 3 5 6 8 5 4 8 1 6 1 3 6 1 1 5 7 3 5 2 5 5 2 1 3 3 4 7 5 7 4 1 8 4 9 4 6 8 4 3 8 5 2 3 3 2 3 9 0 7 3 9 4 1 4 3 3 3 4 5 4 7 7 6 2 4 1 6 8 6 2 5 1 8 9 8 3 5 6 9 4 8 5 5 6 2 0 9 9 2 1 9 2 2 2 1 8 4 2 7 2 5 5 0 2 5 4 2 5 6 8 8 7 6 7 1 7 9 0 4 9 4 6 0 1 6 5 3 4 6 6 8 0 4 9 8 8 6 2 7 2 3 2 7 9 1 7 8 6 0 8 5 7 8 4 3 8 3 8 2 7 9 6 7 9 7 6 6 8 1 4 5 4 1 0 0 9 5 3 8 8 3 7 8 6 3 6 0 9 5 0 6 8 0 0 6 4 2 2 5 1 2 5 2 0 5 1 1 7 3 9 2 9 8 4 8 9 6 0 8 4 1 2 8 4 8 8 6 2 6 9 4 5 6 0 4 2 4 1 9 6 5 2 8 5 0 2 2 2 1 0 6 6 1 1 8 6 3 0 6 7 4 4 2 7 8 6 2 2 0 3 9 1 9 4 9 4 5 0 4 7 1 2 3 7 1 3 7 8 6 9 6 0 9 5 6 3 6 4 3 7 1 9 1 7 2 8 7 4 6 7 7 6 4 6 5 7 5 7 3 9 6 2 4 1 3 8 9 0 8 6 5 8 3 2 6 4 5 9 9 5 8 1 3 3 9 0 4 7 8 0 2 7 5 9 0 0 9 9 4 6 5 7 6 4 0 7 8 9 5 1 2 6 9 4 6 8 3 9 8 3 5 2 5 9 5 7 0 9 8 2 5 8 2 2 6 2 0 5 2 2 4 8 9 4 0 7 7 2 6 7 1 9 4 7 8 2 6 8 4 8 2 6 0 1 4 7 6 9 9 0 9 0 2 6 4 0 1 3 6 3 9 4 4 3 7 4 5 5 3 0 5 0 6 8 2 0 3 4 9 6 2 5 2 4 5 1 7 4 9 3 9 9 6 5 1 4 3 1 4 2 9 8 0 9 1 9 0 6 5 9 2 5 0 9 3 7 2 2 1 6 9 6 4 6 1 5 1 5 7 0 9 8 5 8 3 8 7 4 1 0 5 9 7 8 8 5 9 5 9 7 7 2 9 7 5 4 9 8 9 3 0 1 6 1 7 5 3 9 2 8 4 6 8 1 3 8 2 6 8 6 8 3 8 6 8 9 4 2 7 7 4 1 5 5 9 9 1 8 5 5 9 2 5 2 4 5 9 5 3 9 5 9 4 3 1 0 4 9 9 7 2 5 2 4 6 8 0 8 4 5 9 8 7 2 7 3 6 4 4 6 9 5 8 4 8 6 5 3 8 3 6 7 3 6 2 2 2 6 2 6 0 9 9 1 2 4 6 0 8 0 5 1 2 4 3 8 8 4 3 9 0 4 5 1 2 4 4 1 3 6 5 4 9 7 6 2 7 8 0 7 9 7 7 1 5 6 9 1 4 3 5 9 9 7 7 0 0 1 2 9 6 1 6 0 8 9 4 4 1 6 9 4 8 6 8 5 5 5 8 4 8 4 0 6 3 5 3 4 2 2 0 7 2 2 2 5 8 2 8 4 8 8 6 4 8 1 5 8 4 5 6 0 2 8 5 0 6 0 1 6 8 4 2 7 3 9 4 5 2 2 6 7 4 6 7 6 7 8 8 9 5 2 5 2 1 3 8 5 2 2 5 4 9 9 5 4 6 6 6 7 2 7 8 2 3 9 8 6 4 5 6 5 9 6 1 1 6 3 5 4 8 8 6 2 3 0 5 7 7 4 5 6 4 9 8 0 3 5 5 9 3 6 3 4 5 6 8 1 7 4 3 2 4 1 1 2 5 1 5 0 7 6 0 6 9 4 7 9 4 5 1 0 9 6 5 9 6 0 9 4 0 2 5 2 2 8 8 7 9 7 1 0 8 9 3 1 4 5 6 6 9 1 3 6 8 6 7 2 2 8 7 4 8 9 4 0 5 6 0 1 0 1 5 0 3 3 0 8 6 1 7 9 2 8 6 8 0 9 2 0 8 7 4 7 6 0 9 1 7 8 2 4 9 3 8 5 8 9 0 0 9 7 1 4 9 0 9 6 7 5 9 8 5 2 6 1 3 6 5 5 4 9 7 8 1 8 9 3 1 2 9 7 8 4 8 2 1 6 8 2 9 9 8 9 4 8 7 2 2 6 5 8 8 0 4 8 5 7 5 6 4 0 1 4 2 7 0 4 7 7 5 5 5 1 3 2 3 7 9 6 4 1 4 5 1 5 2 3 7 4 6 2 3 4 3 6 4 5 4 2 8 5 8 4 4 4 7 9 5 2 6 5 8 6 7 8 2 1 0 5 1 1 4 1 3 5 4 7 3 5 7 3 9 5 2 3 1 1 3 4 2 7 1 6 6 1 0 2 1 3 5 9 6 9 5 3 6 2 3 1 4 4 2 9 5 2 4 8 4 9 3 7 1 8 7 1 1 0 1 4 5 7 6 5 4 0 3 5 9 0 2 7 9 9 3 4 4 0 3 7 4 2 0 0 7 3 1 0 5 7 8 5 3 9 0 6 2 1 9 8 3 8 7 4 4 7 8 0 8 4 7 8 4 8 9 6 8 3 3 2 1 4 4 5 7 1 3 8 6 8 7 5 1 9 4 3 5 0 6 4 3 0 2 1 8 4 5 3 1 9 1 0 4 8 4 8 1 0 0 5 3 7 0 6 1 4 6 8 0 6 7 4 9 1 9 2 7 8 1 9 1 1 9 7 9 3 9 9 5 2 0 6 1 4 1 9 6 6 3 4 2 8 7 5 4 4 4 0 6 4 3 7 4 5 1 2 3 7 1 8 1 9 2 1 7 9 9 9 8 3 9 1 0 1 5 9 1 9 5 6 1 8 1 4 6 7 5 1 4 2 6 9 1 2 3 9 7 4 8 9 4 0 9 0 7 1 8 6 4 9 4 2 3 1 9 6 1 5 6 7 9 4 5 2 0 8 0 9 5 1 4 6 5 5 0 2 2 5 2 3 1 6 0 3 8 8 1 9 3 0 1 4 2 0 9 3 7 6 2 1 3 7 8 5 5 9 5 6 6 3 8 9 3 7 7 8 7 0 8 3 0 3 9 0 6 9 7 9 2 0 7 7 3 4 6 7 2 2 1 8 2 5 6 2 5 9 9 6 6 1 5 0 1 4 2 1 5 0 3 0 6 8 0 3 8 4 4 7 7 3 4 5 4 9 2 0 2 6 0 5 4 1 4 6 6 5 9 2 5 2 0 1 4 9 7 4 4 2 8 5 0 7 3 2 5 1 8 6 6 6 0 0 2 1 3 2 4 3 4 0 8 8 1 9 0 7 1 0 4 8 6 3 3 1 7 3 4 6 4 9 6 5 1 4 5 3 9 0 5 7 9 6 2 6 8 5 6 1 0 0 5 5 0 8 1 0 6 6 5 8 7 9 6 9 9 8 1 6 3 5 7 4 7 3 6 3 8 4 0 5 2 5 7 1 4 5 9 1 0 2 8 9 7 0 6 4 1 4 0 1 1 0 9 7 1 2 0 6 2 8 0 4 3 9 0 3 9 7 5 9 5 1 5 6 7 7 1 5 7 7 0 0 4 2 0 3 3 7 8 6 9 9 3 6 0 0 7 2 3 0 5 5 8 7 6 3 1 7 6 3 5 9 4 2 1 8 7 3 1 2 5 1 4 7 1 2 0 5 3 2 9 2 8 1 9 1 8 2 6 1 8 6 1 2 5 8 6 7 3 2 1 5 7 9 1 9 8 4 1 4 8 4 8 8 2 9 1 6 4 4 7 0 6 0 9 5 7 5 2 7 0 6 9 5 7 2 2 0 9 1 7 5 6 7 1 1 6 7 2 2 9 1 0 9 8 1 6 9 0 9 1 5 2 8 0 1 7 3 5 0 6 7 1 2 7 4 8 5 8 3 2 2 2 8 7 1 8 3 5 2 0 9 3 5 3 9 6 5 7 2 5 1 2 1 0 8 3 5 7 9 1 5 1 3 6 9 8 8 2 0 9 1 4 4 4 2 1 0 0 6 7 5 1 0 3 3 4 6 7 1 1 0 3 1 4 1 2 6 7 1 1 1 3 6 9 9 0 8 6 5 8 5 1 6 3 9 8 3 1 5 0 1 9 7 0 1 6 5 1 5 1 1 6 8 5 1 7 1 4 3 7 6 5 7 6 1 8 3 5 1 5 5 6 5 0 8 8 4 9 0 9 9 8 9 8 5 9 9 8 2 3 8 7 3 4 5 5 2 8 3 3 1 6 3 5 5 0 7 6 4 7 9 1 8 5 3 5 8 9 3 2 2 6 1 8 5 4 8 9 6 3 2 1 3 2 9 3 3 0 8 9 8 5 7 0 6 4 2 0 4 6 7 5 2 5 9 0 7 0 9 1 5 4 8 1 4 1 6 5 4 9 8 5 9 4 6 1 6 3 7 1 8 0 2 7 0 9 8 1 9 9 4 3 0 9 9 2 4 4 8 8 9 5 7 5 7 1 2 8 2 8 9 0 5 9 2 3 2 3 3 2 6 0 9 7 2 9 9 7 1 2 0 8 4 4 3 3 5 7 3 2 6 5 4 8 9 3 8 2 3 9 1 1 9 3 2 5 9 7 4 6 3 6 6 7 3 0 5 8 3 6 0 4 1 4 2 8 1 3 8 8 3 0 3 2 0 3 8 2 4 9 0 3 7 5 8 9 8 5 2 4 3 7 4 4 1 7 0 2 9 1 3 2 7 6 5 6 1 8 0 9 3 7 7 3 4 4 4 0 3 0 7 0 7 4 6 9 2 1 1 2 0 1 9 1 3 0 2 0 3 3 0 3 8 0 1 9 7 6 2 1 1 0 1 1 0 0 4 4 9 2 9 3 2 1 5 1 6 0 8 4 2 4 4 4 8 5 9 6 3 7 6 6 9 8 3 8 9 5 2 2 8 6 8 4 7 8 3 1 2 3 5 5 2 6 5 8 2 1 3 1 4 4 9 5 7 6 8 5 7 2 6 2 4 3 3 4 4 1 8 9 3 0 3 9 6 8 6 4 2 6 2 4 3 4 1 0 7 7 3 2 2 6 9 7 8 0 2 8 0 7 3 1 8 9 1 5 4 4 1 1 0 1 0 4 4 6 8 2 3 2 5 2 7 1 6 2 0 1 0 5 2 6 5 2 2 7 2 1 1 1 6 6 0 3 9 6 6 6 5 5 7 3 0 9 2 5 4 7 1 1 0 5 5 7 8 5 3 7 6 3 4 6 6 8 2 0 6 5 3 1 0 9 8 9 6 5 2 6 9 1 8 6 2 0 5 6 4 7 6 9 3 1 2 5 7 0 5 8 6 3 5 6 6 2 0 1 8 5 5 8 1 0 0 7 2 9 3 6 0 6 5 9 8 7 6 4 8 6 1 1 7 9 1 0 4 5 3 3 4 8 8 5 0 3 4 6 1 1 3 6 5 7 6 8 6 7 5 3 2 4 9 4 4 1 6 6 8 0 3 9 6 2 6 5 7 9 7 8 7 7 1 8 5 5 6 0 8 4 5 5 2 9 6 5 4 1 2 6 6 5 4 0 8 5 3 0 6 1 4 3 4 4 4 3 1 8 5 8 6 7 6 9 7 5 1 4 5 6 6 1 4 0 6 8 0 0 7 0 0 2 3 7 8 7 7 6 5 9 1 3 4 4 0 1 7 1 2 7 4 9 4 7 0 4 2 0 5 6 2 2 3 0 5 3 8 9 9 4 5 6 1 3 1 4 0 7 1 1 2 7 0 0 0 4 0 7 8 5 4 7 3 3 2 6 9 9 3 9 0 8 1 4 5 4 6 6 4 6 4 5 8 8 0 7 9 7 2 7 0 8 2 6 6 8 3 0 6 3 4 3 2 8 5 8 7 8 5 6 9 8 3 0 5 2 3 5 8 0 8 9 3 3 0 6 5 7 5 7 4 0 6 7 9 5 4 5 7 1 6 3 7 7 5 2 5 4 2 0 2 1 1 4 9 5 5 7 6 1 5 8 1 4 0 0 2 5 0 1 2 6 2 2 8 5 9 4 1 3 0 2 1 6 4 7 1 5 5 0 9 7 9 2 5 9 2 3 0 9 9 0 7 9 6 5 4 7 3 7 6 1 2 5 5 1 7 6 5 6 7 5 1 3 5 7 5 1 7 8 2 9 6 6 6 4 5 4 7 7 9 1 7 4 5 0 1 1 2 9 9 6 1 4 8 9 0 3 0 4 6 3 9 9 4 7 1 3 2 9 6 2 1 0 7 3 4 0 4 3 7 5 1 8 9 5 7 3 5 9 6 1 4 5 8 9 0 1 9 3 8 9 7 1 3 1 1 1 7 9 0 4 2 9 7 8 2 8 5 6 4 7 5 0 3 2 0 3 1 9 8 6 9 1 5 1 4 0 2 8 7 0 8 0 8 5 9 9 0 4 8 0 1 0 9 4 1 2 1 4 7 2 2 1 3 1 7 9 4 7 6 4 7 7 7 2 6 2 2 4 1 4 2 5 4 8 5 4 5 4 0 3 3 2 1 5 7 1 8 5 3 0 6 1 4 2 2 8 8 1 3 7 5 8 5 0 4 3 0 6 3 3 2 1 7 5 1 8 2 9 7 9 8 6 6 2 2 3 7 1 7 2 1 5 9 1 6 0 7 7 1 6 6 9 2 5 4 7 4 8 7 3 8 9 8 6 6 5 4 9 4 9 4 5 0 1 1 4 6 5 4 0 6 2 8 4 3 3 6 6 3 9 3 7 9 0 0 3 9 7 6 9 2 6 5 6 7 2 1 4 6 3 8 5 3 0 6 7 3 6 0 9 6 5 7 1 2 0 9 1 8 0 7 6 3 8 3 2 7 1 6 6 4 1 6 2 7 4 8 8 8 8 0 0 7 8 6 9 2 5 6 0 2 9 0 2 2 8 4 7 2 1 0 4 0 3 1 7 2 1 1 8 6 0 8 2 0 4 1 9 0 0 0 4 2 2 9 6 6 1 7 1 1 9 6 3 7 7 9 2 1 3 3 7 5 7 5 1 1 4 9 5 9 5 0 1 5 6 6 0 4 9 6 3 1 8 6 2 9 4 7 2 6 5 4 7 3 6 4 2 5 2 3 0 8 1 7 7 0 3 6 7 5 1 5 9 0 6 7 3 5 0 2 3 5 0 7 2 8 3 5 4 0 5 6 7 0 4 0 3 8 6 7 4 3 5 1 3 6 2 2 2 2 4 7 7 1 5 8 9 1 5 0 4 9 5 3 0 9 8 4 4 4 8 9 3 3 3 0 9 6 3 4 0 8 7 8 0 7 6 9 3 2 5 9 9 3 9 7 8 0 5 4 1 9 3 4 1 4 4 7 3 7 7 4 4 1 8 4 2 6 3 1 2 9 8 6 0 8 0 9 9 8 8 8 6 8 7 4 1 3 2 6 0 4 7 2 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/Mavro.txt100644 1750 1750 4035 11532241244 27202 0ustarlucluc 0 0 File Name: Mavro.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 110 (= 50) Dataset Name: Mavro (Filter Transmittance Data) Description: This is an observed/"real world" data set consisting of 50 transmittance measurements (at a sampling rate of 10 observations per second) from a filter with a nominal value of 2. The experimenter was Radu Mavrodineaunu, a member of the chemistry staff at NIST. We here use this data to test accuracy in summary statistics calculations. Stat Category: Univariate: Summary Statistics Reference: None Data: "Real World" 1 Response : y = transmittance 0 Predictors 50 Observations Model: Lower Level of Difficulty 2 Parameters : mu, sigma 1 Response Variable : y 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 2.00185600000000 Sample Standard Deviation (denom. = n-1) s: 0.000429123454003053 Sample Autocorrelation Coefficient (lag 1) r(1): 0.937989183438248 Number of Observations: 50 Data: Y ------------- 2.00180 2.00170 2.00180 2.00190 2.00180 2.00170 2.00150 2.00140 2.00150 2.00150 2.00170 2.00180 2.00180 2.00190 2.00190 2.00210 2.00200 2.00160 2.00140 2.00130 2.00130 2.00150 2.00150 2.00160 2.00150 2.00140 2.00130 2.00140 2.00150 2.00140 2.00150 2.00160 2.00150 2.00160 2.00190 2.00200 2.00200 2.00210 2.00220 2.00230 2.00240 2.00250 2.00270 2.00260 2.00260 2.00260 2.00270 2.00260 2.00250 2.00240 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/Lottery.txt100644 1750 1750 6777 11532241244 27577 0ustarlucluc 0 0 ##################################################################### # Dataset Name: Lottery # #Description: This is an observed/"real world" data set # consisting of 218 lottery values # from September 3, 1989 to April 14, 1990 (32 weeks). # One 3-digit random number (from 000 to 999) # is drawn per day, 7 days per week for most # weeks, but fewer days per week for some weeks. # We here use this data to test accuracy # in summary statistics calculations. # # Stat Category: Univariate: Summary Statistics # # Reference: http://www.itl.nist.gov/div898/strd/univ/lottery.html # # Data: "Real World" # 1 Response : y = 3-digit random number # 0 Predictors # 218 Observations # # Model: Lower Level of Difficulty # 2 Parameters : mu, sigma # 1 Response Variable : y # 0 Predictor Variables# # y = mu + e ##################################################################### ##################################################################### # # Certified Values # ##################################################################### mean = 518.958715596330 standardDeviation = 291.699727470969 autocorrelationCoefficient = -0.120948622967393 n = 218 ##################################################################### # # Data # ##################################################################### 162 671 933 414 788 730 817 33 536 875 670 236 473 167 877 980 316 950 456 92 517 557 956 954 104 178 794 278 147 773 437 435 502 610 582 780 689 562 964 791 28 97 848 281 858 538 660 972 671 613 867 448 738 966 139 636 847 659 754 243 122 455 195 968 793 59 730 361 574 522 97 762 431 158 429 414 22 629 788 999 187 215 810 782 47 34 108 986 25 644 829 630 315 567 919 331 207 412 242 607 668 944 749 168 864 442 533 805 372 63 458 777 416 340 436 140 919 350 510 572 905 900 85 389 473 758 444 169 625 692 140 897 672 288 312 860 724 226 884 508 976 741 476 417 831 15 318 432 241 114 799 955 833 358 935 146 630 830 440 642 356 373 271 715 367 393 190 669 8 861 108 795 269 590 326 866 64 523 862 840 219 382 998 4 628 305 747 247 34 747 729 645 856 974 24 568 24 694 608 480 410 729 947 293 53 930 223 203 677 227 62 455 387 318 562 242 428 968 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/NumAcc1.txt100644 1750 1750 3334 11532241244 27346 0ustarlucluc 0 0 File Name: NumAcc1.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 63 (= 3) Dataset Name: NumAcc1 Description: This is a constructed/fabricated data set to test accuracy in summary statistic calculations. The numbers are large (8-digit integers) and differ only in the last decimal place. Note--by construction, this data set has sample mean = 10000002 (exact) sample standard deviation = 1 (exact) sample autocorrelation coef. = -0.5 (exact) Stat Category: Univariate: Summary Statistics Reference: Simon, Stephen D. and Lesage, James P. (1989). Assessing the Accuracy of ANOVA Caluclations in Statistical Software", Computational Statistics & data Analysis, 8, pp. 325-332. Data: Constructed 1 Response : y 0 Predictors 3 Observations Model: Lower Level of Difficulty 2 Parameters : mu, sigma 1 Response Variable : y 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 10000002 Sample Standard Deviation (denom. = n-1) s: 1 Sample Autocorrelation Coefficient (lag 1) r(1): -0.5 Number of Observations: 3 Data: Y --------- 10000001 10000003 10000002 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/Michelso.txt100644 1750 1750 4215 11532241244 27661 0ustarlucluc 0 0 File Name: Michelso.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 160 (= 100) Dataset Name: Michelso (Speed of Light Data, in millions of meters per second) Description: This is an observed/"real world" data set consisting of 100 measurements of the speed of light in air. This classic experiment was carried out by Michelson is 1879. We here use this data to test accuracy in summary statistics calculations. Stat Category: Univariate: Summary Statistics Reference: Dorsey, Ernest N. (1944). The Velocity of Light. Transactions of the American Philiosophical Society, Volume 34, Part 1, Pages 1-110, Table 22. y = mu + e Certified Values Sample Mean ybar: 299.852400000000 Sample Standard Deviation (denom. = n-1) s: 0.0790105478190518 Sample Autocorrelation Coefficient (lag 1) r(1): 0.535199668621283 Number of Observations: 100 Data: Y ---------- 299.85 299.74 299.90 300.07 299.93 299.85 299.95 299.98 299.98 299.88 300.00 299.98 299.93 299.65 299.76 299.81 300.00 300.00 299.96 299.96 299.96 299.94 299.96 299.94 299.88 299.80 299.85 299.88 299.90 299.84 299.83 299.79 299.81 299.88 299.88 299.83 299.80 299.79 299.76 299.80 299.88 299.88 299.88 299.86 299.72 299.72 299.62 299.86 299.97 299.95 299.88 299.91 299.85 299.87 299.84 299.84 299.85 299.84 299.84 299.84 299.89 299.81 299.81 299.82 299.80 299.77 299.76 299.74 299.75 299.76 299.91 299.92 299.89 299.86 299.88 299.72 299.84 299.85 299.85 299.78 299.89 299.84 299.78 299.81 299.76 299.81 299.79 299.81 299.82 299.85 299.87 299.87 299.81 299.74 299.81 299.94 299.95 299.80 299.81 299.87 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/NumAcc4.txt100644 1750 1750 34533 11532241244 27376 0ustarlucluc 0 0 File Name: NumAcc4.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 1061 (= 1001) Dataset Name: NumAcc4 Description: This is a constructed/fabricated data set to test accuracy in summary statistic calculations. The numbers are 9-digit floating point values and differ only in the last decimal place. sample mean = 10000000.2 (exact) sample standard dev. = 0.1 (exact) sample autocorr. coef. = -0.999 (exact) Stat Category: Univariate Reference: Simon, Stephen D. and Lesage, James P. (1989). Assessing the Accuracy of ANOVA Caluclations in Statistical Software", Computational Statistics & data Analysis, 8, pp. 325-332. Data: Constructed 1 Response : y 0 Predictors 1001 Observations Model: Higher Level of Difficulty 2 Parameters : mu, sigma 1 Response Variable : y 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 10000000.2 Sample Standard Deviation (denom. = n-1) s: 0.1 Sample Autocorrelation Coefficient (lag 1) r(1): -0.999 Number of Observations: 1001 Data: Y -------------- 10000000.2 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 10000000.1 10000000.3 commons-math-2.2-src/src/test/resources/org/apache/commons/math/stat/data/NumAcc2.txt100644 1750 1750 24727 11532241244 27400 0ustarlucluc 0 0 File Name: NumAcc2.dat File Format: ASCII Header : lines 1 to 60 (= 60) Certified Values: lines 41 to 43 (= 3) Data : lines 61 to 1061 (= 1001) Dataset Name: NumAcc2 Description: This is a constructed/fabricated data set to test accuracy in summary statistic calculations. The numbers are 2-digit floating point values and differ only in the last decimal place. Note--by construction, this data set has sample mean = 1.2 (exact) sample standard deviation = 0.1 (exact) sample autocorrelation coef. = -0.999 (exact) Stat Category: Univariate Reference: Simon, Stephen D. and Lesage, James P. (1989). Assessing the Accuracy of ANOVA Caluclations in Statistical Software", Computational Statistics & data Analysis, 8, pp. 325-332. Data: Constructed 1 Response : y 0 Predictors 1001 Observations Model: Average Level of Difficulty 2 Parameters : mu, sigma 1 Response Variable : y 0 Predictor Variables y = mu + e Certified Values Sample Mean ybar: 1.2 Sample Standard Deviation (denom. = n-1) s: 0.1 Sample Autocorrelation Coefficient (lag 1) r(1): -0.999 Number of Observations: 1001 Data: Y --------- 1.2 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 1.1 1.3 commons-math-2.2-src/src/test/java/org/apache/commons/math/MathExceptionTest.java100644 1750 1750 13243 11532241244 26674 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import junit.framework.TestCase; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.util.Locale; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * @version $Revision: 1035475 $ $Date: 2010-11-15 23:39:25 +0100 (lun. 15 nov. 2010) $ */ public class MathExceptionTest extends TestCase { public void testConstructor(){ MathException ex = new MathException(); assertNull(ex.getCause()); assertEquals("", ex.getMessage()); assertEquals("", ex.getMessage(Locale.FRENCH)); } public void testConstructorPatternArguments(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; MathException ex = new MathException(pattern, arguments); assertNull(ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorCause(){ String inMsg = "inner message"; Exception cause = new Exception(inMsg); MathException ex = new MathException(cause); assertEquals(cause, ex.getCause()); } public void testConstructorPatternArgumentsCause(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; String inMsg = "inner message"; Exception cause = new Exception(inMsg); MathException ex = new MathException(cause, pattern, arguments); assertEquals(cause, ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } /** * Tests the printStackTrace() operation. */ public void testPrintStackTrace() { Localizable outMsg = new DummyLocalizable("outer message"); Localizable inMsg = new DummyLocalizable("inner message"); MathException cause = new MathConfigurationException(inMsg); MathException ex = new MathException(cause, outMsg); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); ex.printStackTrace(ps); String stack = baos.toString(); String outerMsg = "org.apache.commons.math.MathException: outer message"; String innerMsg = "Caused by: " + "org.apache.commons.math.MathConfigurationException: inner message"; assertTrue(stack.startsWith(outerMsg)); assertTrue(stack.indexOf(innerMsg) > 0); PrintWriter pw = new PrintWriter(ps, true); ex.printStackTrace(pw); stack = baos.toString(); assertTrue(stack.startsWith(outerMsg)); assertTrue(stack.indexOf(innerMsg) > 0); } /** * Test serialization */ public void testSerialization() { Localizable outMsg = new DummyLocalizable("outer message"); Localizable inMsg = new DummyLocalizable("inner message"); MathException cause = new MathConfigurationException(inMsg); MathException ex = new MathException(cause, outMsg); MathException image = (MathException) TestUtils.serializeAndRecover(ex); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); ex.printStackTrace(ps); String stack = baos.toString(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); PrintStream ps2 = new PrintStream(baos2); image.printStackTrace(ps2); String stack2 = baos2.toString(); // See if JDK supports nested exceptions. If not, stack trace of // inner exception will not be serialized boolean jdkSupportsNesting = false; try { Throwable.class.getDeclaredMethod("getCause", new Class[0]); jdkSupportsNesting = true; } catch (NoSuchMethodException e) { jdkSupportsNesting = false; } if (jdkSupportsNesting) { assertEquals(stack, stack2); } else { assertTrue(stack2.indexOf(inMsg.getSourceString()) != -1); assertTrue(stack2.indexOf("MathConfigurationException") != -1); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/WeightedMeasurementTest.java100644 1750 1750 7020 11532241243 32221 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import org.apache.commons.math.estimation.EstimatedParameter; import org.apache.commons.math.estimation.WeightedMeasurement; import org.apache.commons.math.util.FastMath; import junit.framework.*; @Deprecated public class WeightedMeasurementTest extends TestCase { public WeightedMeasurementTest(String name) { super(name); p1 = null; p2 = null; } public void testConstruction() { WeightedMeasurement m = new MyMeasurement(3.0, theoretical() + 0.1, this); checkValue(m.getWeight(), 3.0); checkValue(m.getMeasuredValue(), theoretical() + 0.1); } public void testIgnored() { WeightedMeasurement m = new MyMeasurement(3.0, theoretical() + 0.1, this); assertTrue(!m.isIgnored()); m.setIgnored(true); assertTrue(m.isIgnored()); m.setIgnored(false); assertTrue(!m.isIgnored()); } public void testTheory() { WeightedMeasurement m = new MyMeasurement(3.0, theoretical() + 0.1, this); checkValue(m.getTheoreticalValue(), theoretical()); checkValue(m.getResidual(), 0.1); double oldP1 = p1.getEstimate(); p1.setEstimate(oldP1 + m.getResidual() / m.getPartial(p1)); checkValue(m.getResidual(), 0.0); p1.setEstimate(oldP1); checkValue(m.getResidual(), 0.1); double oldP2 = p2.getEstimate(); p2.setEstimate(oldP2 + m.getResidual() / m.getPartial(p2)); checkValue(m.getResidual(), 0.0); p2.setEstimate(oldP2); checkValue(m.getResidual(), 0.1); } @Override public void setUp() { p1 = new EstimatedParameter("p1", 1.0); p2 = new EstimatedParameter("p2", 2.0); } @Override public void tearDown() { p1 = null; p2 = null; } private void checkValue(double value, double expected) { assertTrue(FastMath.abs(value - expected) < 1.0e-10); } private double theoretical() { return 3 * p1.getEstimate() - p2.getEstimate(); } private double partial(EstimatedParameter p) { if (p == p1) { return 3.0; } else if (p == p2) { return -1.0; } else { return 0.0; } } private static class MyMeasurement extends WeightedMeasurement { public MyMeasurement(double weight, double measuredValue, WeightedMeasurementTest testInstance) { super(weight, measuredValue); this.testInstance = testInstance; } @Override public double getTheoreticalValue() { return testInstance.theoretical(); } @Override public double getPartial(EstimatedParameter p) { return testInstance.partial(p); } private transient WeightedMeasurementTest testInstance; private static final long serialVersionUID = -246712922500792332L; } private EstimatedParameter p1; private EstimatedParameter p2; } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimatorTes100644 1750 1750 101346 11532241243 32677 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.util.ArrayList; import java.util.HashSet; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** *

Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

* * * *
* Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
    *
  1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
  2. *
  3. 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.
  4. *
  5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
  6. *
  7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
  8. *
  9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
  10. *
    * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ @Deprecated public class LevenbergMarquardtEstimatorTest extends TestCase { public LevenbergMarquardtEstimatorTest(String name) { super(name); } public void testTrivial() throws EstimationException { LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { new EstimatedParameter("p0", 0) }, 3.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); try { estimator.guessParametersErrors(problem); fail("an exception should have been thrown"); } catch (EstimationException ee) { // expected behavior } assertEquals(1.5, problem.getUnboundParameters()[0].getEstimate(), 1.0e-10); } public void testQRColumnsPermutation() throws EstimationException { EstimatedParameter[] x = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { x[0], x[1] }, 4.0), new LinearMeasurement(new double[] { 2.0 }, new EstimatedParameter[] { x[1] }, 6.0), new LinearMeasurement(new double[] { 1.0, -2.0 }, new EstimatedParameter[] { x[0], x[1] }, 1.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(7.0, x[0].getEstimate(), 1.0e-10); assertEquals(3.0, x[1].getEstimate(), 1.0e-10); } public void testNoDependency() throws EstimationException { EstimatedParameter[] p = new EstimatedParameter[] { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0), new EstimatedParameter("p3", 0), new EstimatedParameter("p4", 0), new EstimatedParameter("p5", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[0] }, 0.0), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[1] }, 1.1), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[2] }, 2.2), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[3] }, 3.3), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[4] }, 4.4), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[5] }, 5.5) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); for (int i = 0; i < p.length; ++i) { assertEquals(0.55 * i, p[i].getEstimate(), 1.0e-10); } } public void testOneSet() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0 }, new EstimatedParameter[] { p[0] }, 1.0), new LinearMeasurement(new double[] { -1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { -1.0, 1.0 }, new EstimatedParameter[] { p[1], p[2] }, 1.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(1.0, p[0].getEstimate(), 1.0e-10); assertEquals(2.0, p[1].getEstimate(), 1.0e-10); assertEquals(3.0, p[2].getEstimate(), 1.0e-10); } public void testTwoSets() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 1), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 3), new EstimatedParameter("p4", 4), new EstimatedParameter("p5", 5) }; double epsilon = 1.0e-7; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { // 4 elements sub-problem new LinearMeasurement(new double[] { 2.0, 1.0, 4.0 }, new EstimatedParameter[] { p[0], p[1], p[3] }, 2.0), new LinearMeasurement(new double[] { -4.0, -2.0, 3.0, -7.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, -9.0), new LinearMeasurement(new double[] { 4.0, 1.0, -2.0, 8.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 2.0), new LinearMeasurement(new double[] { -3.0, -12.0, -1.0 }, new EstimatedParameter[] { p[1], p[2], p[3] }, 2.0), // 2 elements sub-problem new LinearMeasurement(new double[] { epsilon, 1.0 }, new EstimatedParameter[] { p[4], p[5] }, 1.0 + epsilon * epsilon), new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[4], p[5] }, 2.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals( 3.0, p[0].getEstimate(), 1.0e-10); assertEquals( 4.0, p[1].getEstimate(), 1.0e-10); assertEquals(-1.0, p[2].getEstimate(), 1.0e-10); assertEquals(-2.0, p[3].getEstimate(), 1.0e-10); assertEquals( 1.0 + epsilon, p[4].getEstimate(), 1.0e-10); assertEquals( 1.0 - epsilon, p[5].getEstimate(), 1.0e-10); } public void testNonInversible() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0) }; LinearMeasurement[] m = new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 2.0, -3.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 1.0), new LinearMeasurement(new double[] { 2.0, 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 1.0), new LinearMeasurement(new double[] { -3.0, -9.0 }, new EstimatedParameter[] { p[0], p[2] }, 1.0) }; LinearProblem problem = new LinearProblem(m); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); double initialCost = estimator.getRMS(problem); estimator.estimate(problem); assertTrue(estimator.getRMS(problem) < initialCost); assertTrue(FastMath.sqrt(m.length) * estimator.getRMS(problem) > 0.6); try { estimator.getCovariances(problem); fail("an exception should have been thrown"); } catch (EstimationException ee) { // expected behavior } double dJ0 = 2 * (m[0].getResidual() * m[0].getPartial(p[0]) + m[1].getResidual() * m[1].getPartial(p[0]) + m[2].getResidual() * m[2].getPartial(p[0])); double dJ1 = 2 * (m[0].getResidual() * m[0].getPartial(p[1]) + m[1].getResidual() * m[1].getPartial(p[1])); double dJ2 = 2 * (m[0].getResidual() * m[0].getPartial(p[2]) + m[1].getResidual() * m[1].getPartial(p[2]) + m[2].getResidual() * m[2].getPartial(p[2])); assertEquals(0, dJ0, 1.0e-10); assertEquals(0, dJ1, 1.0e-10); assertEquals(0, dJ2, 1.0e-10); } public void testIllConditioned() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 1), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 3) }; LinearProblem problem1 = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 10.0, 7.0, 8.0, 7.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 32.0), new LinearMeasurement(new double[] { 7.0, 5.0, 6.0, 5.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 23.0), new LinearMeasurement(new double[] { 8.0, 6.0, 10.0, 9.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 33.0), new LinearMeasurement(new double[] { 7.0, 5.0, 9.0, 10.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 31.0) }); LevenbergMarquardtEstimator estimator1 = new LevenbergMarquardtEstimator(); estimator1.estimate(problem1); assertEquals(0, estimator1.getRMS(problem1), 1.0e-10); assertEquals(1.0, p[0].getEstimate(), 1.0e-10); assertEquals(1.0, p[1].getEstimate(), 1.0e-10); assertEquals(1.0, p[2].getEstimate(), 1.0e-10); assertEquals(1.0, p[3].getEstimate(), 1.0e-10); LinearProblem problem2 = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 10.0, 7.0, 8.1, 7.2 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 32.0), new LinearMeasurement(new double[] { 7.08, 5.04, 6.0, 5.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 23.0), new LinearMeasurement(new double[] { 8.0, 5.98, 9.89, 9.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 33.0), new LinearMeasurement(new double[] { 6.99, 4.99, 9.0, 9.98 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 31.0) }); LevenbergMarquardtEstimator estimator2 = new LevenbergMarquardtEstimator(); estimator2.estimate(problem2); assertEquals(0, estimator2.getRMS(problem2), 1.0e-10); assertEquals(-81.0, p[0].getEstimate(), 1.0e-8); assertEquals(137.0, p[1].getEstimate(), 1.0e-8); assertEquals(-34.0, p[2].getEstimate(), 1.0e-8); assertEquals( 22.0, p[3].getEstimate(), 1.0e-8); } public void testMoreEstimatedParametersSimple() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 7), new EstimatedParameter("p1", 6), new EstimatedParameter("p2", 5), new EstimatedParameter("p3", 4) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 3.0, 2.0 }, new EstimatedParameter[] { p[0], p[1] }, 7.0), new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 }, new EstimatedParameter[] { p[1], p[2], p[3] }, 3.0), new LinearMeasurement(new double[] { 2.0, 1.0 }, new EstimatedParameter[] { p[0], p[2] }, 5.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); } public void testMoreEstimatedParametersUnsorted() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 2), new EstimatedParameter("p1", 2), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 2), new EstimatedParameter("p4", 2), new EstimatedParameter("p5", 2) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, 1.0, 1.0 }, new EstimatedParameter[] { p[2], p[3], p[4] }, 12.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[4], p[5] }, -1.0), new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 }, new EstimatedParameter[] { p[3], p[2], p[5] }, 7.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[4], p[3] }, 1.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(3.0, p[2].getEstimate(), 1.0e-10); assertEquals(4.0, p[3].getEstimate(), 1.0e-10); assertEquals(5.0, p[4].getEstimate(), 1.0e-10); assertEquals(6.0, p[5].getEstimate(), 1.0e-10); } public void testRedundantEquations() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 1), new EstimatedParameter("p1", 1) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1] }, 5.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(2.0, p[0].getEstimate(), 1.0e-10); assertEquals(1.0, p[1].getEstimate(), 1.0e-10); } public void testInconsistentEquations() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 1), new EstimatedParameter("p1", 1) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1] }, 4.0) }); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(problem); assertTrue(estimator.getRMS(problem) > 0.1); } public void testControlParameters() { Circle circle = new Circle(98.680, 47.345); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); checkEstimate(circle, 0.1, 10, 1.0e-14, 1.0e-16, 1.0e-10, false); checkEstimate(circle, 0.1, 10, 1.0e-15, 1.0e-17, 1.0e-10, true); checkEstimate(circle, 0.1, 5, 1.0e-15, 1.0e-16, 1.0e-10, true); circle.addPoint(300, -300); checkEstimate(circle, 0.1, 20, 1.0e-18, 1.0e-16, 1.0e-10, true); } private void checkEstimate(EstimationProblem problem, double initialStepBoundFactor, int maxCostEval, double costRelativeTolerance, double parRelativeTolerance, double orthoTolerance, boolean shouldFail) { try { LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.setInitialStepBoundFactor(initialStepBoundFactor); estimator.setMaxCostEval(maxCostEval); estimator.setCostRelativeTolerance(costRelativeTolerance); estimator.setParRelativeTolerance(parRelativeTolerance); estimator.setOrthoTolerance(orthoTolerance); estimator.estimate(problem); assertTrue(! shouldFail); } catch (EstimationException ee) { assertTrue(shouldFail); } } public void testCircleFitting() throws EstimationException { Circle circle = new Circle(98.680, 47.345); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(circle); assertTrue(estimator.getCostEvaluations() < 10); assertTrue(estimator.getJacobianEvaluations() < 10); double rms = estimator.getRMS(circle); assertEquals(1.768262623567235, FastMath.sqrt(circle.getM()) * rms, 1.0e-10); assertEquals(69.96016176931406, circle.getRadius(), 1.0e-10); assertEquals(96.07590211815305, circle.getX(), 1.0e-10); assertEquals(48.13516790438953, circle.getY(), 1.0e-10); double[][] cov = estimator.getCovariances(circle); assertEquals(1.839, cov[0][0], 0.001); assertEquals(0.731, cov[0][1], 0.001); assertEquals(cov[0][1], cov[1][0], 1.0e-14); assertEquals(0.786, cov[1][1], 0.001); double[] errors = estimator.guessParametersErrors(circle); assertEquals(1.384, errors[0], 0.001); assertEquals(0.905, errors[1], 0.001); // add perfect measurements and check errors are reduced double cx = circle.getX(); double cy = circle.getY(); double r = circle.getRadius(); for (double d= 0; d < 2 * FastMath.PI; d += 0.01) { circle.addPoint(cx + r * FastMath.cos(d), cy + r * FastMath.sin(d)); } estimator = new LevenbergMarquardtEstimator(); estimator.estimate(circle); cov = estimator.getCovariances(circle); assertEquals(0.004, cov[0][0], 0.001); assertEquals(6.40e-7, cov[0][1], 1.0e-9); assertEquals(cov[0][1], cov[1][0], 1.0e-14); assertEquals(0.003, cov[1][1], 0.001); errors = estimator.guessParametersErrors(circle); assertEquals(0.004, errors[0], 0.001); assertEquals(0.004, errors[1], 0.001); } public void testCircleFittingBadInit() throws EstimationException { Circle circle = new Circle(-12, -12); double[][] points = new double[][] { {-0.312967, 0.072366}, {-0.339248, 0.132965}, {-0.379780, 0.202724}, {-0.390426, 0.260487}, {-0.361212, 0.328325}, {-0.346039, 0.392619}, {-0.280579, 0.444306}, {-0.216035, 0.470009}, {-0.149127, 0.493832}, {-0.075133, 0.483271}, {-0.007759, 0.452680}, { 0.060071, 0.410235}, { 0.103037, 0.341076}, { 0.118438, 0.273884}, { 0.131293, 0.192201}, { 0.115869, 0.129797}, { 0.072223, 0.058396}, { 0.022884, 0.000718}, {-0.053355, -0.020405}, {-0.123584, -0.032451}, {-0.216248, -0.032862}, {-0.278592, -0.005008}, {-0.337655, 0.056658}, {-0.385899, 0.112526}, {-0.405517, 0.186957}, {-0.415374, 0.262071}, {-0.387482, 0.343398}, {-0.347322, 0.397943}, {-0.287623, 0.458425}, {-0.223502, 0.475513}, {-0.135352, 0.478186}, {-0.061221, 0.483371}, { 0.003711, 0.422737}, { 0.065054, 0.375830}, { 0.108108, 0.297099}, { 0.123882, 0.222850}, { 0.117729, 0.134382}, { 0.085195, 0.056820}, { 0.029800, -0.019138}, {-0.027520, -0.072374}, {-0.102268, -0.091555}, {-0.200299, -0.106578}, {-0.292731, -0.091473}, {-0.356288, -0.051108}, {-0.420561, 0.014926}, {-0.471036, 0.074716}, {-0.488638, 0.182508}, {-0.485990, 0.254068}, {-0.463943, 0.338438}, {-0.406453, 0.404704}, {-0.334287, 0.466119}, {-0.254244, 0.503188}, {-0.161548, 0.495769}, {-0.075733, 0.495560}, { 0.001375, 0.434937}, { 0.082787, 0.385806}, { 0.115490, 0.323807}, { 0.141089, 0.223450}, { 0.138693, 0.131703}, { 0.126415, 0.049174}, { 0.066518, -0.010217}, {-0.005184, -0.070647}, {-0.080985, -0.103635}, {-0.177377, -0.116887}, {-0.260628, -0.100258}, {-0.335756, -0.056251}, {-0.405195, -0.000895}, {-0.444937, 0.085456}, {-0.484357, 0.175597}, {-0.472453, 0.248681}, {-0.438580, 0.347463}, {-0.402304, 0.422428}, {-0.326777, 0.479438}, {-0.247797, 0.505581}, {-0.152676, 0.519380}, {-0.071754, 0.516264}, { 0.015942, 0.472802}, { 0.076608, 0.419077}, { 0.127673, 0.330264}, { 0.159951, 0.262150}, { 0.153530, 0.172681}, { 0.140653, 0.089229}, { 0.078666, 0.024981}, { 0.023807, -0.037022}, {-0.048837, -0.077056}, {-0.127729, -0.075338}, {-0.221271, -0.067526} }; for (int i = 0; i < points.length; ++i) { circle.addPoint(points[i][0], points[i][1]); } LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.estimate(circle); assertTrue(estimator.getCostEvaluations() < 15); assertTrue(estimator.getJacobianEvaluations() < 10); assertEquals( 0.030184491196225207, estimator.getRMS(circle), 1.0e-9); assertEquals( 0.2922350065939634, circle.getRadius(), 1.0e-9); assertEquals(-0.15173845023862165, circle.getX(), 1.0e-8); assertEquals( 0.20750021499570379, circle.getY(), 1.0e-8); } public void testMath199() { try { QuadraticProblem problem = new QuadraticProblem(); problem.addPoint (0, -3.182591015485607, 0.0); problem.addPoint (1, -2.5581184967730577, 4.4E-323); problem.addPoint (2, -2.1488478161387325, 1.0); problem.addPoint (3, -1.9122489313410047, 4.4E-323); problem.addPoint (4, 1.7785661310051026, 0.0); new LevenbergMarquardtEstimator().estimate(problem); fail("an exception should have been thrown"); } catch (EstimationException ee) { // expected behavior } } private static class LinearProblem implements EstimationProblem { public LinearProblem(LinearMeasurement[] measurements) { this.measurements = measurements; } public WeightedMeasurement[] getMeasurements() { return measurements; } public EstimatedParameter[] getUnboundParameters() { return getAllParameters(); } public EstimatedParameter[] getAllParameters() { HashSet set = new HashSet(); for (int i = 0; i < measurements.length; ++i) { EstimatedParameter[] parameters = measurements[i].getParameters(); for (int j = 0; j < parameters.length; ++j) { set.add(parameters[j]); } } return set.toArray(new EstimatedParameter[set.size()]); } private LinearMeasurement[] measurements; } private static class LinearMeasurement extends WeightedMeasurement { public LinearMeasurement(double[] factors, EstimatedParameter[] parameters, double setPoint) { super(1.0, setPoint); this.factors = factors; this.parameters = parameters; } @Override public double getTheoreticalValue() { double v = 0; for (int i = 0; i < factors.length; ++i) { v += factors[i] * parameters[i].getEstimate(); } return v; } @Override public double getPartial(EstimatedParameter parameter) { for (int i = 0; i < parameters.length; ++i) { if (parameters[i] == parameter) { return factors[i]; } } return 0; } public EstimatedParameter[] getParameters() { return parameters; } private double[] factors; private EstimatedParameter[] parameters; private static final long serialVersionUID = -3922448707008868580L; } private static class Circle implements EstimationProblem { public Circle(double cx, double cy) { this.cx = new EstimatedParameter("cx", cx); this.cy = new EstimatedParameter("cy", cy); points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new PointModel(this, px, py)); } public int getM() { return points.size(); } public WeightedMeasurement[] getMeasurements() { return points.toArray(new PointModel[points.size()]); } public EstimatedParameter[] getAllParameters() { return new EstimatedParameter[] { cx, cy }; } public EstimatedParameter[] getUnboundParameters() { return new EstimatedParameter[] { cx, cy }; } public double getPartialRadiusX() { double dRdX = 0; for (PointModel point : points) { dRdX += point.getPartialDiX(); } return dRdX / points.size(); } public double getPartialRadiusY() { double dRdY = 0; for (PointModel point : points) { dRdY += point.getPartialDiY(); } return dRdY / points.size(); } public double getRadius() { double r = 0; for (PointModel point : points) { r += point.getCenterDistance(); } return r / points.size(); } public double getX() { return cx.getEstimate(); } public double getY() { return cy.getEstimate(); } private static class PointModel extends WeightedMeasurement { public PointModel(Circle circle, double px, double py) { super(1.0, 0.0); this.px = px; this.py = py; this.circle = circle; } @Override public double getPartial(EstimatedParameter parameter) { if (parameter == circle.cx) { return getPartialDiX() - circle.getPartialRadiusX(); } else if (parameter == circle.cy) { return getPartialDiY() - circle.getPartialRadiusY(); } return 0; } public double getCenterDistance() { double dx = px - circle.cx.getEstimate(); double dy = py - circle.cy.getEstimate(); return FastMath.sqrt(dx * dx + dy * dy); } public double getPartialDiX() { return (circle.cx.getEstimate() - px) / getCenterDistance(); } public double getPartialDiY() { return (circle.cy.getEstimate() - py) / getCenterDistance(); } @Override public double getTheoreticalValue() { return getCenterDistance() - circle.getRadius(); } private double px; private double py; private transient final Circle circle; private static final long serialVersionUID = 1L; } private EstimatedParameter cx; private EstimatedParameter cy; private ArrayList points; } private static class QuadraticProblem extends SimpleEstimationProblem { private EstimatedParameter a; private EstimatedParameter b; private EstimatedParameter c; public QuadraticProblem() { a = new EstimatedParameter("a", 0.0); b = new EstimatedParameter("b", 0.0); c = new EstimatedParameter("c", 0.0); addParameter(a); addParameter(b); addParameter(c); } public void addPoint(double x, double y, double w) { addMeasurement(new LocalMeasurement(this, x, y, w)); } public double theoreticalValue(double x) { return ( (a.getEstimate() * x + b.getEstimate() ) * x + c.getEstimate()); } private double partial(double x, EstimatedParameter parameter) { if (parameter == a) { return x * x; } else if (parameter == b) { return x; } else { return 1.0; } } private static class LocalMeasurement extends WeightedMeasurement { private static final long serialVersionUID = 1555043155023729130L; private final double x; private transient final QuadraticProblem pb; // constructor public LocalMeasurement(QuadraticProblem pb, double x, double y, double w) { super(w, y); this.x = x; this.pb = pb; } @Override public double getTheoreticalValue() { return pb.theoreticalValue(x); } @Override public double getPartial(EstimatedParameter parameter) { return pb.partial(x, parameter); } } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/GaussNewtonEstimatorTest.java100644 1750 1750 70766 11532241243 32461 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.util.ArrayList; import java.util.HashSet; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** *

    Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

    * * * *
    * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
    * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
      *
    1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
    2. *
    3. 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.
    4. *
    5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
    6. *
    7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
    8. *
    9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
    10. *
      * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ @Deprecated public class GaussNewtonEstimatorTest extends TestCase { public GaussNewtonEstimatorTest(String name) { super(name); } public void testTrivial() throws EstimationException { LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { new EstimatedParameter("p0", 0) }, 3.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(1.5, problem.getUnboundParameters()[0].getEstimate(), 1.0e-10); } public void testQRColumnsPermutation() throws EstimationException { EstimatedParameter[] x = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { x[0], x[1] }, 4.0), new LinearMeasurement(new double[] { 2.0 }, new EstimatedParameter[] { x[1] }, 6.0), new LinearMeasurement(new double[] { 1.0, -2.0 }, new EstimatedParameter[] { x[0], x[1] }, 1.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(7.0, x[0].getEstimate(), 1.0e-10); assertEquals(3.0, x[1].getEstimate(), 1.0e-10); } public void testNoDependency() throws EstimationException { EstimatedParameter[] p = new EstimatedParameter[] { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0), new EstimatedParameter("p3", 0), new EstimatedParameter("p4", 0), new EstimatedParameter("p5", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[0] }, 0.0), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[1] }, 1.1), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[2] }, 2.2), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[3] }, 3.3), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[4] }, 4.4), new LinearMeasurement(new double[] {2}, new EstimatedParameter[] { p[5] }, 5.5) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); for (int i = 0; i < p.length; ++i) { assertEquals(0.55 * i, p[i].getEstimate(), 1.0e-10); } } public void testOneSet() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0 }, new EstimatedParameter[] { p[0] }, 1.0), new LinearMeasurement(new double[] { -1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { -1.0, 1.0 }, new EstimatedParameter[] { p[1], p[2] }, 1.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals(1.0, p[0].getEstimate(), 1.0e-10); assertEquals(2.0, p[1].getEstimate(), 1.0e-10); assertEquals(3.0, p[2].getEstimate(), 1.0e-10); } public void testTwoSets() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 1), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 3), new EstimatedParameter("p4", 4), new EstimatedParameter("p5", 5) }; double epsilon = 1.0e-7; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { // 4 elements sub-problem new LinearMeasurement(new double[] { 2.0, 1.0, 4.0 }, new EstimatedParameter[] { p[0], p[1], p[3] }, 2.0), new LinearMeasurement(new double[] { -4.0, -2.0, 3.0, -7.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, -9.0), new LinearMeasurement(new double[] { 4.0, 1.0, -2.0, 8.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 2.0), new LinearMeasurement(new double[] { -3.0, -12.0, -1.0 }, new EstimatedParameter[] { p[1], p[2], p[3] }, 2.0), // 2 elements sub-problem new LinearMeasurement(new double[] { epsilon, 1.0 }, new EstimatedParameter[] { p[4], p[5] }, 1.0 + epsilon * epsilon), new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[4], p[5] }, 2.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); assertEquals( 3.0, p[0].getEstimate(), 1.0e-10); assertEquals( 4.0, p[1].getEstimate(), 1.0e-10); assertEquals(-1.0, p[2].getEstimate(), 1.0e-10); assertEquals(-2.0, p[3].getEstimate(), 1.0e-10); assertEquals( 1.0 + epsilon, p[4].getEstimate(), 1.0e-10); assertEquals( 1.0 - epsilon, p[5].getEstimate(), 1.0e-10); } public void testNonInversible() { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 0), new EstimatedParameter("p2", 0) }; LinearMeasurement[] m = new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 2.0, -3.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 1.0), new LinearMeasurement(new double[] { 2.0, 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 1.0), new LinearMeasurement(new double[] { -3.0, -9.0 }, new EstimatedParameter[] { p[0], p[2] }, 1.0) }; LinearProblem problem = new LinearProblem(m); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); try { estimator.estimate(problem); fail("an exception should have been caught"); } catch (EstimationException ee) { // expected behavior } } public void testIllConditioned() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 0), new EstimatedParameter("p1", 1), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 3) }; LinearProblem problem1 = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 10.0, 7.0, 8.0, 7.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 32.0), new LinearMeasurement(new double[] { 7.0, 5.0, 6.0, 5.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 23.0), new LinearMeasurement(new double[] { 8.0, 6.0, 10.0, 9.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 33.0), new LinearMeasurement(new double[] { 7.0, 5.0, 9.0, 10.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 31.0) }); GaussNewtonEstimator estimator1 = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator1.estimate(problem1); assertEquals(0, estimator1.getRMS(problem1), 1.0e-10); assertEquals(1.0, p[0].getEstimate(), 1.0e-10); assertEquals(1.0, p[1].getEstimate(), 1.0e-10); assertEquals(1.0, p[2].getEstimate(), 1.0e-10); assertEquals(1.0, p[3].getEstimate(), 1.0e-10); LinearProblem problem2 = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 10.0, 7.0, 8.1, 7.2 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 32.0), new LinearMeasurement(new double[] { 7.08, 5.04, 6.0, 5.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 23.0), new LinearMeasurement(new double[] { 8.0, 5.98, 9.89, 9.0 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 33.0), new LinearMeasurement(new double[] { 6.99, 4.99, 9.0, 9.98 }, new EstimatedParameter[] { p[0], p[1], p[2], p[3] }, 31.0) }); GaussNewtonEstimator estimator2 = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator2.estimate(problem2); assertEquals(0, estimator2.getRMS(problem2), 1.0e-10); assertEquals(-81.0, p[0].getEstimate(), 1.0e-8); assertEquals(137.0, p[1].getEstimate(), 1.0e-8); assertEquals(-34.0, p[2].getEstimate(), 1.0e-8); assertEquals( 22.0, p[3].getEstimate(), 1.0e-8); } public void testMoreEstimatedParametersSimple() { EstimatedParameter[] p = { new EstimatedParameter("p0", 7), new EstimatedParameter("p1", 6), new EstimatedParameter("p2", 5), new EstimatedParameter("p3", 4) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 3.0, 2.0 }, new EstimatedParameter[] { p[0], p[1] }, 7.0), new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 }, new EstimatedParameter[] { p[1], p[2], p[3] }, 3.0), new LinearMeasurement(new double[] { 2.0, 1.0 }, new EstimatedParameter[] { p[0], p[2] }, 5.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); try { estimator.estimate(problem); fail("an exception should have been caught"); } catch (EstimationException ee) { // expected behavior } } public void testMoreEstimatedParametersUnsorted() { EstimatedParameter[] p = { new EstimatedParameter("p0", 2), new EstimatedParameter("p1", 2), new EstimatedParameter("p2", 2), new EstimatedParameter("p3", 2), new EstimatedParameter("p4", 2), new EstimatedParameter("p5", 2) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, 1.0, 1.0 }, new EstimatedParameter[] { p[2], p[3], p[4] }, 12.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[4], p[5] }, -1.0), new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 }, new EstimatedParameter[] { p[3], p[2], p[5] }, 7.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[4], p[3] }, 1.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); try { estimator.estimate(problem); fail("an exception should have been caught"); } catch (EstimationException ee) { // expected behavior } } public void testRedundantEquations() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 1), new EstimatedParameter("p1", 1) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1] }, 5.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertEquals(0, estimator.getRMS(problem), 1.0e-10); EstimatedParameter[] all = problem.getAllParameters(); for (int i = 0; i < all.length; ++i) { assertEquals(all[i].getName().equals("p0") ? 2.0 : 1.0, all[i].getEstimate(), 1.0e-10); } } public void testInconsistentEquations() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("p0", 1), new EstimatedParameter("p1", 1) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1] }, 3.0), new LinearMeasurement(new double[] { 1.0, -1.0 }, new EstimatedParameter[] { p[0], p[1] }, 1.0), new LinearMeasurement(new double[] { 1.0, 3.0 }, new EstimatedParameter[] { p[0], p[1] }, 4.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertTrue(estimator.getRMS(problem) > 0.1); } public void testBoundParameters() throws EstimationException { EstimatedParameter[] p = { new EstimatedParameter("unbound0", 2, false), new EstimatedParameter("unbound1", 2, false), new EstimatedParameter("bound", 2, true) }; LinearProblem problem = new LinearProblem(new LinearMeasurement[] { new LinearMeasurement(new double[] { 1.0, 1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 3.0), new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 1.0), new LinearMeasurement(new double[] { 1.0, 3.0, 2.0 }, new EstimatedParameter[] { p[0], p[1], p[2] }, 7.0) }); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); estimator.estimate(problem); assertTrue(estimator.getRMS(problem) < 1.0e-10); double[][] covariances = estimator.getCovariances(problem); int i0 = 0, i1 = 1; if (problem.getUnboundParameters()[0].getName().endsWith("1")) { i0 = 1; i1 = 0; } assertEquals(11.0 / 24, covariances[i0][i0], 1.0e-10); assertEquals(-3.0 / 24, covariances[i0][i1], 1.0e-10); assertEquals(-3.0 / 24, covariances[i1][i0], 1.0e-10); assertEquals( 3.0 / 24, covariances[i1][i1], 1.0e-10); double[] errors = estimator.guessParametersErrors(problem); assertEquals(0, errors[i0], 1.0e-10); assertEquals(0, errors[i1], 1.0e-10); } public void testMaxIterations() { Circle circle = new Circle(98.680, 47.345); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); try { GaussNewtonEstimator estimator = new GaussNewtonEstimator(4, 1.0e-14, 1.0e-14); estimator.estimate(circle); fail("an exception should have been caught"); } catch (EstimationException ee) { // expected behavior } } public void testCircleFitting() throws EstimationException { Circle circle = new Circle(98.680, 47.345); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-10, 1.0e-10); estimator.estimate(circle); double rms = estimator.getRMS(circle); assertEquals(1.768262623567235, FastMath.sqrt(circle.getM()) * rms, 1.0e-10); assertEquals(69.96016176931406, circle.getRadius(), 1.0e-10); assertEquals(96.07590211815305, circle.getX(), 1.0e-10); assertEquals(48.13516790438953, circle.getY(), 1.0e-10); } public void testCircleFittingBadInit() { Circle circle = new Circle(-12, -12); double[][] points = new double[][] { {-0.312967, 0.072366}, {-0.339248, 0.132965}, {-0.379780, 0.202724}, {-0.390426, 0.260487}, {-0.361212, 0.328325}, {-0.346039, 0.392619}, {-0.280579, 0.444306}, {-0.216035, 0.470009}, {-0.149127, 0.493832}, {-0.075133, 0.483271}, {-0.007759, 0.452680}, { 0.060071, 0.410235}, { 0.103037, 0.341076}, { 0.118438, 0.273884}, { 0.131293, 0.192201}, { 0.115869, 0.129797}, { 0.072223, 0.058396}, { 0.022884, 0.000718}, {-0.053355, -0.020405}, {-0.123584, -0.032451}, {-0.216248, -0.032862}, {-0.278592, -0.005008}, {-0.337655, 0.056658}, {-0.385899, 0.112526}, {-0.405517, 0.186957}, {-0.415374, 0.262071}, {-0.387482, 0.343398}, {-0.347322, 0.397943}, {-0.287623, 0.458425}, {-0.223502, 0.475513}, {-0.135352, 0.478186}, {-0.061221, 0.483371}, { 0.003711, 0.422737}, { 0.065054, 0.375830}, { 0.108108, 0.297099}, { 0.123882, 0.222850}, { 0.117729, 0.134382}, { 0.085195, 0.056820}, { 0.029800, -0.019138}, {-0.027520, -0.072374}, {-0.102268, -0.091555}, {-0.200299, -0.106578}, {-0.292731, -0.091473}, {-0.356288, -0.051108}, {-0.420561, 0.014926}, {-0.471036, 0.074716}, {-0.488638, 0.182508}, {-0.485990, 0.254068}, {-0.463943, 0.338438}, {-0.406453, 0.404704}, {-0.334287, 0.466119}, {-0.254244, 0.503188}, {-0.161548, 0.495769}, {-0.075733, 0.495560}, { 0.001375, 0.434937}, { 0.082787, 0.385806}, { 0.115490, 0.323807}, { 0.141089, 0.223450}, { 0.138693, 0.131703}, { 0.126415, 0.049174}, { 0.066518, -0.010217}, {-0.005184, -0.070647}, {-0.080985, -0.103635}, {-0.177377, -0.116887}, {-0.260628, -0.100258}, {-0.335756, -0.056251}, {-0.405195, -0.000895}, {-0.444937, 0.085456}, {-0.484357, 0.175597}, {-0.472453, 0.248681}, {-0.438580, 0.347463}, {-0.402304, 0.422428}, {-0.326777, 0.479438}, {-0.247797, 0.505581}, {-0.152676, 0.519380}, {-0.071754, 0.516264}, { 0.015942, 0.472802}, { 0.076608, 0.419077}, { 0.127673, 0.330264}, { 0.159951, 0.262150}, { 0.153530, 0.172681}, { 0.140653, 0.089229}, { 0.078666, 0.024981}, { 0.023807, -0.037022}, {-0.048837, -0.077056}, {-0.127729, -0.075338}, {-0.221271, -0.067526} }; for (int i = 0; i < points.length; ++i) { circle.addPoint(points[i][0], points[i][1]); } GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6); try { estimator.estimate(circle); fail("an exception should have been caught"); } catch (EstimationException ee) { // expected behavior } } private static class LinearProblem extends SimpleEstimationProblem { public LinearProblem(LinearMeasurement[] measurements) { HashSet set = new HashSet(); for (int i = 0; i < measurements.length; ++i) { addMeasurement(measurements[i]); EstimatedParameter[] parameters = measurements[i].getParameters(); for (int j = 0; j < parameters.length; ++j) { set.add(parameters[j]); } } for (EstimatedParameter p : set) { addParameter(p); } } } private static class LinearMeasurement extends WeightedMeasurement { public LinearMeasurement(double[] factors, EstimatedParameter[] parameters, double setPoint) { super(1.0, setPoint, true); this.factors = factors; this.parameters = parameters; setIgnored(false); } @Override public double getTheoreticalValue() { double v = 0; for (int i = 0; i < factors.length; ++i) { v += factors[i] * parameters[i].getEstimate(); } return v; } @Override public double getPartial(EstimatedParameter parameter) { for (int i = 0; i < parameters.length; ++i) { if (parameters[i] == parameter) { return factors[i]; } } return 0; } public EstimatedParameter[] getParameters() { return parameters; } private double[] factors; private EstimatedParameter[] parameters; private static final long serialVersionUID = -3922448707008868580L; } private static class Circle implements EstimationProblem { public Circle(double cx, double cy) { this.cx = new EstimatedParameter("cx", cx); this.cy = new EstimatedParameter(new EstimatedParameter("cy", cy)); points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new PointModel(this, px, py)); } public int getM() { return points.size(); } public WeightedMeasurement[] getMeasurements() { return points.toArray(new PointModel[points.size()]); } public EstimatedParameter[] getAllParameters() { return new EstimatedParameter[] { cx, cy }; } public EstimatedParameter[] getUnboundParameters() { return new EstimatedParameter[] { cx, cy }; } public double getPartialRadiusX() { double dRdX = 0; for (PointModel point : points) { dRdX += point.getPartialDiX(); } return dRdX / points.size(); } public double getPartialRadiusY() { double dRdY = 0; for (PointModel point : points) { dRdY += point.getPartialDiY(); } return dRdY / points.size(); } public double getRadius() { double r = 0; for (PointModel point : points) { r += point.getCenterDistance(); } return r / points.size(); } public double getX() { return cx.getEstimate(); } public double getY() { return cy.getEstimate(); } private static class PointModel extends WeightedMeasurement { public PointModel(Circle circle, double px, double py) { super(1.0, 0.0); this.px = px; this.py = py; this.circle = circle; } @Override public double getPartial(EstimatedParameter parameter) { if (parameter == circle.cx) { return getPartialDiX() - circle.getPartialRadiusX(); } else if (parameter == circle.cy) { return getPartialDiY() - circle.getPartialRadiusY(); } return 0; } public double getCenterDistance() { double dx = px - circle.cx.getEstimate(); double dy = py - circle.cy.getEstimate(); return FastMath.sqrt(dx * dx + dy * dy); } public double getPartialDiX() { return (circle.cx.getEstimate() - px) / getCenterDistance(); } public double getPartialDiY() { return (circle.cy.getEstimate() - py) / getCenterDistance(); } @Override public double getTheoreticalValue() { return getCenterDistance() - circle.getRadius(); } private double px; private double py; private transient final Circle circle; private static final long serialVersionUID = 1L; } private EstimatedParameter cx; private EstimatedParameter cy; private ArrayList points; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/MinpackTest.java100644 1750 1750 167062 11532241243 27712 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.util.Arrays; import org.apache.commons.math.estimation.EstimatedParameter; import org.apache.commons.math.estimation.EstimationException; import org.apache.commons.math.estimation.EstimationProblem; import org.apache.commons.math.estimation.LevenbergMarquardtEstimator; import org.apache.commons.math.estimation.WeightedMeasurement; import org.apache.commons.math.util.FastMath; import junit.framework.*; /** *

      Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

      * * * *
      * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
      * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
        *
      1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
      2. *
      3. 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.
      4. *
      5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
      6. *
      7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
      8. *
      9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
      10. *
        * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ @Deprecated public class MinpackTest extends TestCase { public MinpackTest(String name) { super(name); } public void testMinpackLinearFullRank() { minpackTest(new LinearFullRankFunction(10, 5, 1.0, 5.0, 2.23606797749979), false); minpackTest(new LinearFullRankFunction(50, 5, 1.0, 8.06225774829855, 6.70820393249937), false); } public void testMinpackLinearRank1() { minpackTest(new LinearRank1Function(10, 5, 1.0, 291.521868819476, 1.4638501094228), false); minpackTest(new LinearRank1Function(50, 5, 1.0, 3101.60039334535, 3.48263016573496), false); } public void testMinpackLinearRank1ZeroColsAndRows() { minpackTest(new LinearRank1ZeroColsAndRowsFunction(10, 5, 1.0), false); minpackTest(new LinearRank1ZeroColsAndRowsFunction(50, 5, 1.0), false); } public void testMinpackRosenbrok() { minpackTest(new RosenbrockFunction(new double[] { -1.2, 1.0 }, FastMath.sqrt(24.2)), false); minpackTest(new RosenbrockFunction(new double[] { -12.0, 10.0 }, FastMath.sqrt(1795769.0)), false); minpackTest(new RosenbrockFunction(new double[] { -120.0, 100.0 }, 11.0 * FastMath.sqrt(169000121.0)), false); } public void testMinpackHelicalValley() { minpackTest(new HelicalValleyFunction(new double[] { -1.0, 0.0, 0.0 }, 50.0), false); minpackTest(new HelicalValleyFunction(new double[] { -10.0, 0.0, 0.0 }, 102.95630140987), false); minpackTest(new HelicalValleyFunction(new double[] { -100.0, 0.0, 0.0}, 991.261822123701), false); } public void testMinpackPowellSingular() { minpackTest(new PowellSingularFunction(new double[] { 3.0, -1.0, 0.0, 1.0 }, 14.6628782986152), false); minpackTest(new PowellSingularFunction(new double[] { 30.0, -10.0, 0.0, 10.0 }, 1270.9838708654), false); minpackTest(new PowellSingularFunction(new double[] { 300.0, -100.0, 0.0, 100.0 }, 126887.903284750), false); } public void testMinpackFreudensteinRoth() { minpackTest(new FreudensteinRothFunction(new double[] { 0.5, -2.0 }, 20.0124960961895, 6.99887517584575, new double[] { 11.4124844654993, -0.896827913731509 }), false); minpackTest(new FreudensteinRothFunction(new double[] { 5.0, -20.0 }, 12432.833948863, 6.9988751744895, new double[] { 11.4130046614746, -0.896796038685958 }), false); minpackTest(new FreudensteinRothFunction(new double[] { 50.0, -200.0 }, 11426454.595762, 6.99887517242903, new double[] { 11.4127817857886, -0.89680510749204 }), false); } public void testMinpackBard() { minpackTest(new BardFunction(1.0, 6.45613629515967, 0.0906359603390466, new double[] { 0.0824105765758334, 1.1330366534715, 2.34369463894115 }), false); minpackTest(new BardFunction(10.0, 36.1418531596785, 4.17476870138539, new double[] { 0.840666673818329, -158848033.259565, -164378671.653535 }), false); minpackTest(new BardFunction(100.0, 384.114678637399, 4.17476870135969, new double[] { 0.840666673867645, -158946167.205518, -164464906.857771 }), false); } public void testMinpackKowalikOsborne() { minpackTest(new KowalikOsborneFunction(new double[] { 0.25, 0.39, 0.415, 0.39 }, 0.0728915102882945, 0.017535837721129, new double[] { 0.192807810476249, 0.191262653354071, 0.123052801046931, 0.136053221150517 }), false); minpackTest(new KowalikOsborneFunction(new double[] { 2.5, 3.9, 4.15, 3.9 }, 2.97937007555202, 0.032052192917937, new double[] { 728675.473768287, -14.0758803129393, -32977797.7841797, -20571594.1977912 }), false); minpackTest(new KowalikOsborneFunction(new double[] { 25.0, 39.0, 41.5, 39.0 }, 29.9590617016037, 0.0175364017658228, new double[] { 0.192948328597594, 0.188053165007911, 0.122430604321144, 0.134575665392506 }), true); } public void testMinpackMeyer() { minpackTest(new MeyerFunction(new double[] { 0.02, 4000.0, 250.0 }, 41153.4665543031, 9.37794514651874, new double[] { 0.00560963647102661, 6181.34634628659, 345.223634624144 }), false); minpackTest(new MeyerFunction(new double[] { 0.2, 40000.0, 2500.0 }, 4168216.89130846, 792.917871779501, new double[] { 1.42367074157994e-11, 33695.7133432541, 901.268527953801 }), true); } public void testMinpackWatson() { minpackTest(new WatsonFunction(6, 0.0, 5.47722557505166, 0.0478295939097601, new double[] { -0.0157249615083782, 1.01243488232965, -0.232991722387673, 1.26043101102818, -1.51373031394421, 0.99299727291842 }), false); minpackTest(new WatsonFunction(6, 10.0, 6433.12578950026, 0.0478295939096951, new double[] { -0.0157251901386677, 1.01243485860105, -0.232991545843829, 1.26042932089163, -1.51372776706575, 0.99299573426328 }), false); minpackTest(new WatsonFunction(6, 100.0, 674256.040605213, 0.047829593911544, new double[] { -0.0157247019712586, 1.01243490925658, -0.232991922761641, 1.26043292929555, -1.51373320452707, 0.99299901922322 }), false); minpackTest(new WatsonFunction(9, 0.0, 5.47722557505166, 0.00118311459212420, new double[] { -0.153070644166722e-4, 0.999789703934597, 0.0147639634910978, 0.146342330145992, 1.00082109454817, -2.61773112070507, 4.10440313943354, -3.14361226236241, 1.05262640378759 }), false); minpackTest(new WatsonFunction(9, 10.0, 12088.127069307, 0.00118311459212513, new double[] { -0.153071334849279e-4, 0.999789703941234, 0.0147639629786217, 0.146342334818836, 1.00082107321386, -2.61773107084722, 4.10440307655564, -3.14361222178686, 1.05262639322589 }), false); minpackTest(new WatsonFunction(9, 100.0, 1269109.29043834, 0.00118311459212384, new double[] { -0.153069523352176e-4, 0.999789703958371, 0.0147639625185392, 0.146342341096326, 1.00082104729164, -2.61773101573645, 4.10440301427286, -3.14361218602503, 1.05262638516774 }), false); minpackTest(new WatsonFunction(12, 0.0, 5.47722557505166, 0.217310402535861e-4, new double[] { -0.660266001396382e-8, 1.00000164411833, -0.000563932146980154, 0.347820540050756, -0.156731500244233, 1.05281515825593, -3.24727109519451, 7.2884347837505, -10.271848098614, 9.07411353715783, -4.54137541918194, 1.01201187975044 }), false); minpackTest(new WatsonFunction(12, 10.0, 19220.7589790951, 0.217310402518509e-4, new double[] { -0.663710223017410e-8, 1.00000164411787, -0.000563932208347327, 0.347820540486998, -0.156731503955652, 1.05281517654573, -3.2472711515214, 7.28843489430665, -10.2718482369638, 9.07411364383733, -4.54137546533666, 1.01201188830857 }), false); minpackTest(new WatsonFunction(12, 100.0, 2018918.04462367, 0.217310402539845e-4, new double[] { -0.663806046485249e-8, 1.00000164411786, -0.000563932210324959, 0.347820540503588, -0.156731504091375, 1.05281517718031, -3.24727115337025, 7.28843489775302, -10.2718482410813, 9.07411364688464, -4.54137546660822, 1.0120118885369 }), false); } public void testMinpackBox3Dimensional() { minpackTest(new Box3DimensionalFunction(10, new double[] { 0.0, 10.0, 20.0 }, 32.1115837449572), false); } public void testMinpackJennrichSampson() { minpackTest(new JennrichSampsonFunction(10, new double[] { 0.3, 0.4 }, 64.5856498144943, 11.1517793413499, new double[] { 0.257819926636811, 0.257829976764542 }), false); } public void testMinpackBrownDennis() { minpackTest(new BrownDennisFunction(20, new double[] { 25.0, 5.0, -5.0, -1.0 }, 2815.43839161816, 292.954288244866, new double[] { -11.59125141003, 13.2024883984741, -0.403574643314272, 0.236736269844604 }), false); minpackTest(new BrownDennisFunction(20, new double[] { 250.0, 50.0, -50.0, -10.0 }, 555073.354173069, 292.954270581415, new double[] { -11.5959274272203, 13.2041866926242, -0.403417362841545, 0.236771143410386 }), false); minpackTest(new BrownDennisFunction(20, new double[] { 2500.0, 500.0, -500.0, -100.0 }, 61211252.2338581, 292.954306151134, new double[] { -11.5902596937374, 13.2020628854665, -0.403688070279258, 0.236665033746463 }), false); } public void testMinpackChebyquad() { minpackTest(new ChebyquadFunction(1, 8, 1.0, 1.88623796907732, 1.88623796907732, new double[] { 0.5 }), false); minpackTest(new ChebyquadFunction(1, 8, 10.0, 5383344372.34005, 1.88424820499951, new double[] { 0.9817314924684 }), false); minpackTest(new ChebyquadFunction(1, 8, 100.0, 0.118088726698392e19, 1.88424820499347, new double[] { 0.9817314852934 }), false); minpackTest(new ChebyquadFunction(8, 8, 1.0, 0.196513862833975, 0.0593032355046727, new double[] { 0.0431536648587336, 0.193091637843267, 0.266328593812698, 0.499999334628884, 0.500000665371116, 0.733671406187302, 0.806908362156733, 0.956846335141266 }), false); minpackTest(new ChebyquadFunction(9, 9, 1.0, 0.16994993465202, 0.0, new double[] { 0.0442053461357828, 0.199490672309881, 0.23561910847106, 0.416046907892598, 0.5, 0.583953092107402, 0.764380891528940, 0.800509327690119, 0.955794653864217 }), false); minpackTest(new ChebyquadFunction(10, 10, 1.0, 0.183747831178711, 0.0806471004038253, new double[] { 0.0596202671753563, 0.166708783805937, 0.239171018813509, 0.398885290346268, 0.398883667870681, 0.601116332129320, 0.60111470965373, 0.760828981186491, 0.833291216194063, 0.940379732824644 }), false); } public void testMinpackBrownAlmostLinear() { minpackTest(new BrownAlmostLinearFunction(10, 0.5, 16.5302162063499, 0.0, new double[] { 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 1.20569696650138 }), false); minpackTest(new BrownAlmostLinearFunction(10, 5.0, 9765624.00089211, 0.0, new double[] { 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 1.20569696650135 }), false); minpackTest(new BrownAlmostLinearFunction(10, 50.0, 0.9765625e17, 0.0, new double[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }), false); minpackTest(new BrownAlmostLinearFunction(30, 0.5, 83.476044467848, 0.0, new double[] { 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 1.06737350671578 }), false); minpackTest(new BrownAlmostLinearFunction(40, 0.5, 128.026364472323, 0.0, new double[] { 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 0.999999999999121 }), false); } public void testMinpackOsborne1() { minpackTest(new Osborne1Function(new double[] { 0.5, 1.5, -1.0, 0.01, 0.02, }, 0.937564021037838, 0.00739249260904843, new double[] { 0.375410049244025, 1.93584654543108, -1.46468676748716, 0.0128675339110439, 0.0221227011813076 }), false); } public void testMinpackOsborne2() { minpackTest(new Osborne2Function(new double[] { 1.3, 0.65, 0.65, 0.7, 0.6, 3.0, 5.0, 7.0, 2.0, 4.5, 5.5 }, 1.44686540984712, 0.20034404483314, new double[] { 1.30997663810096, 0.43155248076, 0.633661261602859, 0.599428560991695, 0.754179768272449, 0.904300082378518, 1.36579949521007, 4.82373199748107, 2.39868475104871, 4.56887554791452, 5.67534206273052 }), false); } private void minpackTest(MinpackFunction function, boolean exceptionExpected) { LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator(); estimator.setMaxCostEval(100 * (function.getN() + 1)); estimator.setCostRelativeTolerance(FastMath.sqrt(2.22044604926e-16)); estimator.setParRelativeTolerance(FastMath.sqrt(2.22044604926e-16)); estimator.setOrthoTolerance(2.22044604926e-16); assertTrue(function.checkTheoreticalStartCost(estimator.getRMS(function))); try { estimator.estimate(function); assertFalse(exceptionExpected); } catch (EstimationException lsse) { assertTrue(exceptionExpected); } assertTrue(function.checkTheoreticalMinCost(estimator.getRMS(function))); assertTrue(function.checkTheoreticalMinParams()); } private static abstract class MinpackFunction implements EstimationProblem { protected MinpackFunction(int m, double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { this.m = m; this.n = startParams.length; parameters = new EstimatedParameter[n]; for (int i = 0; i < n; ++i) { parameters[i] = new EstimatedParameter("p" + i, startParams[i]); } this.theoreticalStartCost = theoreticalStartCost; this.theoreticalMinCost = theoreticalMinCost; this.theoreticalMinParams = theoreticalMinParams; this.costAccuracy = 1.0e-8; this.paramsAccuracy = 1.0e-5; } protected static double[] buildArray(int n, double x) { double[] array = new double[n]; Arrays.fill(array, x); return array; } protected void setCostAccuracy(double costAccuracy) { this.costAccuracy = costAccuracy; } protected void setParamsAccuracy(double paramsAccuracy) { this.paramsAccuracy = paramsAccuracy; } public int getN() { return parameters.length; } public boolean checkTheoreticalStartCost(double rms) { double threshold = costAccuracy * (1.0 + theoreticalStartCost); return FastMath.abs(FastMath.sqrt(m) * rms - theoreticalStartCost) <= threshold; } public boolean checkTheoreticalMinCost(double rms) { double threshold = costAccuracy * (1.0 + theoreticalMinCost); return FastMath.abs(FastMath.sqrt(m) * rms - theoreticalMinCost) <= threshold; } public boolean checkTheoreticalMinParams() { if (theoreticalMinParams != null) { for (int i = 0; i < theoreticalMinParams.length; ++i) { double mi = theoreticalMinParams[i]; double vi = parameters[i].getEstimate(); if (FastMath.abs(mi - vi) > (paramsAccuracy * (1.0 + FastMath.abs(mi)))) { return false; } } } return true; } public WeightedMeasurement[] getMeasurements() { WeightedMeasurement[] measurements = new WeightedMeasurement[m]; for (int i = 0; i < m; ++i) { measurements[i] = new MinpackMeasurement(this, i); } return measurements; } public EstimatedParameter[] getUnboundParameters() { return parameters; } public EstimatedParameter[] getAllParameters() { return parameters; } protected abstract double[][] getJacobian(); protected abstract double[] getResiduals(); private static class MinpackMeasurement extends WeightedMeasurement { public MinpackMeasurement(MinpackFunction f, int index) { super(1.0, 0.0); this.index = index; this.f = f; } @Override public double getTheoreticalValue() { // this is obviously NOT efficient as we recompute the whole vector // each time we need only one element, but it is only for test // purposes and is simpler to check. // This implementation should NOT be taken as an example, it is ugly! return f.getResiduals()[index]; } @Override public double getPartial(EstimatedParameter parameter) { // this is obviously NOT efficient as we recompute the whole jacobian // each time we need only one element, but it is only for test // purposes and is simpler to check. // This implementation should NOT be taken as an example, it is ugly! for (int j = 0; j < f.n; ++j) { if (parameter == f.parameters[j]) { return f.getJacobian()[index][j]; } } return 0; } private int index; private transient final MinpackFunction f; private static final long serialVersionUID = 1L; } protected int n; protected int m; protected EstimatedParameter[] parameters; protected double theoreticalStartCost; protected double theoreticalMinCost; protected double[] theoreticalMinParams; protected double costAccuracy; protected double paramsAccuracy; } private static class LinearFullRankFunction extends MinpackFunction { public LinearFullRankFunction(int m, int n, double x0, double theoreticalStartCost, double theoreticalMinCost) { super(m, buildArray(n, x0), theoreticalStartCost, theoreticalMinCost, buildArray(n, -1.0)); } @Override protected double[][] getJacobian() { double t = 2.0 / m; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = (i == j) ? (1 - t) : -t; } } return jacobian; } @Override protected double[] getResiduals() { double sum = 0; for (int i = 0; i < n; ++i) { sum += parameters[i].getEstimate(); } double t = 1 + 2 * sum / m; double[] f = new double[m]; for (int i = 0; i < n; ++i) { f[i] = parameters[i].getEstimate() - t; } Arrays.fill(f, n, m, -t); return f; } } private static class LinearRank1Function extends MinpackFunction { public LinearRank1Function(int m, int n, double x0, double theoreticalStartCost, double theoreticalMinCost) { super(m, buildArray(n, x0), theoreticalStartCost, theoreticalMinCost, null); } @Override protected double[][] getJacobian() { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = (i + 1) * (j + 1); } } return jacobian; } @Override protected double[] getResiduals() { double[] f = new double[m]; double sum = 0; for (int i = 0; i < n; ++i) { sum += (i + 1) * parameters[i].getEstimate(); } for (int i = 0; i < m; ++i) { f[i] = (i + 1) * sum - 1; } return f; } } private static class LinearRank1ZeroColsAndRowsFunction extends MinpackFunction { public LinearRank1ZeroColsAndRowsFunction(int m, int n, double x0) { super(m, buildArray(n, x0), FastMath.sqrt(m + (n+1)*(n-2)*(m-2)*(m-1) * ((n+1)*(n-2)*(2*m-3) - 12) / 24.0), FastMath.sqrt((m * (m + 3) - 6) / (2.0 * (2 * m - 3))), null); } @Override protected double[][] getJacobian() { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; jacobian[i][0] = 0; for (int j = 1; j < (n - 1); ++j) { if (i == 0) { jacobian[i][j] = 0; } else if (i != (m - 1)) { jacobian[i][j] = i * (j + 1); } else { jacobian[i][j] = 0; } } jacobian[i][n - 1] = 0; } return jacobian; } @Override protected double[] getResiduals() { double[] f = new double[m]; double sum = 0; for (int i = 1; i < (n - 1); ++i) { sum += (i + 1) * parameters[i].getEstimate(); } for (int i = 0; i < (m - 1); ++i) { f[i] = i * sum - 1; } f[m - 1] = -1; return f; } } private static class RosenbrockFunction extends MinpackFunction { public RosenbrockFunction(double[] startParams, double theoreticalStartCost) { super(2, startParams, theoreticalStartCost, 0.0, buildArray(2, 1.0)); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); return new double[][] { { -20 * x1, 10 }, { -1, 0 } }; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); return new double[] { 10 * (x2 - x1 * x1), 1 - x1 }; } } private static class HelicalValleyFunction extends MinpackFunction { public HelicalValleyFunction(double[] startParams, double theoreticalStartCost) { super(3, startParams, theoreticalStartCost, 0.0, new double[] { 1.0, 0.0, 0.0 }); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double tmpSquare = x1 * x1 + x2 * x2; double tmp1 = twoPi * tmpSquare; double tmp2 = FastMath.sqrt(tmpSquare); return new double[][] { { 100 * x2 / tmp1, -100 * x1 / tmp1, 10 }, { 10 * x1 / tmp2, 10 * x2 / tmp2, 0 }, { 0, 0, 1 } }; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double tmp1; if (x1 == 0) { tmp1 = (x2 >= 0) ? 0.25 : -0.25; } else { tmp1 = FastMath.atan(x2 / x1) / twoPi; if (x1 < 0) { tmp1 += 0.5; } } double tmp2 = FastMath.sqrt(x1 * x1 + x2 * x2); return new double[] { 10.0 * (x3 - 10 * tmp1), 10.0 * (tmp2 - 1), x3 }; } private static final double twoPi = 2.0 * FastMath.PI; } private static class PowellSingularFunction extends MinpackFunction { public PowellSingularFunction(double[] startParams, double theoreticalStartCost) { super(4, startParams, theoreticalStartCost, 0.0, buildArray(4, 0.0)); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); return new double[][] { { 1, 10, 0, 0 }, { 0, 0, sqrt5, -sqrt5 }, { 0, 2 * (x2 - 2 * x3), -4 * (x2 - 2 * x3), 0 }, { 2 * sqrt10 * (x1 - x4), 0, 0, -2 * sqrt10 * (x1 - x4) } }; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); return new double[] { x1 + 10 * x2, sqrt5 * (x3 - x4), (x2 - 2 * x3) * (x2 - 2 * x3), sqrt10 * (x1 - x4) * (x1 - x4) }; } private static final double sqrt5 = FastMath.sqrt( 5.0); private static final double sqrt10 = FastMath.sqrt(10.0); } private static class FreudensteinRothFunction extends MinpackFunction { public FreudensteinRothFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(2, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double x2 = parameters[1].getEstimate(); return new double[][] { { 1, x2 * (10 - 3 * x2) - 2 }, { 1, x2 * ( 2 + 3 * x2) - 14, } }; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); return new double[] { -13.0 + x1 + ((5.0 - x2) * x2 - 2.0) * x2, -29.0 + x1 + ((1.0 + x2) * x2 - 14.0) * x2 }; } } private static class BardFunction extends MinpackFunction { public BardFunction(double x0, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(15, buildArray(3, x0), theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp1 = i + 1; double tmp2 = 15 - i; double tmp3 = (i <= 7) ? tmp1 : tmp2; double tmp4 = x2 * tmp2 + x3 * tmp3; tmp4 *= tmp4; jacobian[i] = new double[] { -1, tmp1 * tmp2 / tmp4, tmp1 * tmp3 / tmp4 }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double tmp1 = i + 1; double tmp2 = 15 - i; double tmp3 = (i <= 7) ? tmp1 : tmp2; f[i] = y[i] - (x1 + tmp1 / (x2 * tmp2 + x3 * tmp3)); } return f; } private static final double[] y = { 0.14, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.39, 0.37, 0.58, 0.73, 0.96, 1.34, 2.10, 4.39 }; } private static class KowalikOsborneFunction extends MinpackFunction { public KowalikOsborneFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(11, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); if (theoreticalStartCost > 20.0) { setCostAccuracy(2.0e-4); setParamsAccuracy(5.0e-3); } } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp = v[i] * (v[i] + x3) + x4; double j1 = -v[i] * (v[i] + x2) / tmp; double j2 = -v[i] * x1 / tmp; double j3 = j1 * j2; double j4 = j3 / v[i]; jacobian[i] = new double[] { j1, j2, j3, j4 }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { f[i] = y[i] - x1 * (v[i] * (v[i] + x2)) / (v[i] * (v[i] + x3) + x4); } return f; } private static final double[] v = { 4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625 }; private static final double[] y = { 0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627, 0.0456, 0.0342, 0.0323, 0.0235, 0.0246 }; } private static class MeyerFunction extends MinpackFunction { public MeyerFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(16, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); if (theoreticalStartCost > 1.0e6) { setCostAccuracy(7.0e-3); setParamsAccuracy(2.0e-2); } } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = 5.0 * (i + 1) + 45.0 + x3; double tmp1 = x2 / temp; double tmp2 = FastMath.exp(tmp1); double tmp3 = x1 * tmp2 / temp; jacobian[i] = new double[] { tmp2, tmp3, -tmp1 * tmp3 }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { f[i] = x1 * FastMath.exp(x2 / (5.0 * (i + 1) + 45.0 + x3)) - y[i]; } return f; } private static final double[] y = { 34780.0, 28610.0, 23650.0, 19630.0, 16370.0, 13720.0, 11540.0, 9744.0, 8261.0, 7030.0, 6005.0, 5147.0, 4427.0, 3820.0, 3307.0, 2872.0 }; } private static class WatsonFunction extends MinpackFunction { public WatsonFunction(int n, double x0, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(31, buildArray(n, x0), theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double[][] jacobian = new double[m][]; for (int i = 0; i < (m - 2); ++i) { double div = (i + 1) / 29.0; double s2 = 0.0; double dx = 1.0; for (int j = 0; j < n; ++j) { s2 += dx * parameters[j].getEstimate(); dx *= div; } double temp= 2 * div * s2; dx = 1.0 / div; jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = dx * (j - temp); dx *= div; } } jacobian[m - 2] = new double[n]; jacobian[m - 2][0] = 1; jacobian[m - 1] = new double[n]; jacobian[m - 1][0]= -2 * parameters[0].getEstimate(); jacobian[m - 1][1]= 1; return jacobian; } @Override protected double[] getResiduals() { double[] f = new double[m]; for (int i = 0; i < (m - 2); ++i) { double div = (i + 1) / 29.0; double s1 = 0; double dx = 1; for (int j = 1; j < n; ++j) { s1 += j * dx * parameters[j].getEstimate(); dx *= div; } double s2 =0; dx =1; for (int j = 0; j < n; ++j) { s2 += dx * parameters[j].getEstimate(); dx *= div; } f[i] = s1 - s2 * s2 - 1; } double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); f[m - 2] = x1; f[m - 1] = x2 - x1 * x1 - 1; return f; } } private static class Box3DimensionalFunction extends MinpackFunction { public Box3DimensionalFunction(int m, double[] startParams, double theoreticalStartCost) { super(m, startParams, theoreticalStartCost, 0.0, new double[] { 1.0, 10.0, 1.0 }); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp = (i + 1) / 10.0; jacobian[i] = new double[] { -tmp * FastMath.exp(-tmp * x1), tmp * FastMath.exp(-tmp * x2), FastMath.exp(-i - 1) - FastMath.exp(-tmp) }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double tmp = (i + 1) / 10.0; f[i] = FastMath.exp(-tmp * x1) - FastMath.exp(-tmp * x2) + (FastMath.exp(-i - 1) - FastMath.exp(-tmp)) * x3; } return f; } } private static class JennrichSampsonFunction extends MinpackFunction { public JennrichSampsonFunction(int m, double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double t = i + 1; jacobian[i] = new double[] { -t * FastMath.exp(t * x1), -t * FastMath.exp(t * x2) }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = i + 1; f[i] = 2 + 2 * temp - FastMath.exp(temp * x1) - FastMath.exp(temp * x2); } return f; } } private static class BrownDennisFunction extends MinpackFunction { public BrownDennisFunction(int m, double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); setCostAccuracy(2.5e-8); } @Override protected double[][] getJacobian() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = (i + 1) / 5.0; double ti = FastMath.sin(temp); double tmp1 = x1 + temp * x2 - FastMath.exp(temp); double tmp2 = x3 + ti * x4 - FastMath.cos(temp); jacobian[i] = new double[] { 2 * tmp1, 2 * temp * tmp1, 2 * tmp2, 2 * ti * tmp2 }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = (i + 1) / 5.0; double tmp1 = x1 + temp * x2 - FastMath.exp(temp); double tmp2 = x3 + FastMath.sin(temp) * x4 - FastMath.cos(temp); f[i] = tmp1 * tmp1 + tmp2 * tmp2; } return f; } } private static class ChebyquadFunction extends MinpackFunction { private static double[] buildChebyquadArray(int n, double factor) { double[] array = new double[n]; double inv = factor / (n + 1); for (int i = 0; i < n; ++i) { array[i] = (i + 1) * inv; } return array; } public ChebyquadFunction(int n, int m, double factor, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, buildChebyquadArray(n, factor), theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; } double dx = 1.0 / n; for (int j = 0; j < n; ++j) { double tmp1 = 1; double tmp2 = 2 * parameters[j].getEstimate() - 1; double temp = 2 * tmp2; double tmp3 = 0; double tmp4 = 2; for (int i = 0; i < m; ++i) { jacobian[i][j] = dx * tmp4; double ti = 4 * tmp2 + temp * tmp4 - tmp3; tmp3 = tmp4; tmp4 = ti; ti = temp * tmp2 - tmp1; tmp1 = tmp2; tmp2 = ti; } } return jacobian; } @Override protected double[] getResiduals() { double[] f = new double[m]; for (int j = 0; j < n; ++j) { double tmp1 = 1; double tmp2 = 2 * parameters[j].getEstimate() - 1; double temp = 2 * tmp2; for (int i = 0; i < m; ++i) { f[i] += tmp2; double ti = temp * tmp2 - tmp1; tmp1 = tmp2; tmp2 = ti; } } double dx = 1.0 / n; boolean iev = false; for (int i = 0; i < m; ++i) { f[i] *= dx; if (iev) { f[i] += 1.0 / (i * (i + 2)); } iev = ! iev; } return f; } } private static class BrownAlmostLinearFunction extends MinpackFunction { public BrownAlmostLinearFunction(int m, double factor, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, buildArray(m, factor), theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; } double prod = 1; for (int j = 0; j < n; ++j) { prod *= parameters[j].getEstimate(); for (int i = 0; i < n; ++i) { jacobian[i][j] = 1; } jacobian[j][j] = 2; } for (int j = 0; j < n; ++j) { EstimatedParameter vj = parameters[j]; double temp = vj.getEstimate(); if (temp == 0) { temp = 1; prod = 1; for (int k = 0; k < n; ++k) { if (k != j) { prod *= parameters[k].getEstimate(); } } } jacobian[n - 1][j] = prod / temp; } return jacobian; } @Override protected double[] getResiduals() { double[] f = new double[m]; double sum = -(n + 1); double prod = 1; for (int j = 0; j < n; ++j) { sum += parameters[j].getEstimate(); prod *= parameters[j].getEstimate(); } for (int i = 0; i < n; ++i) { f[i] = parameters[i].getEstimate() + sum; } f[n - 1] = prod - 1; return f; } } private static class Osborne1Function extends MinpackFunction { public Osborne1Function(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(33, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double x5 = parameters[4].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = 10.0 * i; double tmp1 = FastMath.exp(-temp * x4); double tmp2 = FastMath.exp(-temp * x5); jacobian[i] = new double[] { -1, -tmp1, -tmp2, temp * x2 * tmp1, temp * x3 * tmp2 }; } return jacobian; } @Override protected double[] getResiduals() { double x1 = parameters[0].getEstimate(); double x2 = parameters[1].getEstimate(); double x3 = parameters[2].getEstimate(); double x4 = parameters[3].getEstimate(); double x5 = parameters[4].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = 10.0 * i; double tmp1 = FastMath.exp(-temp * x4); double tmp2 = FastMath.exp(-temp * x5); f[i] = y[i] - (x1 + x2 * tmp1 + x3 * tmp2); } return f; } private static final double[] y = { 0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818, 0.784, 0.751, 0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506, 0.490, 0.478, 0.467, 0.457, 0.448, 0.438, 0.431, 0.424, 0.420, 0.414, 0.411, 0.406 }; } private static class Osborne2Function extends MinpackFunction { public Osborne2Function(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(65, startParams, theoreticalStartCost, theoreticalMinCost, theoreticalMinParams); } @Override protected double[][] getJacobian() { double x01 = parameters[0].getEstimate(); double x02 = parameters[1].getEstimate(); double x03 = parameters[2].getEstimate(); double x04 = parameters[3].getEstimate(); double x05 = parameters[4].getEstimate(); double x06 = parameters[5].getEstimate(); double x07 = parameters[6].getEstimate(); double x08 = parameters[7].getEstimate(); double x09 = parameters[8].getEstimate(); double x10 = parameters[9].getEstimate(); double x11 = parameters[10].getEstimate(); double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = i / 10.0; double tmp1 = FastMath.exp(-x05 * temp); double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09)); double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10)); double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11)); jacobian[i] = new double[] { -tmp1, -tmp2, -tmp3, -tmp4, temp * x01 * tmp1, x02 * (temp - x09) * (temp - x09) * tmp2, x03 * (temp - x10) * (temp - x10) * tmp3, x04 * (temp - x11) * (temp - x11) * tmp4, -2 * x02 * x06 * (temp - x09) * tmp2, -2 * x03 * x07 * (temp - x10) * tmp3, -2 * x04 * x08 * (temp - x11) * tmp4 }; } return jacobian; } @Override protected double[] getResiduals() { double x01 = parameters[0].getEstimate(); double x02 = parameters[1].getEstimate(); double x03 = parameters[2].getEstimate(); double x04 = parameters[3].getEstimate(); double x05 = parameters[4].getEstimate(); double x06 = parameters[5].getEstimate(); double x07 = parameters[6].getEstimate(); double x08 = parameters[7].getEstimate(); double x09 = parameters[8].getEstimate(); double x10 = parameters[9].getEstimate(); double x11 = parameters[10].getEstimate(); double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = i / 10.0; double tmp1 = FastMath.exp(-x05 * temp); double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09)); double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10)); double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11)); f[i] = y[i] - (x01 * tmp1 + x02 * tmp2 + x03 * tmp3 + x04 * tmp4); } return f; } private static final double[] y = { 1.366, 1.191, 1.112, 1.013, 0.991, 0.885, 0.831, 0.847, 0.786, 0.725, 0.746, 0.679, 0.608, 0.655, 0.616, 0.606, 0.602, 0.626, 0.651, 0.724, 0.649, 0.649, 0.694, 0.644, 0.624, 0.661, 0.612, 0.558, 0.533, 0.495, 0.500, 0.423, 0.395, 0.375, 0.372, 0.391, 0.396, 0.405, 0.428, 0.429, 0.523, 0.562, 0.607, 0.653, 0.672, 0.708, 0.633, 0.668, 0.645, 0.632, 0.591, 0.559, 0.597, 0.625, 0.739, 0.710, 0.729, 0.720, 0.636, 0.581, 0.428, 0.292, 0.162, 0.098, 0.054 }; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/estimation/EstimatedParameterTest.java100644 1750 1750 4126 11532241243 32037 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import org.apache.commons.math.estimation.EstimatedParameter; import org.apache.commons.math.util.FastMath; import junit.framework.*; @Deprecated public class EstimatedParameterTest extends TestCase { public EstimatedParameterTest(String name) { super(name); } public void testConstruction() { EstimatedParameter p1 = new EstimatedParameter("p1", 1.0); assertTrue(p1.getName().equals("p1")); checkValue(p1.getEstimate(), 1.0); assertTrue(! p1.isBound()); EstimatedParameter p2 = new EstimatedParameter("p2", 2.0, true); assertTrue(p2.getName().equals("p2")); checkValue(p2.getEstimate(), 2.0); assertTrue(p2.isBound()); } public void testBound() { EstimatedParameter p = new EstimatedParameter("p", 0.0); assertTrue(! p.isBound()); p.setBound(true); assertTrue(p.isBound()); p.setBound(false); assertTrue(! p.isBound()); } public void testEstimate() { EstimatedParameter p = new EstimatedParameter("p", 0.0); checkValue(p.getEstimate(), 0.0); for (double e = 0.0; e < 10.0; e += 0.5) { p.setEstimate(e); checkValue(p.getEstimate(), e); } } private void checkValue(double value, double expected) { assertTrue(FastMath.abs(value - expected) < 1.0e-10); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ConvergenceExceptionTest.java100644 1750 1750 6157 11532241244 30227 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import junit.framework.TestCase; import java.util.Locale; import org.apache.commons.math.exception.util.LocalizedFormats; /** * @version $Revision: 1035475 $ $Date: 2010-11-15 23:39:25 +0100 (lun. 15 nov. 2010) $ */ public class ConvergenceExceptionTest extends TestCase { public void testConstructor(){ ConvergenceException ex = new ConvergenceException(); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertNotNull(ex.getMessage(Locale.FRENCH)); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorPatternArguments(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; ConvergenceException ex = new ConvergenceException(pattern, arguments); assertNull(ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorCause(){ String inMsg = "inner message"; Exception cause = new Exception(inMsg); ConvergenceException ex = new ConvergenceException(cause); assertEquals(cause, ex.getCause()); } public void testConstructorPatternArgumentsCause(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; String inMsg = "inner message"; Exception cause = new Exception(inMsg); ConvergenceException ex = new ConvergenceException(cause, pattern, arguments); assertEquals(cause, ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/ValueServerTest.java100644 1750 1750 15206 11532241241 27645 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.EOFException; import java.net.URL; import org.apache.commons.math.RetryTestCase; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Test cases for the ValueServer class. * * @version $Revision: 1003907 $ $Date: 2010-10-03 00:23:34 +0200 (dim. 03 oct. 2010) $ */ public final class ValueServerTest extends RetryTestCase { private ValueServer vs = new ValueServer(); public ValueServerTest(String name) { super(name); } @Override public void setUp() { vs.setMode(ValueServer.DIGEST_MODE); URL url = getClass().getResource("testData.txt"); vs.setValuesFileURL(url); } /** * Generate 1000 random values and make sure they look OK.
        * Note that there is a non-zero (but very small) probability that * these tests will fail even if the code is working as designed. */ public void testNextDigest() throws Exception{ double next = 0.0; double tolerance = 0.1; vs.computeDistribution(); assertTrue("empirical distribution property", vs.getEmpiricalDistribution() != null); SummaryStatistics stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { next = vs.getNext(); stats.addValue(next); } assertEquals("mean", 5.069831575018909, stats.getMean(), tolerance); assertEquals ("std dev", 1.0173699343977738, stats.getStandardDeviation(), tolerance); vs.computeDistribution(500); stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { next = vs.getNext(); stats.addValue(next); } assertEquals("mean", 5.069831575018909, stats.getMean(), tolerance); assertEquals ("std dev", 1.0173699343977738, stats.getStandardDeviation(), tolerance); } /** * Make sure exception thrown if digest getNext is attempted * before loading empiricalDistribution. */ public void testNextDigestFail() throws Exception { try { vs.getNext(); fail("Expecting IllegalStateException"); } catch (IllegalStateException ex) {} } public void testEmptyReplayFile() throws Exception { try { URL url = getClass().getResource("emptyFile.txt"); vs.setMode(ValueServer.REPLAY_MODE); vs.setValuesFileURL(url); vs.getNext(); fail("an exception should have been thrown"); } catch (EOFException eof) { // expected behavior } } public void testEmptyDigestFile() throws Exception { try { URL url = getClass().getResource("emptyFile.txt"); vs.setMode(ValueServer.DIGEST_MODE); vs.setValuesFileURL(url); vs.computeDistribution(); fail("an exception should have been thrown"); } catch (EOFException eof) { // expected behavior } } /** * Test ValueServer REPLAY_MODE using values in testData file.
        * Check that the values 1,2,1001,1002 match data file values 1 and 2. * the sample data file. */ public void testReplay() throws Exception { double firstDataValue = 4.038625496201205; double secondDataValue = 3.6485326248346936; double tolerance = 10E-15; double compareValue = 0.0d; vs.setMode(ValueServer.REPLAY_MODE); vs.resetReplayFile(); compareValue = vs.getNext(); assertEquals(compareValue,firstDataValue,tolerance); compareValue = vs.getNext(); assertEquals(compareValue,secondDataValue,tolerance); for (int i = 3; i < 1001; i++) { compareValue = vs.getNext(); } compareValue = vs.getNext(); assertEquals(compareValue,firstDataValue,tolerance); compareValue = vs.getNext(); assertEquals(compareValue,secondDataValue,tolerance); vs.closeReplayFile(); // make sure no NPE vs.closeReplayFile(); } /** * Test other ValueServer modes */ public void testModes() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); vs.setMu(0); assertEquals("constant mode test",vs.getMu(),vs.getNext(),Double.MIN_VALUE); vs.setMode(ValueServer.UNIFORM_MODE); vs.setMu(2); double val = vs.getNext(); assertTrue(val > 0 && val < 4); vs.setSigma(1); vs.setMode(ValueServer.GAUSSIAN_MODE); val = vs.getNext(); assertTrue("gaussian value close enough to mean", val < vs.getMu() + 100*vs.getSigma()); vs.setMode(ValueServer.EXPONENTIAL_MODE); val = vs.getNext(); assertTrue(val > 0); try { vs.setMode(1000); vs.getNext(); fail("bad mode, expecting IllegalStateException"); } catch (IllegalStateException ex) { // ignored } } /** * Test fill */ public void testFill() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); vs.setMu(2); double[] val = new double[5]; vs.fill(val); for (int i = 0; i < 5; i++) { assertEquals("fill test in place",2,val[i],Double.MIN_VALUE); } double v2[] = vs.fill(3); for (int i = 0; i < 3; i++) { assertEquals("fill test in place",2,v2[i],Double.MIN_VALUE); } } /** * Test getters to make Clover happy */ public void testProperties() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); assertEquals("mode test",ValueServer.CONSTANT_MODE,vs.getMode()); vs.setValuesFileURL("http://www.apache.org"); URL url = vs.getValuesFileURL(); assertEquals("valuesFileURL test","http://www.apache.org",url.toString()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/MersenneTwisterTest.java100644 1750 1750 101324 11532241241 30555 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class MersenneTwisterTest { @Test public void testGaussian() { MersenneTwister mt = new MersenneTwister(42853252100l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 1000; ++i) { sample.addValue(mt.nextGaussian()); } assertEquals(0.0, sample.getMean(), 0.005); assertEquals(1.0, sample.getStandardDeviation(), 0.025); } @Test public void testDouble() { MersenneTwister mt = new MersenneTwister(195357343514l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 1000; ++i) { sample.addValue(mt.nextDouble()); } assertEquals(0.5, sample.getMean(), 0.02); assertEquals(1.0 / (2.0 * FastMath.sqrt(3.0)), sample.getStandardDeviation(), 0.002); } @Test public void testFloat() { MersenneTwister mt = new MersenneTwister(4442733263l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 1000; ++i) { sample.addValue(mt.nextFloat()); } assertEquals(0.5, sample.getMean(), 0.01); assertEquals(1.0 / (2.0 * FastMath.sqrt(3.0)), sample.getStandardDeviation(), 0.006); } @Test(expected=java.lang.IllegalArgumentException.class) public void testNextIntNeg() { new MersenneTwister(1).nextInt(-1); } @Test public void testNextIntN() { MersenneTwister mt = new MersenneTwister(0x12b8a7412bb25el); for (int n = 1; n < 20; ++n) { int[] count = new int[n]; for (int k = 0; k < 10000; ++k) { int l = mt.nextInt(n); ++count[l]; assertTrue(l >= 0); assertTrue(l < n); } for (int i = 0; i < n; ++i) { assertTrue(n * count[i] > 8600); assertTrue(n * count[i] < 11200); } } } @Test public void testNextInt() { MersenneTwister mt = new MersenneTwister(new int[] { 1, 2, 3, 4, 5 }); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextInt() >= 0) { ++walk; } else { --walk; } } assertTrue(FastMath.abs(walk) < 120); } @Test public void testNextLong() { MersenneTwister mt = new MersenneTwister(12345); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextLong() >= 0) { ++walk; } else { --walk; } } assertTrue(FastMath.abs(walk) < 50); } @Test public void testNexBoolean() { MersenneTwister mt = new MersenneTwister(76342); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextBoolean()) { ++walk; } else { --walk; } } assertTrue(FastMath.abs(walk) < 250); } @Test public void testNexBytes() { MersenneTwister mt = new MersenneTwister(0); int[] count = new int[256]; byte[] bytes = new byte[10]; for (int k = 0; k < 100000; ++k) { mt.nextBytes(bytes); for (byte b : bytes) { ++count[b + 128]; } } int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int c : count) { min = FastMath.min(min, c); max = FastMath.max(max, c); } int expected = (100000 * bytes.length) / count.length; assertTrue((expected - 200) < min); assertTrue(max < (expected + 200)); } @Test public void testMakotoNishimura() { MersenneTwister mt = new MersenneTwister(new int[] {0x123, 0x234, 0x345, 0x456}); long[] refInt = { 1067595299l, 955945823l, 477289528l, 4107218783l, 4228976476l, 3344332714l, 3355579695l, 227628506l, 810200273l, 2591290167l, 2560260675l, 3242736208l, 646746669l, 1479517882l, 4245472273l, 1143372638l, 3863670494l, 3221021970l, 1773610557l, 1138697238l, 1421897700l, 1269916527l, 2859934041l, 1764463362l, 3874892047l, 3965319921l, 72549643l, 2383988930l, 2600218693l, 3237492380l, 2792901476l, 725331109l, 605841842l, 271258942l, 715137098l, 3297999536l, 1322965544l, 4229579109l, 1395091102l, 3735697720l, 2101727825l, 3730287744l, 2950434330l, 1661921839l, 2895579582l, 2370511479l, 1004092106l, 2247096681l, 2111242379l, 3237345263l, 4082424759l, 219785033l, 2454039889l, 3709582971l, 835606218l, 2411949883l, 2735205030l, 756421180l, 2175209704l, 1873865952l, 2762534237l, 4161807854l, 3351099340l, 181129879l, 3269891896l, 776029799l, 2218161979l, 3001745796l, 1866825872l, 2133627728l, 34862734l, 1191934573l, 3102311354l, 2916517763l, 1012402762l, 2184831317l, 4257399449l, 2899497138l, 3818095062l, 3030756734l, 1282161629l, 420003642l, 2326421477l, 2741455717l, 1278020671l, 3744179621l, 271777016l, 2626330018l, 2560563991l, 3055977700l, 4233527566l, 1228397661l, 3595579322l, 1077915006l, 2395931898l, 1851927286l, 3013683506l, 1999971931l, 3006888962l, 1049781534l, 1488758959l, 3491776230l, 104418065l, 2448267297l, 3075614115l, 3872332600l, 891912190l, 3936547759l, 2269180963l, 2633455084l, 1047636807l, 2604612377l, 2709305729l, 1952216715l, 207593580l, 2849898034l, 670771757l, 2210471108l, 467711165l, 263046873l, 3569667915l, 1042291111l, 3863517079l, 1464270005l, 2758321352l, 3790799816l, 2301278724l, 3106281430l, 7974801l, 2792461636l, 555991332l, 621766759l, 1322453093l, 853629228l, 686962251l, 1455120532l, 957753161l, 1802033300l, 1021534190l, 3486047311l, 1902128914l, 3701138056l, 4176424663l, 1795608698l, 560858864l, 3737752754l, 3141170998l, 1553553385l, 3367807274l, 711546358l, 2475125503l, 262969859l, 251416325l, 2980076994l, 1806565895l, 969527843l, 3529327173l, 2736343040l, 2987196734l, 1649016367l, 2206175811l, 3048174801l, 3662503553l, 3138851612l, 2660143804l, 1663017612l, 1816683231l, 411916003l, 3887461314l, 2347044079l, 1015311755l, 1203592432l, 2170947766l, 2569420716l, 813872093l, 1105387678l, 1431142475l, 220570551l, 4243632715l, 4179591855l, 2607469131l, 3090613241l, 282341803l, 1734241730l, 1391822177l, 1001254810l, 827927915l, 1886687171l, 3935097347l, 2631788714l, 3905163266l, 110554195l, 2447955646l, 3717202975l, 3304793075l, 3739614479l, 3059127468l, 953919171l, 2590123714l, 1132511021l, 3795593679l, 2788030429l, 982155079l, 3472349556l, 859942552l, 2681007391l, 2299624053l, 647443547l, 233600422l, 608168955l, 3689327453l, 1849778220l, 1608438222l, 3968158357l, 2692977776l, 2851872572l, 246750393l, 3582818628l, 3329652309l, 4036366910l, 1012970930l, 950780808l, 3959768744l, 2538550045l, 191422718l, 2658142375l, 3276369011l, 2927737484l, 1234200027l, 1920815603l, 3536074689l, 1535612501l, 2184142071l, 3276955054l, 428488088l, 2378411984l, 4059769550l, 3913744741l, 2732139246l, 64369859l, 3755670074l, 842839565l, 2819894466l, 2414718973l, 1010060670l, 1839715346l, 2410311136l, 152774329l, 3485009480l, 4102101512l, 2852724304l, 879944024l, 1785007662l, 2748284463l, 1354768064l, 3267784736l, 2269127717l, 3001240761l, 3179796763l, 895723219l, 865924942l, 4291570937l, 89355264l, 1471026971l, 4114180745l, 3201939751l, 2867476999l, 2460866060l, 3603874571l, 2238880432l, 3308416168l, 2072246611l, 2755653839l, 3773737248l, 1709066580l, 4282731467l, 2746170170l, 2832568330l, 433439009l, 3175778732l, 26248366l, 2551382801l, 183214346l, 3893339516l, 1928168445l, 1337157619l, 3429096554l, 3275170900l, 1782047316l, 4264403756l, 1876594403l, 4289659572l, 3223834894l, 1728705513l, 4068244734l, 2867840287l, 1147798696l, 302879820l, 1730407747l, 1923824407l, 1180597908l, 1569786639l, 198796327l, 560793173l, 2107345620l, 2705990316l, 3448772106l, 3678374155l, 758635715l, 884524671l, 486356516l, 1774865603l, 3881226226l, 2635213607l, 1181121587l, 1508809820l, 3178988241l, 1594193633l, 1235154121l, 326117244l, 2304031425l, 937054774l, 2687415945l, 3192389340l, 2003740439l, 1823766188l, 2759543402l, 10067710l, 1533252662l, 4132494984l, 82378136l, 420615890l, 3467563163l, 541562091l, 3535949864l, 2277319197l, 3330822853l, 3215654174l, 4113831979l, 4204996991l, 2162248333l, 3255093522l, 2219088909l, 2978279037l, 255818579l, 2859348628l, 3097280311l, 2569721123l, 1861951120l, 2907080079l, 2719467166l, 998319094l, 2521935127l, 2404125338l, 259456032l, 2086860995l, 1839848496l, 1893547357l, 2527997525l, 1489393124l, 2860855349l, 76448234l, 2264934035l, 744914583l, 2586791259l, 1385380501l, 66529922l, 1819103258l, 1899300332l, 2098173828l, 1793831094l, 276463159l, 360132945l, 4178212058l, 595015228l, 177071838l, 2800080290l, 1573557746l, 1548998935l, 378454223l, 1460534296l, 1116274283l, 3112385063l, 3709761796l, 827999348l, 3580042847l, 1913901014l, 614021289l, 4278528023l, 1905177404l, 45407939l, 3298183234l, 1184848810l, 3644926330l, 3923635459l, 1627046213l, 3677876759l, 969772772l, 1160524753l, 1522441192l, 452369933l, 1527502551l, 832490847l, 1003299676l, 1071381111l, 2891255476l, 973747308l, 4086897108l, 1847554542l, 3895651598l, 2227820339l, 1621250941l, 2881344691l, 3583565821l, 3510404498l, 849362119l, 862871471l, 797858058l, 2867774932l, 2821282612l, 3272403146l, 3997979905l, 209178708l, 1805135652l, 6783381l, 2823361423l, 792580494l, 4263749770l, 776439581l, 3798193823l, 2853444094l, 2729507474l, 1071873341l, 1329010206l, 1289336450l, 3327680758l, 2011491779l, 80157208l, 922428856l, 1158943220l, 1667230961l, 2461022820l, 2608845159l, 387516115l, 3345351910l, 1495629111l, 4098154157l, 3156649613l, 3525698599l, 4134908037l, 446713264l, 2137537399l, 3617403512l, 813966752l, 1157943946l, 3734692965l, 1680301658l, 3180398473l, 3509854711l, 2228114612l, 1008102291l, 486805123l, 863791847l, 3189125290l, 1050308116l, 3777341526l, 4291726501l, 844061465l, 1347461791l, 2826481581l, 745465012l, 2055805750l, 4260209475l, 2386693097l, 2980646741l, 447229436l, 2077782664l, 1232942813l, 4023002732l, 1399011509l, 3140569849l, 2579909222l, 3794857471l, 900758066l, 2887199683l, 1720257997l, 3367494931l, 2668921229l, 955539029l, 3818726432l, 1105704962l, 3889207255l, 2277369307l, 2746484505l, 1761846513l, 2413916784l, 2685127085l, 4240257943l, 1166726899l, 4215215715l, 3082092067l, 3960461946l, 1663304043l, 2087473241l, 4162589986l, 2507310778l, 1579665506l, 767234210l, 970676017l, 492207530l, 1441679602l, 1314785090l, 3262202570l, 3417091742l, 1561989210l, 3011406780l, 1146609202l, 3262321040l, 1374872171l, 1634688712l, 1280458888l, 2230023982l, 419323804l, 3262899800l, 39783310l, 1641619040l, 1700368658l, 2207946628l, 2571300939l, 2424079766l, 780290914l, 2715195096l, 3390957695l, 163151474l, 2309534542l, 1860018424l, 555755123l, 280320104l, 1604831083l, 2713022383l, 1728987441l, 3639955502l, 623065489l, 3828630947l, 4275479050l, 3516347383l, 2343951195l, 2430677756l, 635534992l, 3868699749l, 808442435l, 3070644069l, 4282166003l, 2093181383l, 2023555632l, 1568662086l, 3422372620l, 4134522350l, 3016979543l, 3259320234l, 2888030729l, 3185253876l, 4258779643l, 1267304371l, 1022517473l, 815943045l, 929020012l, 2995251018l, 3371283296l, 3608029049l, 2018485115l, 122123397l, 2810669150l, 1411365618l, 1238391329l, 1186786476l, 3155969091l, 2242941310l, 1765554882l, 279121160l, 4279838515l, 1641578514l, 3796324015l, 13351065l, 103516986l, 1609694427l, 551411743l, 2493771609l, 1316337047l, 3932650856l, 4189700203l, 463397996l, 2937735066l, 1855616529l, 2626847990l, 55091862l, 3823351211l, 753448970l, 4045045500l, 1274127772l, 1124182256l, 92039808l, 2126345552l, 425973257l, 386287896l, 2589870191l, 1987762798l, 4084826973l, 2172456685l, 3366583455l, 3602966653l, 2378803535l, 2901764433l, 3716929006l, 3710159000l, 2653449155l, 3469742630l, 3096444476l, 3932564653l, 2595257433l, 318974657l, 3146202484l, 853571438l, 144400272l, 3768408841l, 782634401l, 2161109003l, 570039522l, 1886241521l, 14249488l, 2230804228l, 1604941699l, 3928713335l, 3921942509l, 2155806892l, 134366254l, 430507376l, 1924011722l, 276713377l, 196481886l, 3614810992l, 1610021185l, 1785757066l, 851346168l, 3761148643l, 2918835642l, 3364422385l, 3012284466l, 3735958851l, 2643153892l, 3778608231l, 1164289832l, 205853021l, 2876112231l, 3503398282l, 3078397001l, 3472037921l, 1748894853l, 2740861475l, 316056182l, 1660426908l, 168885906l, 956005527l, 3984354789l, 566521563l, 1001109523l, 1216710575l, 2952284757l, 3834433081l, 3842608301l, 2467352408l, 3974441264l, 3256601745l, 1409353924l, 1329904859l, 2307560293l, 3125217879l, 3622920184l, 3832785684l, 3882365951l, 2308537115l, 2659155028l, 1450441945l, 3532257603l, 3186324194l, 1225603425l, 1124246549l, 175808705l, 3009142319l, 2796710159l, 3651990107l, 160762750l, 1902254979l, 1698648476l, 1134980669l, 497144426l, 3302689335l, 4057485630l, 3603530763l, 4087252587l, 427812652l, 286876201l, 823134128l, 1627554964l, 3745564327l, 2589226092l, 4202024494l, 62878473l, 3275585894l, 3987124064l, 2791777159l, 1916869511l, 2585861905l, 1375038919l, 1403421920l, 60249114l, 3811870450l, 3021498009l, 2612993202l, 528933105l, 2757361321l, 3341402964l, 2621861700l, 273128190l, 4015252178l, 3094781002l, 1621621288l, 2337611177l, 1796718448l, 1258965619l, 4241913140l, 2138560392l, 3022190223l, 4174180924l, 450094611l, 3274724580l, 617150026l, 2704660665l, 1469700689l, 1341616587l, 356715071l, 1188789960l, 2278869135l, 1766569160l, 2795896635l, 57824704l, 2893496380l, 1235723989l, 1630694347l, 3927960522l, 428891364l, 1814070806l, 2287999787l, 4125941184l, 3968103889l, 3548724050l, 1025597707l, 1404281500l, 2002212197l, 92429143l, 2313943944l, 2403086080l, 3006180634l, 3561981764l, 1671860914l, 1768520622l, 1803542985l, 844848113l, 3006139921l, 1410888995l, 1157749833l, 2125704913l, 1789979528l, 1799263423l, 741157179l, 2405862309l, 767040434l, 2655241390l, 3663420179l, 2172009096l, 2511931187l, 1680542666l, 231857466l, 1154981000l, 157168255l, 1454112128l, 3505872099l, 1929775046l, 2309422350l, 2143329496l, 2960716902l, 407610648l, 2938108129l, 2581749599l, 538837155l, 2342628867l, 430543915l, 740188568l, 1937713272l, 3315215132l, 2085587024l, 4030765687l, 766054429l, 3517641839l, 689721775l, 1294158986l, 1753287754l, 4202601348l, 1974852792l, 33459103l, 3568087535l, 3144677435l, 1686130825l, 4134943013l, 3005738435l, 3599293386l, 426570142l, 754104406l, 3660892564l, 1964545167l, 829466833l, 821587464l, 1746693036l, 1006492428l, 1595312919l, 1256599985l, 1024482560l, 1897312280l, 2902903201l, 691790057l, 1037515867l, 3176831208l, 1968401055l, 2173506824l, 1089055278l, 1748401123l, 2941380082l, 968412354l, 1818753861l, 2973200866l, 3875951774l, 1119354008l, 3988604139l, 1647155589l, 2232450826l, 3486058011l, 3655784043l, 3759258462l, 847163678l, 1082052057l, 989516446l, 2871541755l, 3196311070l, 3929963078l, 658187585l, 3664944641l, 2175149170l, 2203709147l, 2756014689l, 2456473919l, 3890267390l, 1293787864l, 2830347984l, 3059280931l, 4158802520l, 1561677400l, 2586570938l, 783570352l, 1355506163l, 31495586l, 3789437343l, 3340549429l, 2092501630l, 896419368l, 671715824l, 3530450081l, 3603554138l, 1055991716l, 3442308219l, 1499434728l, 3130288473l, 3639507000l, 17769680l, 2259741420l, 487032199l, 4227143402l, 3693771256l, 1880482820l, 3924810796l, 381462353l, 4017855991l, 2452034943l, 2736680833l, 2209866385l, 2128986379l, 437874044l, 595759426l, 641721026l, 1636065708l, 3899136933l, 629879088l, 3591174506l, 351984326l, 2638783544l, 2348444281l, 2341604660l, 2123933692l, 143443325l, 1525942256l, 364660499l, 599149312l, 939093251l, 1523003209l, 106601097l, 376589484l, 1346282236l, 1297387043l, 764598052l, 3741218111l, 933457002l, 1886424424l, 3219631016l, 525405256l, 3014235619l, 323149677l, 2038881721l, 4100129043l, 2851715101l, 2984028078l, 1888574695l, 2014194741l, 3515193880l, 4180573530l, 3461824363l, 2641995497l, 3179230245l, 2902294983l, 2217320456l, 4040852155l, 1784656905l, 3311906931l, 87498458l, 2752971818l, 2635474297l, 2831215366l, 3682231106l, 2920043893l, 3772929704l, 2816374944l, 309949752l, 2383758854l, 154870719l, 385111597l, 1191604312l, 1840700563l, 872191186l, 2925548701l, 1310412747l, 2102066999l, 1504727249l, 3574298750l, 1191230036l, 3330575266l, 3180292097l, 3539347721l, 681369118l, 3305125752l, 3648233597l, 950049240l, 4173257693l, 1760124957l, 512151405l, 681175196l, 580563018l, 1169662867l, 4015033554l, 2687781101l, 699691603l, 2673494188l, 1137221356l, 123599888l, 472658308l, 1053598179l, 1012713758l, 3481064843l, 3759461013l, 3981457956l, 3830587662l, 1877191791l, 3650996736l, 988064871l, 3515461600l, 4089077232l, 2225147448l, 1249609188l, 2643151863l, 3896204135l, 2416995901l, 1397735321l, 3460025646l }; double[] refDouble = { 0.76275443, 0.99000644, 0.98670464, 0.10143112, 0.27933125, 0.69867227, 0.94218740, 0.03427201, 0.78842173, 0.28180608, 0.92179002, 0.20785655, 0.54534773, 0.69644020, 0.38107718, 0.23978165, 0.65286910, 0.07514568, 0.22765211, 0.94872929, 0.74557914, 0.62664415, 0.54708246, 0.90959343, 0.42043116, 0.86334511, 0.19189126, 0.14718544, 0.70259889, 0.63426346, 0.77408121, 0.04531601, 0.04605807, 0.88595519, 0.69398270, 0.05377184, 0.61711170, 0.05565708, 0.10133577, 0.41500776, 0.91810699, 0.22320679, 0.23353705, 0.92871862, 0.98897234, 0.19786706, 0.80558809, 0.06961067, 0.55840445, 0.90479405, 0.63288060, 0.95009721, 0.54948447, 0.20645042, 0.45000959, 0.87050869, 0.70806991, 0.19406895, 0.79286390, 0.49332866, 0.78483914, 0.75145146, 0.12341941, 0.42030252, 0.16728160, 0.59906494, 0.37575460, 0.97815160, 0.39815952, 0.43595080, 0.04952478, 0.33917805, 0.76509902, 0.61034321, 0.90654701, 0.92915732, 0.85365931, 0.18812377, 0.65913428, 0.28814566, 0.59476081, 0.27835931, 0.60722542, 0.68310435, 0.69387186, 0.03699800, 0.65897714, 0.17527003, 0.02889304, 0.86777366, 0.12352068, 0.91439461, 0.32022990, 0.44445731, 0.34903686, 0.74639273, 0.65918367, 0.92492794, 0.31872642, 0.77749724, 0.85413832, 0.76385624, 0.32744211, 0.91326300, 0.27458185, 0.22190155, 0.19865383, 0.31227402, 0.85321225, 0.84243342, 0.78544200, 0.71854080, 0.92503892, 0.82703064, 0.88306297, 0.47284073, 0.70059042, 0.48003761, 0.38671694, 0.60465770, 0.41747204, 0.47163243, 0.72750808, 0.65830223, 0.10955369, 0.64215401, 0.23456345, 0.95944940, 0.72822249, 0.40888451, 0.69980355, 0.26677428, 0.57333635, 0.39791582, 0.85377858, 0.76962816, 0.72004885, 0.90903087, 0.51376506, 0.37732665, 0.12691640, 0.71249738, 0.81217908, 0.37037313, 0.32772374, 0.14238259, 0.05614811, 0.74363008, 0.39773267, 0.94859135, 0.31452454, 0.11730313, 0.62962618, 0.33334237, 0.45547255, 0.10089665, 0.56550662, 0.60539371, 0.16027624, 0.13245301, 0.60959939, 0.04671662, 0.99356286, 0.57660859, 0.40269560, 0.45274629, 0.06699735, 0.85064246, 0.87742744, 0.54508392, 0.87242982, 0.29321385, 0.67660627, 0.68230715, 0.79052073, 0.48592054, 0.25186266, 0.93769755, 0.28565487, 0.47219067, 0.99054882, 0.13155240, 0.47110470, 0.98556600, 0.84397623, 0.12875246, 0.90953202, 0.49129015, 0.23792727, 0.79481194, 0.44337770, 0.96564297, 0.67749118, 0.55684872, 0.27286897, 0.79538393, 0.61965356, 0.22487929, 0.02226018, 0.49248200, 0.42247006, 0.91797788, 0.99250134, 0.23449967, 0.52531508, 0.10246337, 0.78685622, 0.34310922, 0.89892996, 0.40454552, 0.68608407, 0.30752487, 0.83601319, 0.54956031, 0.63777550, 0.82199797, 0.24890696, 0.48801123, 0.48661910, 0.51223987, 0.32969635, 0.31075073, 0.21393155, 0.73453207, 0.15565705, 0.58584522, 0.28976728, 0.97621478, 0.61498701, 0.23891470, 0.28518540, 0.46809591, 0.18371914, 0.37597910, 0.13492176, 0.66849449, 0.82811466, 0.56240330, 0.37548956, 0.27562998, 0.27521910, 0.74096121, 0.77176757, 0.13748143, 0.99747138, 0.92504502, 0.09175241, 0.21389176, 0.21766512, 0.31183245, 0.23271221, 0.21207367, 0.57903312, 0.77523344, 0.13242613, 0.31037988, 0.01204835, 0.71652949, 0.84487594, 0.14982178, 0.57423142, 0.45677888, 0.48420169, 0.53465428, 0.52667473, 0.46880526, 0.49849733, 0.05670710, 0.79022476, 0.03872047, 0.21697212, 0.20443086, 0.28949326, 0.81678186, 0.87629474, 0.92297064, 0.27373097, 0.84625273, 0.51505586, 0.00582792, 0.33295971, 0.91848412, 0.92537226, 0.91760033, 0.07541125, 0.71745848, 0.61158698, 0.00941650, 0.03135554, 0.71527471, 0.24821915, 0.63636652, 0.86159918, 0.26450229, 0.60160194, 0.35557725, 0.24477500, 0.07186456, 0.51757096, 0.62120362, 0.97981062, 0.69954667, 0.21065616, 0.13382753, 0.27693186, 0.59644095, 0.71500764, 0.04110751, 0.95730081, 0.91600724, 0.47704678, 0.26183479, 0.34706971, 0.07545431, 0.29398385, 0.93236070, 0.60486023, 0.48015011, 0.08870451, 0.45548581, 0.91872718, 0.38142712, 0.10668643, 0.01397541, 0.04520355, 0.93822273, 0.18011940, 0.57577277, 0.91427606, 0.30911399, 0.95853475, 0.23611214, 0.69619891, 0.69601980, 0.76765372, 0.58515930, 0.49479057, 0.11288752, 0.97187699, 0.32095365, 0.57563608, 0.40760618, 0.78703383, 0.43261152, 0.90877651, 0.84686346, 0.10599030, 0.72872803, 0.19315490, 0.66152912, 0.10210518, 0.06257876, 0.47950688, 0.47062066, 0.72701157, 0.48915116, 0.66110261, 0.60170685, 0.24516994, 0.12726050, 0.03451185, 0.90864994, 0.83494878, 0.94800035, 0.91035206, 0.14480751, 0.88458997, 0.53498312, 0.15963215, 0.55378627, 0.35171349, 0.28719791, 0.09097957, 0.00667896, 0.32309622, 0.87561479, 0.42534520, 0.91748977, 0.73908457, 0.41793223, 0.99279792, 0.87908370, 0.28458072, 0.59132853, 0.98672190, 0.28547393, 0.09452165, 0.89910674, 0.53681109, 0.37931425, 0.62683489, 0.56609740, 0.24801549, 0.52948179, 0.98328855, 0.66403523, 0.55523786, 0.75886666, 0.84784685, 0.86829981, 0.71448906, 0.84670080, 0.43922919, 0.20771016, 0.64157936, 0.25664246, 0.73055695, 0.86395782, 0.65852932, 0.99061803, 0.40280575, 0.39146298, 0.07291005, 0.97200603, 0.20555729, 0.59616495, 0.08138254, 0.45796388, 0.33681125, 0.33989127, 0.18717090, 0.53545811, 0.60550838, 0.86520709, 0.34290701, 0.72743276, 0.73023855, 0.34195926, 0.65019733, 0.02765254, 0.72575740, 0.32709576, 0.03420866, 0.26061893, 0.56997511, 0.28439072, 0.84422744, 0.77637570, 0.55982168, 0.06720327, 0.58449067, 0.71657369, 0.15819609, 0.58042821, 0.07947911, 0.40193792, 0.11376012, 0.88762938, 0.67532159, 0.71223735, 0.27829114, 0.04806073, 0.21144026, 0.58830274, 0.04140071, 0.43215628, 0.12952729, 0.94668759, 0.87391019, 0.98382450, 0.27750768, 0.90849647, 0.90962737, 0.59269720, 0.96102026, 0.49544979, 0.32007095, 0.62585546, 0.03119821, 0.85953001, 0.22017528, 0.05834068, 0.80731217, 0.53799961, 0.74166948, 0.77426600, 0.43938444, 0.54862081, 0.58575513, 0.15886492, 0.73214332, 0.11649057, 0.77463977, 0.85788827, 0.17061997, 0.66838056, 0.96076133, 0.07949296, 0.68521946, 0.89986254, 0.05667410, 0.12741385, 0.83470977, 0.63969104, 0.46612929, 0.10200126, 0.01194925, 0.10476340, 0.90285217, 0.31221221, 0.32980614, 0.46041971, 0.52024973, 0.05425470, 0.28330912, 0.60426543, 0.00598243, 0.97244013, 0.21135841, 0.78561597, 0.78428734, 0.63422849, 0.32909934, 0.44771136, 0.27380750, 0.14966697, 0.18156268, 0.65686758, 0.28726350, 0.97074787, 0.63676171, 0.96649494, 0.24526295, 0.08297372, 0.54257548, 0.03166785, 0.33735355, 0.15946671, 0.02102971, 0.46228045, 0.11892296, 0.33408336, 0.29875681, 0.29847692, 0.73767569, 0.02080745, 0.62980060, 0.08082293, 0.22993106, 0.25031439, 0.87787525, 0.45150053, 0.13673441, 0.63407612, 0.97907688, 0.52241942, 0.50580158, 0.06273902, 0.05270283, 0.77031811, 0.05113352, 0.24393329, 0.75036441, 0.37436336, 0.22877652, 0.59975358, 0.85707591, 0.88691457, 0.85547165, 0.36641027, 0.58720133, 0.45462835, 0.09243817, 0.32981586, 0.07820411, 0.25421519, 0.36004706, 0.60092307, 0.46192412, 0.36758683, 0.98424170, 0.08019934, 0.68594024, 0.45826386, 0.29962317, 0.79365413, 0.89231296, 0.49478547, 0.87645944, 0.23590734, 0.28106737, 0.75026285, 0.08136314, 0.79582424, 0.76010628, 0.82792971, 0.27947652, 0.72482861, 0.82191216, 0.46171689, 0.79189752, 0.96043686, 0.51609668, 0.88995725, 0.28998963, 0.55191845, 0.03934737, 0.83033700, 0.49553013, 0.98009549, 0.19017594, 0.98347750, 0.33452066, 0.87144372, 0.72106301, 0.71272114, 0.71465963, 0.88361677, 0.85571283, 0.73782329, 0.20920458, 0.34855153, 0.46766817, 0.02780062, 0.74898344, 0.03680650, 0.44866557, 0.77426312, 0.91025891, 0.25195236, 0.87319953, 0.63265037, 0.25552148, 0.27422476, 0.95217406, 0.39281839, 0.66441573, 0.09158900, 0.94515992, 0.07800798, 0.02507888, 0.39901462, 0.17382573, 0.12141278, 0.85502334, 0.19902911, 0.02160210, 0.44460522, 0.14688742, 0.68020336, 0.71323733, 0.60922473, 0.95400380, 0.99611159, 0.90897777, 0.41073520, 0.66206647, 0.32064685, 0.62805003, 0.50677209, 0.52690101, 0.87473387, 0.73918362, 0.39826974, 0.43683919, 0.80459118, 0.32422684, 0.01958019, 0.95319576, 0.98326137, 0.83931735, 0.69060863, 0.33671416, 0.68062550, 0.65152380, 0.33392969, 0.03451730, 0.95227244, 0.68200635, 0.85074171, 0.64721009, 0.51234433, 0.73402047, 0.00969637, 0.93835057, 0.80803854, 0.31485260, 0.20089527, 0.01323282, 0.59933780, 0.31584602, 0.20209563, 0.33754800, 0.68604181, 0.24443049, 0.19952227, 0.78162632, 0.10336988, 0.11360736, 0.23536740, 0.23262256, 0.67803776, 0.48749791, 0.74658435, 0.92156640, 0.56706407, 0.36683221, 0.99157136, 0.23421374, 0.45183767, 0.91609720, 0.85573315, 0.37706276, 0.77042618, 0.30891908, 0.40709595, 0.06944866, 0.61342849, 0.88817388, 0.58734506, 0.98711323, 0.14744128, 0.63242656, 0.87704136, 0.68347125, 0.84446569, 0.43265239, 0.25146321, 0.04130111, 0.34259839, 0.92697368, 0.40878778, 0.56990338, 0.76204273, 0.19820348, 0.66314909, 0.02482844, 0.06669207, 0.50205581, 0.26084093, 0.65139159, 0.41650223, 0.09733904, 0.56344203, 0.62651696, 0.67332139, 0.58037374, 0.47258086, 0.21010758, 0.05713135, 0.89390629, 0.10781246, 0.32037450, 0.07628388, 0.34227964, 0.42190597, 0.58201860, 0.77363549, 0.49595133, 0.86031236, 0.83906769, 0.81098161, 0.26694195, 0.14215941, 0.88210306, 0.53634237, 0.12090720, 0.82480459, 0.75930318, 0.31847147, 0.92768077, 0.01037616, 0.56201727, 0.88107122, 0.35925856, 0.85860762, 0.61109408, 0.70408301, 0.58434977, 0.92192494, 0.62667915, 0.75988365, 0.06858761, 0.36156496, 0.58057195, 0.13636150, 0.57719713, 0.59340255, 0.63530602, 0.22976282, 0.71915530, 0.41162531, 0.63979565, 0.09931342, 0.79344045, 0.10893790, 0.84450224, 0.23122236, 0.99485593, 0.73637397, 0.17276368, 0.13357764, 0.74965804, 0.64991737, 0.61990341, 0.41523170, 0.05878239, 0.05687301, 0.05497131, 0.42868366, 0.42571090, 0.25810502, 0.89642955, 0.30439758, 0.39310223, 0.11357431, 0.04288255, 0.23397550, 0.11200634, 0.85621396, 0.89733974, 0.37508865, 0.42077265, 0.68597384, 0.72781399, 0.19296476, 0.61699087, 0.31667128, 0.67756410, 0.00177323, 0.05725176, 0.79474693, 0.18885238, 0.06724856, 0.68193156, 0.42202167, 0.22082041, 0.28554673, 0.64995708, 0.87851940, 0.29124547, 0.61009521, 0.87374537, 0.05743712, 0.69902994, 0.81925115, 0.45653873, 0.37236821, 0.31118709, 0.52734307, 0.39672836, 0.38185294, 0.30163915, 0.17374510, 0.04913278, 0.90404879, 0.25742801, 0.58266467, 0.97663209, 0.79823377, 0.36437958, 0.15206043, 0.26529938, 0.22690047, 0.05839021, 0.84721160, 0.18622435, 0.37809403, 0.55706977, 0.49828704, 0.47659049, 0.24289680, 0.88477595, 0.07807463, 0.56245739, 0.73490635, 0.21099431, 0.13164942, 0.75840044, 0.66877037, 0.28988183, 0.44046090, 0.24967434, 0.80048356, 0.26029740, 0.30416821, 0.64151867, 0.52067892, 0.12880774, 0.85465381, 0.02690525, 0.19149288, 0.49630295, 0.79682619, 0.43566145, 0.00288078, 0.81484193, 0.03763639, 0.68529083, 0.01339574, 0.38405386, 0.30537067, 0.22994703, 0.44000045, 0.27217985, 0.53831243, 0.02870435, 0.86282045, 0.61831306, 0.09164956, 0.25609707, 0.07445781, 0.72185784, 0.90058883, 0.30070608, 0.94476583, 0.56822213, 0.21933909, 0.96772793, 0.80063440, 0.26307906, 0.31183306, 0.16501252, 0.55436179, 0.68562285, 0.23829083, 0.86511559, 0.57868991, 0.81888344, 0.20126869, 0.93172350, 0.66028129, 0.21786948, 0.78515828, 0.10262106, 0.35390326, 0.79303876, 0.63427924, 0.90479631, 0.31024934, 0.60635447, 0.56198079, 0.63573813, 0.91854197, 0.99701497, 0.83085849, 0.31692291, 0.01925964, 0.97446405, 0.98751283, 0.60944293, 0.13751018, 0.69519957, 0.68956636, 0.56969015, 0.46440193, 0.88341765, 0.36754434, 0.89223647, 0.39786427, 0.85055280, 0.12749961, 0.79452122, 0.89449784, 0.14567830, 0.45716830, 0.74822309, 0.28200437, 0.42546044, 0.17464886, 0.68308746, 0.65496587, 0.52935411, 0.12736159, 0.61523955, 0.81590528, 0.63107864, 0.39786553, 0.20102294, 0.53292914, 0.75485590, 0.59847044, 0.32861691, 0.12125866, 0.58917183, 0.07638293, 0.86845380, 0.29192617, 0.03989733, 0.52180460, 0.32503407, 0.64071852, 0.69516575, 0.74254998, 0.54587026, 0.48713246, 0.32920155, 0.08719954, 0.63497059, 0.54328459, 0.64178757, 0.45583809, 0.70694291, 0.85212760, 0.86074305, 0.33163422, 0.85739792, 0.59908488, 0.74566046, 0.72157152 }; for (int i = 0; i < refInt.length; ++i) { int r = mt.nextInt(); assertEquals(refInt[i], (r & 0x7fffffffl) | ((r < 0) ? 0x80000000l : 0x0l)); } for (int i = 0; i < refDouble.length; ++i) { int r = mt.nextInt(); assertEquals(refDouble[i], ((r & 0x7fffffffl) | ((r < 0) ? 0x80000000l : 0x0l)) / 4294967296.0, 1.0e-8); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well19937aTest.java100644 1750 1750 40636 11532241241 27070 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.junit.Test; public class Well19937aTest { @Test public void testReferenceCode() { int[] base = { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000, -595495729, 1047766204, 1875773301, -1637793284, 1379017098, 262792705, 191880010, -251000180, -1753047622, -972355720, 90626881, 1644693418, 1503365577, 439653419, 1806361562, 1268823869 }; int[] init = new int[624]; for (int i = 0; i < init.length; ++i) { init[i] = base[i % base.length] + i; } Well19937a mt = new Well19937a(init); int[] refInt = { -612874471, -354976292, -1838197125, -1781560577, 278390997, 1214938280, -1752615390, -760835246, -1712883765, -241205782, -145390202, 495649160, -514388259, -1271015916, -1640000013, 849273623, -549729394, -1206917255, -545909692, 811925434, -1665729633, -1525292882, 1416246482, -153220826, 1148868872, -326143196, 1724979062, 1790931148, -1648679618, -439051683, 112482777, -1484051520, -1881272572, -1270447031, -1216102401, 1579107248, -1224395621, 2144411988, -416216641, -1529222361, 1628987080, 164445245, 1506928916, 928145916, 1436000427, 862025970, 560077705, -1887251027, -514360858, 1735094506, 475624879, 1755802355, 295448361, -155399225, 3972415, 1368201076, -465126094, -1622687259, -246099304, 1798631152, -1937269102, -1700560396, -293352622, -896632303, -2088933220, -194382452, -480218162, -1618517785, -1925031481, -150217434, 1678937261, 2130832364, -485546678, -1499224981, 1430390884, -1895417302, 210514746, 1781140999, -1940853105, -1238099647, 485922557, -103223212, 633481679, -632946979, 695235541, -1661735272, 277603567, -958341538, 256982285, 1850270018, -327388076, -219053874, 1380560653, -1221689980, 1335863752, -545032383, -575291735, -1295623907, -140058298, 1063302709, -1290702617, -790401546, -170630961, -1203114473, 1458063108, -1212753301, 1546428514, 2112636413, -1463028928, -1812598032, -883529486, 1131084094, 62042165, 2135819802, -1192342739, 98361522, -1341042205, -475283063, -1632033747, 1745196892, 168608689, -914987039, 274428907, -881357258, 167940012, -1975737532, -903960486, -1370984244, -589352935, 1783633514, -570111010, 71495377, 194463285, -1243905021, -1398490898, 221691209, -55728834, -638916786, -770622372, -1911651810, -295233027, 301467998, 2058638784, 681490183, -1547865078, -1668135684, 1299261826, 1649468635, 287995017, -2076844852, 1193468826, -853948258, 120082777, 1051829542, -1288514343, -159456430, 275748820, -480127107, -604943233, -2138088332, 1202614819, 1427201263, -1906344469, -1230779533, 1690367192, 733159097, 794410312, -1114452505, -1601554413, 976747949, 1517787154, 2091780205, 1052078906, 1919282771, -191013374, 1805397142, 736939268, -1056272823, -727464316, -659459005, 797803875, -1104633884, 1042342081, -24514837, 1919469940, 1903722546, -814157872, 1605407665, -262351256, -288949635, 729204844, -1132605534, 745453338, 387915035, 1094173337, 2100279147, 156863702, -257377544, -719587984, -1496015613, 1908993744, 2016957554, 918749666, -135963651, -1356808639, -1711185741, 1472589240, -398100149, 628791415, -1381837652, -1820702771, -593586943, -1456631279, -1837975351, -1394249972, -556916726, 833231177, 43449750, 1029237092, -2086437337, -459463076, -533031784, -1739648287, -1374722961, 2024908394, 1389678488, 2018558, -1391707864, -795935743, 904816957, 836583280, 1766194531, -1374431014, -904437876, 2030248636, -265724199, 2056758426, -810499837, 887193593, -77811488, 1496312336, -1874348275, -456193866, -2137130942, 868120387, 29025455, -1999867716, 2001322335, -579152815, -390892056, 1592011837, -306394879, 93636886, -190879994, 1923358153, 269052141, -396050253, -987531729, 480350991, 1276744541, -1445571957, -957571005, -2046270221, -1715395752, 1113585628, -1782113514, -697560146, 835320000, 1014320959, -2119834109, 460056841, -1464772991, -1282790418, -2120806165, 86176097, -731086307, 832497517, -1876684928, 541008240, 551124479, -450919132, 647860281, -2115397586, 979247589, 1095559204, 1927958688, 169497703, 1999579054, 2019745038, 1656022059, -1109662138, 375237154, 1450814436, 919988416, 849761266, 1457057327, 1771166577, -1639880487, -852488298, 1767063646, 657295386, -585561879, 740792583, 1664558308, -654749506, 1109275990, 182597559, 1106789745, -1806628480, 25948116, 1748374299, 196057325, -164213209, 1687024594, 782029276, 1879737947, -1528219611, 412585737, 1190325629, 1985821911, -1272945202, -1238637137, 465818730, -1537670961, 1131953615, 905623579, 609183424, 1138422991, 1522974699, 589719061, -1310894604, 890952933, -885204790, -393535694, 1238408670, 1780660354, 677803525, -1121509064, 1553148616, 1109165936, -1450120385, 1525252521, -1354897489, -595402189, -1274551767, -869281409, 1788815975, 2020262116, 1124100185, -400839020, 310574108, 1354413045, -1310514485, 1895732085, 626639054, 1667355357, 2065637178, -1889009143, -440157749, 1762849463, -1693853642, -56602956, -930874188, -398470740, 778356402, -2113156881, 42854964, 1844399604, -2098310302, -1812029757, 1441188713, 899579267, 1266994172, 1841370863, -660740252, -43254718, 1124500192, 1884907320, 879997211, 1775139845, -1360112721, 1630490057, 362567879, 1113475029, 290319279, -1209506867, 398146039, -957742350, 1185761854, 1519676447, -912689915, -1117128973, -305563462, -1928033363, -1766324543, 1702753492, 1696951912, -1895072395, 932663591, -566548128, 991675996, 56529814, 980735023, 718166662, -650028466, -886842051, 1857048587, -569023569, -1820572202, -851452711, -958700452, -621825633, -65649888, -510143183, 761267599, -1692108035, 1729071710, 1623630864, -53498654, 267235687, 659201413, 1152882627, -824194574, 356636960, -502391121, -538453360, 66115376, -1633290370, -1522088932, 268949070, 684499443, -859474501, 1586764345, -1515639709, 319695602, -307025150, 69076508, 1050726785, -1340930110, 552191600, -207852941, -273572993, -539580440, 710343120, 1957076127, -1107172811, -561518280, -1775022699, 1978792904, 1935531451, -2084046304, -419742902, -737652926, 614022023, 1676952428, 769892939, -1092786807, -1117113223, -266029995, -350150999, 207738542, 1964896575, 48805284, 1736500159, 551289617, -1847923501, 1856609505, 2007480480, -681860219, -1198106493, 1483591043, -523895316, -1814473078, -1521087404, -1348859926, 1298056897, 1813789478, 946683654, 79196400, 1766250931, 472737685, 1764634332, -1844726079, -130619045, -508713868, -1762537125, 1010108863, 170107098, 1705386380, -1139681802, 183739097, 1662699401, 1842694501, 1714633805, 46208876, 616720693, -252553427, 1986302230, -103130254, 1943225981, 110746655, 553260552, 1588938073, -1934623163, -2144781332, -2086217416, 1941265852, -781953226, 1216234254, 605543697, -710872598, 2048636577, -1986927728, -1007017623, 1243051501, -614249563, -2128221291, 581579813, 1173464240, -1906830937, 261329601, -1805974103, 769823490, 1858731164, -561762071, 516417430, -1221329437, -825500715, 1091364656, -993658663, -1475434188, -1070804384, -1876492082, 899494424, 683486936, 878807455, 56642807, -1268202879, 1379172046, -1386869373, -1158233876, 1759190552, 1597629789, 1411151497, -1254268471, 1075936979, -918778269, -2132675184, 953140888, 1906982077, 1154200766, -365384600, -1142488826, 708535121, -2134869964, -1531201665, -2100526761, 1268256467, 2071480803, 193135243, 1374158182, 989505347, -933612202, -2134839213, -1302795271, -2092029041, 1812014826, 2090855917, 2005348528, 606434393, -60141386, 11156360, 539516285, -122485034, -893237911, -978127424, 1509901816, -451029719, 428544700, -1622965963, -1993611605, -1989324583, 1104111587, -795138585, -899552401, -2110167769, -234502445, 1586963605, -503778455, 529261062, 325327284, -106186403, 65369563, -1475700698, -228624261, 715975009, 1099352363, -1796883396, 1376542700, -308942420, -344940451, -395389249, -1562737166, 1869802677, 1273494710, 2075587668, -789570273, 1563347596, 1142901755, 1676422422, -1729157809, -1399423717, -1814262429, -1809707284, 1393992342, -570246212, 1065528749, -781643849, 1218667301, -1097949471, 1305629790, 901301039, -704762030, 360582612, 1411910672, 1848068741, -614500891, -146889637, -913903597, 723527277, -147033328, -199273155, 734997691, -2072735286, 2129258691, -1385074104, 931616624, 1065477319, -1543474555, -531410292, -2123119121, -1538464113, -1153585193, 1559931968, -654877011, 879865200, 1489681397, 1998864644, -1964160144, 163671782, -858364148, -323324233, 801208648, 705864113, 436184243, 643773864, 2087594507, 134637265, -749956494, -1657343972, -1828172168, -27357303, -1145161336, -1192513644, 216148260, 611393153, -13752671, -358631090, -1211920749, 593572064, 657629904, -1445961088, -250704995, 1797542707, -2122311891, -316774825, -296303057, -868002056, -86697533, 2020588145, 1203427903, -1371839056, 669531557, -2031033836, 1323994690, 13703036, 785437772, -1465821554, -694756014, -2131068154, -1745448876, -1095891733, 936594025, -1119068454, 855423970, 1705079340, -905640608, 162297141, 1336619311, -344353769, -92608588, -1080573824, 2002293105, -2088030765, -1684198727, -129054718, -949437132, -127983221, -216664110, 1700146143, -711174649, 1500113839, 1212236226, -2017364219, -1263597675, 511929344, -323998524, -2021313185, 1803000924, 927670608, 336267187, 1244256964, -1665390108, 991395134, -251232188, 1267445783, 1547951569, 740269916, 1776431169, 1687220659, 228229817, 271386089, -682906779, -438090344, 1190436796, -744272540, 1879221151, 1145200306, -1730983338, -1119209309, 90826726, 1567861540, 1638852830, -1645384932, 1566909531, 1088584561, 1030555565, -1872052014, 720320695, -885053674, -321216789, 739907579, 368580703, -443635520, 1232705619, -1355949988, -1047211249, -1571429448, 599299852, 1036970439, 1513838571, -51797291, -26647565, -1262878942, -916262582, 1579082269, -292007383, 1289013866, -1612184284, 1451738668, 448608569, 476432992, -1229609565, 786372409, 929928149, -150100614, 448155944, -1322320576, -856549627, 1057443268, -1536809554, 577508258, 584906122, 275295163, -604262071, -236043234, -1866434954, -2072447013, 646132876, 847562546, -310005953, -1104162658, 393261203, -730102354, 440824482, 1654535035, -1296359745, 1487359328, -977776604, -775827779, -1298695106, 519080622, 1697162240, 227873031, -371123123, 1273702312, -1710063656, -2138342344, 1139555478, 1531578907, -1498880699, 1183507362, 1875307493, -1649740413, 2135386504, -962458407, 424161768, 504272962, 202204247, 1783466420, 2015579232, -676642965, 2067456450, 914480415, -620398841, 1880405399, 1406637142, 1951104977, 633496157, 224861869, -58659291, 994942775, -479000645, 1421449115, 100168104, 249754169, -1219011494, 1736303638, 364013694, -1750035055, -479217141, 1652913106, -2109452331, 1633842910, -1547663337, 936627493, -1152799743, 896955899, -1407742850, -523769014, 357161414, 872293304, 744895980, 720829676, -240843156, -111779524, 1292836315, -1792141538, 1946959925, 1181751089, -1120674052, 1185192575, -1387002557, 1973209255, -120887476, -766577735, -443913073, 786620227, 428564781, -101232106, -425959852, 198082021, 1173272226, -1744840378, -1621135606, -1539498583, -1101274572, 43399711, -1256764602, 1201920787, 2049426139, 846545551, -2121520873, -1202939675, -470425740, 321987390, 1862019060, -951540342, -894238318, -430407175, -1662746491, 656574776, 1580373777, -431290218, 1645824323, -1953526979, -374682356, 474291752, 1071558425, 511038981, -760598678, -567797285, -1176476266, -268409005, -2130644484, -67970563, 1756046948, 1429860462, -1130984739, -124916495, -1544436836, -1863524031, 1024916487, -1388636482, -1573205065, 892628956, 1831270021, 1176430590, 1158914682, -2006787098, -1228130033, 1516111488, -1499151347, 470546266, 1642603981, 1425140838, -1823071475, -1775267236, -1009380612, 164746986, 1129677098, 1842642579, -482342932, -507480364, 1656012309, 1981601761, -881042120, -511987083, 342447017, 381192578, 983008095, 741012865, -1877136350, -199211983, -452784912, 1929572576, -1678291139, -864375281, -1610561247, -1936356726, -749553767, -865893512, -567081879, -1303973729, -939636958, -622974563, 428284937, 1049237414, 852280765, 86648946, -1353851401, -1045422335, 898035731, -1636093996, -1083174191, 245046915, -359768226, -1028491655, 1051575118, 1774289451, 1839389415, -1594053468, 736707953, 1873556950, 401186168, -583669552, -88375334, 2002752071, 264506453, -1304812107, -759203942, -114958524, -1878903503, 841613720, 1910863820, -1738114003, 701455920, 1791058048, -1850960547, 1672292671, 1172188809, 604848896, -1607489375, 305370478, -948153885, -1971080100, -1848966954, -584538365, 39416319, -1689119162, 944942598, 1777111075, 1534005553, 2022718432, -25820385, 3077695, -315950520, 1859184648, -1397829266, -1666371809, 858913807, -610818620, 1554973298, 580023809, -1662988256, -408630026, 1316681876, 738204271, 942829881, -758486983, 780345857, 667165037, -2086803585, 789741324 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well44497bTest.java100644 1750 1750 40537 11532241241 27070 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.junit.Test; public class Well44497bTest { @Test public void testReferenceCode() { int[] base = { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000, -595495729, 1047766204, 1875773301, -1637793284, 1379017098, 262792705, 191880010, -251000180, -1753047622, -972355720, 90626881, 1644693418, 1503365577, 439653419, 1806361562, 1268823869 }; int[] init = new int[1391]; for (int i = 0; i < init.length; ++i) { init[i] = base[i % base.length] + i; } Well44497b mt = new Well44497b(init); int[] refInt = { -102003638, -1254584449, 836441550, 1949705484, 653000494, 1579400718, 699652570, -140738233, 1164288466, 419933874, 366568847, 780567309, 1867405910, -350557801, -964350642, -1323492759, 191502468, 398676344, 1568976991, 1005053759, 199053603, 31083944, 74697788, -1343941248, -1205631880, -1637961625, 361813531, -1706096179, -403340909, 1666226814, -2034962600, 1237102662, -1833248535, 1584255126, 1295661745, -1753848945, 1208145993, 930278953, -733716134, 192752767, 1692463060, 1727273316, 2122952931, -809025255, -992081044, -895539688, -419372543, -1835478922, 2089629419, 1646590742, -1261083717, -1005462992, 1619627287, -1437723182, 1619689210, 1319393089, -1816963183, -150214444, -513482220, 1897815796, -1861960936, -1766444468, 2034653890, 585657634, 1867016559, 696942260, -1536237241, -527055447, -1554805020, -1063992566, 1024799415, 1782080572, -1884276362, 129028272, 1427925968, -1154222271, -1383146732, -1580532830, -1907049616, -104299169, -1780913000, -2090815339, -1789809502, -1521443849, 1226625769, 1126090676, -2117094290, -449575109, -218982833, -695554478, 35923022, 1386126825, -95031305, -168657023, 436674049, -1137917876, -2045134053, -1025629865, 133144659, 64226081, -1966942130, 700813483, 344058910, -910646033, -212789479, 740360859, -1269028713, 1517763679, -664178514, -683718472, -71951996, 86583727, -1235669348, -1426987265, -166598353, 214190040, -1436967644, 233824411, 710927452, -1939548641, -433607408, -1075939594, -1549702826, -1310827917, -640604762, -696863672, -1282162126, -546470833, -1516734192, -513809904, -458526835, 708926727, -476643096, -2108375037, -2870478, -1460116421, 436587555, -948939610, 1891375124, 1944216545, 959034236, -1267038790, -1695098736, 1853748495, 1594424552, 1270099319, 1139585482, 1837434635, -709909535, -457524230, -887118113, -241703912, -1888225819, -751575804, 1122280146, 1194255209, 949350188, 892826516, -791212042, -151203035, -859297731, -1979039938, 323603119, -1022065097, -1804294506, -385802891, -2127523442, -720380255, -1315859127, 999649487, 335041941, -1732821688, -1833409827, 535715225, -1285355653, 1206723386, -1141619270, 759796285, -1599504546, -1988521411, 1056668895, -852564594, 1056509609, -1831687977, 754168875, -1301144422, 922880446, -1502666503, -949791898, -1043870198, -1136941938, -1649670259, 1342769348, 1692605059, -132279148, -1108038310, -14355545, -1611387086, 1651826569, 877600127, 1356160799, -759125205, -1300490081, -414938486, -201479285, 1958709363, 1513313540, -1396836908, 1352702612, 1142506253, 52969438, -365142357, -1619054179, -1368514102, 1470750417, -1420830959, -843909462, -1679570143, 1447444607, 234551752, -1507452115, -1433234579, -680890000, -497305145, 860408898, 263376761, 1537070218, -592353956, 1587852989, 1756653749, -2081320633, -1547020311, 723771611, -883819383, 1899879513, -268417584, 1058606451, 1665941493, -1630340612, -614737477, 891313237, 1368950660, -1166187089, 296322368, -1908770726, -2120378408, 1245479677, 1879710487, -1705947124, 1018371589, -1715010575, -1096078094, -1749891454, 2130888667, 318647750, 554592231, -489121568, -1809605233, -1697905160, -953926536, -2013960553, -148884919, 1822739964, -1466301760, 141999978, 1946526064, 1323036718, 864390149, -2141665227, 1510602225, 1468408474, 1277039721, -1368096647, 180965986, 2140852057, -688071899, 819713016, -154385940, -1182972611, 1257224305, 1392607672, 1364245931, -1768434401, 323522132, -555278604, 474186520, -1178901665, -2137343658, 1636421121, 1398987084, 1276656225, 1013316006, -955917865, -1537149363, -179145358, 342862050, 1172728007, 736300054, -1114656959, -1831840325, -1882353535, -442915191, -1206488416, -1818534411, 25312311, 2100297098, -1562767719, 1762553519, -1853194231, -1152612739, -2020055792, -809572150, 848584579, -535789699, 1817604709, 1343773216, -602234204, 1739930964, -833790834, 501215449, -730104057, 1217783189, -681773267, -611951354, 978387629, -1516811237, 974303980, -1389665696, 2091099075, -727528826, 2116026151, 271935854, 613242379, -2100429856, 190004963, -1629612570, -1362888327, 175094223, -917873219, -2008308245, -401946815, 504218792, -1966525201, 4106248, 164895454, 226502921, 655865257, -610528718, 189428750, 1055978898, 17603028, 591024369, 1127922501, -1546639293, 1994174637, -724136988, -673919372, -1665002120, -612145705, -793102882, -1904763558, 757565058, -2091240021, -2123324826, -1518702766, -802889839, -223045921, -1509216579, 1195556261, 2079259971, -903969953, -1781800655, 1834950463, -956531922, -1152550807, -1116052662, -348802884, -1395330117, -91758501, -19115285, 1926930669, -1015793599, 545904386, 1617858191, 716963473, 1917089719, -980914811, -212646927, -1634695647, -1857924568, -1462257477, 1273750178, 1060328454, -361604424, 867932749, 451213698, 405780152, 1165233215, 1877230909, 2103114395, 1644330815, 1252998537, 1961603970, -1533101488, 1790456024, -38226118, -1306744489, 713676418, -1535871838, 1378109935, -338185548, 1647669762, -477465913, 203482277, -1949756706, -503326093, -638704909, 320186309, -1435581459, 907446649, -77384645, 537368928, -335347295, -1912061924, 547819174, -225549827, 1089455486, 463516297, -240127764, -85895271, 2053179697, -287394931, 921878827, -933362608, -1178670275, -1200942874, -672571265, 574422382, 1441734039, -1814493454, 165751640, -176907245, -1170992192, -2123252090, -1435971541, 1591853830, -885477992, -792847559, 1359875286, 1038392904, -2027255124, 687291425, -165513490, 1391146576, -1387080955, 794663652, -807189965, 667820962, -545384499, -1371368854, -689031878, 1504805541, -752825823, -1920047745, -1884874017, -350566320, -197152911, -181743050, -798415949, -915922276, 1790690149, -363997181, 1923116185, -1326427198, -1621079427, -1997440997, 1798118127, -2053110382, -159879848, -1286787216, 1046436411, 1832030471, -389092059, 71686169, -76025260, 1914270607, 1854169353, 872157826, -1774323792, -575165717, -1919931724, 2051498109, -1176174934, -883578901, -1253047270, -1310573900, 245466682, -1784824328, -1319912821, 1377340217, 1364313761, -408687373, 142333378, -1952335763, -1703126184, 316314678, 2030555423, 488640834, -1783293306, 2116925005, -428337460, -42966447, -476226114, -325172903, -1690748475, 852791569, 26490302, 85251337, -1374975770, -376283969, 982639600, 595119792, 376403422, 1574509912, -1509664496, -1901241749, -59019104, 358566667, 341667214, 184541206, -550950854, -1897143732, 1595753537, -1236127928, 2014297822, -2033179270, -669806121, -1927596980, 1010735700, -581795164, 1922398838, -1456743538, -1633813803, 323177707, 2002098813, -2099067658, 277393729, -671911622, -384463053, 2028267908, 367391785, 1270052637, -172839030, -650486693, -831800809, -1255138113, -137512799, 1904317942, -8229811, 707361898, -276859812, 50417442, 1487081728, 1577776181, 1994451303, 1237303035, -602016235, -1905218276, -1895725672, 1172978849, 801129953, -1819485071, -587985848, -2010386741, -1645226427, -850866837, 816998708, 357665811, 1955856762, 1617902189, -1013761306, 146782652, 904185608, -500146809, 2085848310, 1917713975, -1823786899, 1994184748, 789196322, 1766857258, 1770685286, 58213029, -1699628994, 346827379, -1274423227, -5079670, -193099487, 1020296939, -1795904054, -1951053094, -43782418, -375403393, 1026761026, -207269610, 1364563521, 1578793454, 457809423, -534138380, -1052938788, -1897101526, 1449976516, 2052800058, -1145169719, 1476303269, 370625650, -325249282, 2165984, 1631432802, 1032336355, -1292978191, -1810172401, 725725820, -1162678778, 702624490, 1387673527, 981825943, -556408212, -1108487850, -1782136935, 1582316425, -1752682164, 307235003, 1386486299, -1343636074, 1936875586, -1265279891, -345847069, 928241171, 239050350, 1859358526, -664776217, -823267892, 346651710, -867656288, -1907921425, 1362445801, 541145461, -192727350, 1649366606, 244694627, -488180018, 214008256, 2032125437, -1678591993, -264593820, 1309017286, -652451998, 1845366657, -703990120, -550186406, -630285276, 1782372955, 1650564210, -1127904234, -1407983860, -1119422877, -1565976361, -1913545385, 549841420, -1410323732, -1964467146, 228296551, -421026422, 1929094398, -266906424, 264810315, -2008122665, -1088278148, 141242192, 1871293282, 234634067, 1724159838, 1638271051, -837713428, -657941661, 168093988, 708605363, -1881612509, -1810496006, -193495322, 1889982309, -2050702012, -693694192, -1249780322, 718733403, -76349730, -188217051, 920912090, -1814078273, 2013358456, -1948845521, -198407575, -1248904632, 1182772565, 1236791612, -1297489171, -1958468586, 1437011007, 390460941, 113068796, 1247982993, 2102889679, -1563524844, -128174212, -754095070, -1461699362, 943615640, -1013270737, 221253920, 1514140013, 1596946745, 674222984, 616356702, 1811224435, -1764322023, -1653707581, -1702404459, 390678142, -209506765, -1398278531, -117061517, 1625861343, 659048069, -1490678943, 846536668, 210715637, 1855458786, 1727745280, 1086729456, 1109111683, -985298098, -1813777567, -954599702, -1522494031, 1166103515, -191868965, -1048777852, -661271058, 1161457421, 1509090409, -919753558, -155431193, -1774302994, -366390263, 2090138916, -693431491, -1693888428, 1846774454, 925855693, 474383470, 208889079, 382195164, -283005634, -2095134392, 579927985, 1390765326, -1766119865, 900457129, -1503703236, 974952690, -107714111, 381338452, 1187256613, -860560742, 524103620, 1499506130, 197755276, -790802926, -406920967, -1972219791, -665721155, -113336203, 1037154436, -1185441801, -745541706, -546274471, 1988928457, -1975403782, -1167172845, 777779004, -1560935061, -140258712, -1243598232, -1394149587, -785002782, 311842991, -1025469277, -605350463, -1251538057, 537203966, 597777961, -1845767072, -1556349193, -1491015509, -1935936671, 2093498487, 1908270236, -315396187, 1356362300, -2025658518, 630119678, 276190559, 510123398, -1266145363, -170152124, -151540077, -477900187, 1895894303, 1870333068, -1169891437, 353366620, 2111175941, 1691245786, 1318765802, -90993610, 921309517, 118241505, 367005284, 1624861072, 2010785894, 865255951, 1717799691, -80757664, -644944841, 136999836, -341686875, -1908076090, -1968934200, -346397811, -184213520, -511811333, -2118173466, -1086490399, 1795322855, -635494328, 415716276, 851044432, -904636831, -1972230341, -64337858, 571177016, 1248814747, -1351030778, 457872680, 1843549954, 1718960038, 815088665, 1812961065, 360686952, -1356586646, 1657802416, 1776192945, -786723490, -342254407, -236653811, 771014701, 906386785, -308057635, 1907957462, 206000440, -42143480, 900403654, -917549795, -310520796, -1713627766, 2061136240, -377977839, 891282946, -821163030, 328143584, 1503793080, 551621842, -2086273683, -2070526343, 91195293, -1654389038, -1035734266, -336619597, -1220221027, -1468468844, 2105626873, -841372573, -122707018, -2013073683, 494461000, -2054807734, -67946259, 1914163407, 1941835405, -1027244745, -768123277, 419129844, -275750260, -171533009, 97756174, -17651409, -1578102255, 995291430, -1587462977, 692904675, 951632643, 1882101293, -1546298756, 2018418068, -1790777661, 1542305514, -1437624383, 469587009, -1647853474, -1318279028, 497228822, 726733469, 1693133452, -2091185798, -209017732, 126386499, 1056958932, -2105494133, 754067324, 96463951, 83701151, 1101658289, 1485852701, 553783806, 1898769881, -1072031442, 1438062141, 1992540265, 1152252136, 1019391719, -175951257, -6691216, 989789689, 968359367, -1330392786, 1704963399, -998432914, -948060232, -1921688855, -975840920, 1360273515, -872810459, 12676907, -1908050756, 883609616, 65641549, -200365398, 1386653304, -1203665071, 1878689007, 426262328, 315375145, 1900325181, 703658494, -765404895, 1070155172, 1399748900, -804264234, -1619419026, 1347225486, 230635292, 1093717835, 14020583, -2107039873, -968325341, -1679158691, 1959784097, 1065690797, 1090615161, 1311445364, 865835426, 870016646, 574122879, 1842697922, -1289210431, -1914001560, 1672467629, -900366331, -1524066872, 136503816, -1910431892, -1431958329, -830367152, -1316233970, -801974860, 1560669382, -81784810, 401822577, -949103202, 943897151, -722666726, -96825841, -1092898846, 230567004, -70355840, -1398069192, -312953142, 1475420133, -622491023, 1661205388, -19071322, 6024591, 1473041593, 2053897978, -1346768903, 1484764721, -1552461890, 1287146711, 1613069307, 902497864, -1504480063, 375292915, -836353108, 2047602411 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/GaussianRandomGeneratorTest.java100644 1750 1750 3013 11532241241 32135 0ustarlucluc 0 0 //Licensed to the Apache Software Foundation (ASF) under one //or more contributor license agreements. See the NOTICE file //distributed with this work for additional information //regarding copyright ownership. The ASF licenses this file //to you under the Apache License, Version 2.0 (the //"License"); you may not use this file except in compliance //with the License. You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, //software distributed under the License is distributed on an //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY //KIND, either express or implied. See the License for the //specific language governing permissions and limitations //under the License. package org.apache.commons.math.random; import org.apache.commons.math.stat.StatUtils; import junit.framework.*; public class GaussianRandomGeneratorTest extends TestCase { public GaussianRandomGeneratorTest(String name) { super(name); } public void testMeanAndStandardDeviation() { RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(17399225432l); GaussianRandomGenerator generator = new GaussianRandomGenerator(rg); double[] sample = new double[10000]; for (int i = 0; i < sample.length; ++i) { sample[i] = generator.nextNormalizedDouble(); } assertEquals(0.0, StatUtils.mean(sample), 0.012); assertEquals(1.0, StatUtils.variance(sample), 0.01); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well1024aTest.java100644 1750 1750 22315 11532241241 26754 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class Well1024aTest { @Test public void testGaussian() { Well1024a mt = new Well1024a(42853252100l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 10000; ++i) { sample.addValue(mt.nextGaussian()); } Assert.assertEquals(0.0, sample.getMean(), 0.004); Assert.assertEquals(1.0, sample.getStandardDeviation(), 0.003); } @Test public void testDouble() { Well1024a mt = new Well1024a(195357343514l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 10000; ++i) { sample.addValue(mt.nextDouble()); } Assert.assertEquals(0.5, sample.getMean(), 0.0006); Assert.assertEquals(1.0 / (2.0 * FastMath.sqrt(3.0)), sample.getStandardDeviation(), 0.002); } @Test public void testFloat() { Well1024a mt = new Well1024a(4442733263l); SummaryStatistics sample = new SummaryStatistics(); for (int i = 0; i < 10000; ++i) { sample.addValue(mt.nextFloat()); } Assert.assertEquals(0.5, sample.getMean(), 0.0001); Assert.assertEquals(1.0 / (2.0 * FastMath.sqrt(3.0)), sample.getStandardDeviation(), 0.003); } @Test(expected=java.lang.IllegalArgumentException.class) public void testNextIntNeg() { new Well1024a(1).nextInt(-1); } @Test public void testNextIntN() { Well1024a mt = new Well1024a(0x12b8a7412bb25el); for (int n = 1; n < 20; ++n) { int[] count = new int[n]; for (int k = 0; k < 10000; ++k) { int l = mt.nextInt(n); ++count[l]; Assert.assertTrue(l >= 0); Assert.assertTrue(l < n); } for (int i = 0; i < n; ++i) { Assert.assertTrue(n * count[i] > 8600); Assert.assertTrue(n * count[i] < 11200); } } } @Test public void testNextInt() { Well1024a mt = new Well1024a(new int[] { 1, 2, 3, 4, 5 }); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextInt() >= 0) { ++walk; } else { --walk; } } Assert.assertTrue(FastMath.abs(walk) < 70); } @Test public void testNextLong() { Well1024a mt = new Well1024a(12345); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextLong() >= 0) { ++walk; } else { --walk; } } Assert.assertTrue(FastMath.abs(walk) < 70); } @Test public void testNexBoolean() { Well1024a mt = new Well1024a(76342); int walk = 0; for (int k = 0; k < 10000; ++k) { if (mt.nextBoolean()) { ++walk; } else { --walk; } } Assert.assertTrue(FastMath.abs(walk) < 180); } @Test public void testNexBytes() { Well1024a mt = new Well1024a(0); int[] count = new int[256]; byte[] bytes = new byte[10]; for (int k = 0; k < 1000000; ++k) { mt.nextBytes(bytes); for (byte b : bytes) { ++count[b + 128]; } } int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int c : count) { min = FastMath.min(min, c); max = FastMath.max(max, c); } int expected = (1000000 * bytes.length) / count.length; Assert.assertTrue((expected - 600) < min); Assert.assertTrue(max < (expected + 600)); } @Test public void testReferenceCode() { Well1024a mt = new Well1024a(new int[] { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000, -595495729, 1047766204, 1875773301, -1637793284, 1379017098, 262792705, 191880010, -251000180, -1753047622, -972355720, 90626881, 1644693418, 1503365577, 439653419, 1806361562, 1268823869 }); int[] refInt = { -1478749726, -1645579484, -2075363835, -2063444174, -1834148336, -1769045872, -40711346, 1717441026, 2130656771, 783441285, 570433609, 1560023451, 653233971, 1368672434, -72036215, 1071111800, 933776492, 26114960, 49888778, 1808107515, 1092989296, 754848337, 1336994364, -1987450448, -691190146, -1803870839, 1110716866, 1173269113, -391000050, 2014216908, 180756301, -382891013, -1908154585, 1580737629, 1080267957, -125532248, 2094530239, 2132964485, -438596348, -760299445, 1058181869, 2050816800, -1534429037, -62552782, 824524142, -818590371, -1857695907, -684762866, -156556543, -902759995, -880795194, -1387351132, -1263017515, 448006597, 201038266, 1929826313, -455367306, 672963027, 2000073013, -1546842042, 446341090, 1001696686, -779919012, -347722602, -1342821677, 1639571150, -835315755, 1505585376, 367004975, -2035864404, -1786623553, 1249724913, 182435312, 1444514513, 1815333708, 1333772382, 299664001, -284691169, 2034403374, 1423310887, -1319051884, 1557286441, -445198266, -251809030, 1602786123, 944036382, -1020529634, 258344235, 685254367, 1838964943, -156674528, -979736602, -538312836, 234643178, 211152102, -635498640, -1036733933, -1347589147, -565609042, -1358714165, 508618483, -786364693, 2071450261, 1206956772, -678931458, 167690617, 144698821, 1719720781, 1575869280, -1343221123, -1766469944, 284991647, -717305514, 892653651, -1368347075, -615701972, -730369849, 1360396003, -1869287623, 1778269052, -586061545, -699517114, 61530249, -1860611767, -519660852, 1841085925, 1555610093, -399979337, -790345742, 422355947, 2007965433, 2044952550, -1712164595, -102915702, -693865324, -1894042487, -1285020072, -215883074, 95833252, 1625818040, -1055951680, 513067085, 1825246558, -553461652, -1923361799, -1869480206, 567232636, -1751727150, -1832301399, -108136455, -1312244126, 14006795, 850221366, -382389732, -1741556188, -1317464467, 1948314870, 753994471, 1028235947, 342494132, -1862256693, 723808794, -234257642, 1609928369, -802733456, 1315831915, 1436072885, 1224767136, 2144557791, -1839965886, 224821018, -1461697757, -1080386760, 1638573498, -1188173812, -325181523, -1750676219, -1780415850, 698793362, -908352052, 299746482, -161660934, 1938166833, 800297005, 56640033, -1214932666, -1248124842, 1822796868, 1777615881, -718517774, 1908159957, 1733053281, 1851844331, 1283519375, -1771494956, 2060179999, 1666129209, 1919453531, -498145770, 697567008, 1855487148, -1587163491, 565216434, -1477877933, -925662919, -806492585, -1201439047, -1424534232, 1788616523, 69414717, 655893636, -1175978556, 24787512, -861550001, 439525754, -190433174, -383811606, -508589783, 1441608687, 608181366, 1539467064, 925903122, 697209654, 1878283393, -1967567432, -1659677763, -249658183, 847096354, 397741956, -125334541, -1286840731, 1016461908, -997968592, 1795331475, 1856856501, -1716726445, -582181331, -887091847, 426964855, -609219941, -1456232632, -483467616, 1069260754, 972242064, -1406786247, 1954194029, 52627891, 1212755081, 2117436668, 281073392, 741537353, -483063506, 1850906286, -244876135, -270818140, 1817568823 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/UniformRandomGeneratorTest.java100644 1750 1750 3006 11532241241 32004 0ustarlucluc 0 0 //Licensed to the Apache Software Foundation (ASF) under one //or more contributor license agreements. See the NOTICE file //distributed with this work for additional information //regarding copyright ownership. The ASF licenses this file //to you under the Apache License, Version 2.0 (the //"License"); you may not use this file except in compliance //with the License. You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, //software distributed under the License is distributed on an //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY //KIND, either express or implied. See the License for the //specific language governing permissions and limitations //under the License. package org.apache.commons.math.random; import org.apache.commons.math.stat.StatUtils; import junit.framework.*; public class UniformRandomGeneratorTest extends TestCase { public UniformRandomGeneratorTest(String name) { super(name); } public void testMeanAndStandardDeviation() { RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(17399225432l); UniformRandomGenerator generator = new UniformRandomGenerator(rg); double[] sample = new double[10000]; for (int i = 0; i < sample.length; ++i) { sample[i] = generator.nextNormalizedDouble(); } assertEquals(0.0, StatUtils.mean(sample), 0.07); assertEquals(1.0, StatUtils.variance(sample), 0.02); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well19937cTest.java100644 1750 1750 40636 11532241241 27072 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.junit.Test; public class Well19937cTest { @Test public void testReferenceCode() { int[] base = { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000, -595495729, 1047766204, 1875773301, -1637793284, 1379017098, 262792705, 191880010, -251000180, -1753047622, -972355720, 90626881, 1644693418, 1503365577, 439653419, 1806361562, 1268823869 }; int[] init = new int[624]; for (int i = 0; i < init.length; ++i) { init[i] = base[i % base.length] + i; } Well19937c mt = new Well19937c(init); int[] refInt = { 2128528153, 327121884, 935445371, -83026433, -1041143083, 2084595880, -1073535198, -1678863790, -523636021, -1514837782, -736786810, 1527711112, -1051227939, 978703380, 410322163, 1727815703, -648426354, 636056441, 1954420292, 17754810, -958628705, -1091307602, 1793078738, -1680336346, 1792171272, 941973796, -2066152330, -1248758068, -1061211586, 262020189, 1276960217, -233886784, 1767509252, -1811939255, -406116097, -742435920, -1349799525, 240329556, -332161345, 1488943143, -332244280, 2093328957, 674753300, -1930135556, 257111467, 63793650, -1964335223, 1315849133, -797349146, 1372022250, -1451892049, -1325138957, -870401239, -1294317369, 91490879, 386205044, -704074702, -1230679067, 1513674392, -262996240, 1196007314, 1398903796, 803719762, -1750926831, -1268814180, 1233515404, 1498313934, -970591257, 611113671, -261632474, 1834097325, 1709440492, -150396854, 2120561003, -62645660, 479080234, 1535125050, 1823378695, -1129289329, -1095198399, 2092564733, 78836308, -692015409, 1647147229, -1847922219, 1838279320, -848333841, -1375151778, 920238861, 1512628290, -749439404, 288851918, -427218675, 679640964, 425700808, -2077624511, -1929434455, -647176419, 650437190, -1926749131, -1564744729, 734494454, 108193743, 246246679, 810042628, 1952337771, 1089253730, -1874275331, 1428419392, -492969232, 1945270770, -201265602, -755490251, -624426214, -699605715, -113446478, 809091299, -1521531511, 1136505389, -523660964, 132928433, 1926559713, -1485314325, -508322506, 46307756, -1627479740, -589386406, -1855555892, 584299545, 1272841066, -597242658, 925134545, 1102566453, -753335037, -9523218, -1778632375, 568963646, 764338254, 1259944540, -2000124642, 1307414525, -151384482, 807294400, 1993749511, -15503094, -709471492, 2104830082, 1387684315, -1929056119, 224254668, -733550950, -889466978, -1987783335, -437144026, 995905753, -1021386158, -1096313388, -1014152835, -1303258241, 1201884788, -1845042397, 1421462511, 980805867, 2143771251, 481226968, 1790544569, 328448328, 1995857639, -66668269, -1411421267, -222586606, 866950765, -308713926, -1048350893, 993222402, -1139265642, -871837948, 1145571913, 381928580, 35386691, 1640961123, -1192981020, 775971009, 594246635, 1603197812, -575106766, 2023682000, -1636301903, -718093720, -1666421635, -2146115988, 320593570, 287355418, 454400027, 1112753817, 1751196267, 782077910, -1478447368, -1007557264, -862315517, -2035355952, 2123515250, -557641502, -1789932035, 879640129, 44167603, 791148984, 1382939723, -2135684233, 1825489580, 937345485, -1839983359, -1536880111, -1472578359, 1548052748, -1471535862, -14508727, 1509621398, -2134967452, -787485401, 815341660, -327905128, 1028096737, 866906991, -1585990806, 859229080, 234806270, 998518056, -1897890815, -900923587, 1179856752, 1529572451, 620486106, 1119836556, 1661285564, 2097404633, -1437490790, 265306115, -984880135, 1326751968, 1280043536, 680210701, 155786166, 1550973250, -325781949, -597789777, -1939780, 1345275487, 1930450001, 941449704, 669301309, 693651713, -990721514, 582968326, 976132553, -1892942099, -1065070157, -711990993, -688974833, -1026091683, 1115346827, -1305730749, -1733626381, -364566696, -21761572, -37152746, -262011730, 1302722752, -1806313409, -767072509, 764112137, 1671157377, 1837645038, -1021606421, -1781898911, -232127459, -310742675, -1818095744, -1128320656, -705565953, -354445532, -523172807, -433877202, 131904485, -64292316, 381829280, 229820263, 1797992622, 1359665678, 978481451, -885267130, -1415988446, -356533788, -961419072, 1938703090, 708344111, 679299953, 744615129, 1328811158, 1257588574, 569216282, -753296151, -1519838713, 2016884452, 1062684606, 1561736790, 2028643511, -1353001615, 886376832, 1466953172, 1664783899, 1290079981, -57483993, -1176112430, 1634916316, 1976304475, 1374136869, -648738039, 1058175869, -909000745, -1526439218, 726626991, 2066596202, 64980943, -26166577, -885900005, -1821546816, -1103727665, 730606315, -1324948459, -696956940, -1300869403, 1171578314, 797249074, -1600611618, 1928247682, 307164165, -1482476232, -1886179640, 1306433392, 1945271359, -1272113751, -1285984081, -2057145549, 795047465, 1262569087, -1239828121, 1426641636, -786371495, 2120199316, 1273690652, 74457589, -1033394229, 338952565, 46122958, 1225741533, 2115308090, 678200841, -1618264885, -101162569, -1628976330, -1232839500, 468709044, 1876019116, 92723122, 233398255, -554960844, 38494196, -406437278, 2083528643, -1106878615, -340722557, -2123964932, 223183343, 108918116, -1014629054, -901344544, -838896840, -1908460517, -1763508731, -926890833, 1703791049, -667755577, 1694418389, 791641263, 1095689677, 1119202039, -1419111438, -2012259010, 188017439, -1775110395, -1971099661, -1688113734, 131472813, -776304959, 1511388884, 2080864872, -1733824651, 1992147495, 1119828320, 1065336924, -1357606762, 462963503, 1180719494, -202678962, -892646595, 605869323, 1144255663, 878462678, -1051371303, 872374876, 631322271, -172600544, -1552071375, -1939570033, 151973117, 1640861022, 310682640, 34192866, 2057773671, -2004476027, -1879238973, 582736114, 900581664, -427390545, -1232348528, -535115984, 1321853054, 69386780, -1729375922, 1418473715, 1022091451, 496799289, -80757405, -1903543310, -1128846846, 1703964, 1984450945, 856753858, -812919184, 775486323, -1376056193, 638628840, 314243536, 1030626207, 644050997, 73923896, 362270613, 236584904, 1463240891, -223614432, 435371594, -751940030, -124274553, -1991092884, 1579624267, 1249632649, 157589625, -345229739, -366245207, -1399995986, 1651729983, 1965074340, -1108970305, 1163690769, 1732013523, -1461252895, 669755552, -476503675, -264578685, -32813949, 288222188, -25734262, 106040916, 1654395626, -365148479, 2014455846, -2040447994, 1351639280, -919975757, -1970412139, -47306532, 222377665, -363434917, -1091717516, 2090685531, -1221091649, -1729649190, -1239406708, 1064945398, -105437479, -419675255, 74701669, -12862899, -498269844, 1566898997, -1872838355, 1596887574, 485902962, 469225597, -881763553, 1307841032, -1642872487, 1388543045, 379792876, 1095683384, 840780732, 1934378038, 1851278350, -1359389423, 130868458, -313448799, -663624816, 1031714153, -608443411, -205137499, -1849464427, 1973593637, 1068741808, -1420655961, 1188762305, 954044841, -995454462, -1818101092, -1937201943, -324541290, -1520603933, 572873173, -554764496, 1051557081, -1245136076, -985349536, 329320398, 1787901464, -37803304, -1759310177, -1463492617, -1861729663, 1251768782, 256937091, -779036948, -2049893864, 1256022877, 1228075657, -1550195255, -611319853, 1190797155, 2047604112, -576077160, -1532843331, -1324899394, -159729560, -622525946, -1080302767, -236033484, 1895243903, -410123689, -1944154157, -681781021, 1208453003, 579595878, 1303914051, -145607082, -131567277, -1917288455, 894217359, -175688726, -1585480723, 663691440, -1140068263, -641711178, 1596080008, 629197693, 976422358, -1570451095, 525923776, 895046136, -504151767, 1602553020, -1233054923, -1798474837, -1488857895, 1055782627, 261863143, 1879276655, 488240679, 1910982611, -1919441259, 370435945, 1265230086, -1293284428, -1503576227, 2076963035, -1379628250, 1157098875, 1984461153, -1947837397, 1705880124, 1453607404, -1233649748, 1479943773, -863878721, -862415630, -736723275, 940306358, -1596000684, -1174889953, -615723892, -885006597, -1796723178, 1844159055, -188942309, 2107251811, -1675486996, -1009475178, -859263556, -431866963, -9593673, -1878920923, -104853791, -1535224994, -69315537, 586690130, -1292234796, 1378749456, -301873019, -319297563, 1677205851, 292450579, -1289441171, 1788113680, 1907606333, 1464711611, -1372023606, -1978832445, -1772259768, 1949124464, 1818322887, -1138036603, 1249727628, -1474866449, -1868013169, -1384567593, 717007936, 954189997, -1900561040, 738470389, -158973180, 1732860784, 1936031206, -1133354740, -1173166665, 1432976712, 852636081, 1732064691, -1831788120, 1273933579, 455403217, 1988395890, 106493468, 506092152, -610530423, 1698053512, 1311747476, 1969503012, -1887461759, 1613543073, 903200334, -737865837, 325656800, -1234001200, 1492148864, 2009861533, -368262605, 1091338541, 2076108119, -961392337, 1835877112, 316250307, -853333391, -2125443777, 815363504, -798707803, -158146540, 690786114, -530775684, 1203556940, 1611485582, -1661412270, -53184506, 2126287444, -232222229, 1559486057, 283532250, 1202760418, 932144172, 1082594656, -570104011, 413509167, -995027177, -996477516, -540544, -745537167, -712135469, -996294983, -592787198, 1889840948, 1314628747, -394266926, -682316577, 456447239, 1728806063, -396279614, -43387643, 1915717013, -861574144, -1078710588, -561401249, 1111464540, 63643984, -1693870413, -968369980, -1053148188, 708799038, 1883537988, 373371671, -156410415, -1596483236, -1846890431, 888692915, -1025632583, -1666477591, -343066267, -2059058792, 641501628, -1744347292, 1648632991, 1743540146, 2020952406, 164014499, 990508262, 1706408228, -1236471842, -347116260, 1843634523, 827255665, 300519853, -1265974830, -547247177, -583064554, -1995437077, 689210107, -93151393, 835365056, 1706367315, -1605902756, 200954895, 431093688, -277573364, -928486713, -552221973, 145432789, 1128919795, 1675095586, 1930359882, 1215849501, -1447770583, 657776490, 1885869860, -1629237204, -868897479, -1258169760, 1828140195, -883850439, 463933909, -347361158, 1478116648, 801176896, -1501915899, 1017335748, -1654508882, 123994786, 1588785290, 791166651, -1523108535, 340411166, -496474762, -1189711141, -7392628, 2045171250, -1245366209, 834787230, -1346883181, 2034209454, 737043362, 898803323, 1983089087, -1845404320, 9585188, -1180608323, 1665100606, 1949474222, -211115008, 1151308295, -2132174259, 913126312, -2085061672, 1419864120, -1134542954, -53833957, -246913211, 468382370, -1759479323, 1136686211, 1307012488, -2036299559, -1346099736, 314743106, -1683101865, -947151948, -234529696, -2103334293, -279256894, -1484257, -1053953017, 1801205399, 941594454, -874119215, -672865187, 762284205, -1494975451, 486607927, -898264389, -1711861093, -212572760, 2106484281, -1610786470, 1352525590, -837779586, 1568282001, -593019125, -1146260782, -1595879979, -640781858, 1107692311, 1547132709, -1928385535, -2057772805, 634887038, 329772618, 942136006, -864405576, 501883884, 1537141484, -1180626836, 1123055420, 1090885851, 421662750, 2033111605, 1710917425, -1118058244, 74321279, 257328195, -1199940697, 208625996, -442341447, 808119183, 1166827075, 1177417517, -1856155370, -1464837036, -60624923, -1306220638, -91104698, -1434621430, 548899241, 37351476, 1478278431, -1255061434, 248470035, -104642597, -1865169521, 1418373655, -1660810523, -2129015436, 154612798, 276575732, 1930338442, 179503250, -929294855, -39452027, -1377657544, 1442322193, 1137511318, -432158653, -984801987, 743099148, -1118893528, -904123623, -1273146363, -1884800406, -803169061, 1254123158, -484252077, 317646844, 404246525, -1230293916, 1121445742, -19657507, 652967153, -1055406692, -468950719, -1493532921, -1447624258, -1369679689, -1517000228, -145853307, 1518006526, 1591195514, -1475557146, -909722097, 2103182976, -406830579, -2124025254, -1804819507, -1357512858, 567321869, 409048156, 567805180, 1749009386, 1762759722, -1770324077, 1271140844, 468219092, 955792405, 1911965665, 1876314424, -718200715, -1278883927, 1392281730, -120519585, 851473793, 245054754, -33369039, -284877584, -479534880, -212346563, -122017521, -1461429983, 1331007370, 1788621721, 1739036536, 1446350953, -1985448033, 685528610, -1386434659, 1368233993, 2021786790, 1596478397, -1716635278, -2011083017, 171876097, -311529197, 687812052, 377000657, -1055547517, -1499047842, -1818434951, -120863666, 33888043, -1387509273, -541540700, 1162597745, -1331415338, 1931708792, -850270000, 663845594, 1536495943, -322924971, -1380272203, 261190298, -204874428, -2104974031, 883819928, 155808204, -1454446035, 1323388464, -1696505728, 1549800285, 1018150463, -1327715703, -1582480640, 1013659809, -1820360082, 1666498787, 1406120540, -196541482, 1248470531, -1250433281, 836375878, 177646854, -1927020253, 2145878321, 689712096, -596605921, 348283199, 1916993096, 481356808, -339687826, 1219340319, 718895887, -2007521340, -1859185806, 2042164737, -58146784, 742449142, 1930754708, 780832111, 715056441, -1393886151, -8150527, -599607443, -537300865, -1212516084 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/RandomAdaptorTest.java100644 1750 1750 5527 11532241241 30122 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Random; /** * Test cases for the RandomAdaptor class * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class RandomAdaptorTest extends RandomDataTest { public RandomAdaptorTest(String name) { super(name); } public void testAdaptor() { ConstantGenerator generator = new ConstantGenerator(); Random random = RandomAdaptor.createAdaptor(generator); checkConstant(random); RandomAdaptor randomAdaptor = new RandomAdaptor(generator); checkConstant(randomAdaptor); } private void checkConstant(Random random) { byte[] bytes = new byte[] {0}; random.nextBytes(bytes); assertEquals(0, bytes[0]); assertEquals(false, random.nextBoolean()); assertEquals(0, random.nextDouble(), 0); assertEquals(0, random.nextFloat(), 0); assertEquals(0, random.nextGaussian(), 0); assertEquals(0, random.nextInt()); assertEquals(0, random.nextInt(1)); assertEquals(0, random.nextLong()); random.setSeed(100); assertEquals(0, random.nextDouble(), 0); } /* * "Constant" generator to test Adaptor delegation. * "Powered by Eclipse ;-)" * */ private static class ConstantGenerator implements RandomGenerator { public boolean nextBoolean() { return false; } public void nextBytes(byte[] bytes) { } public double nextDouble() { return 0; } public float nextFloat() { return 0; } public double nextGaussian() { return 0; } public int nextInt() { return 0; } public int nextInt(int n) { return 0; } public long nextLong() { return 0; } public void setSeed(int seed) { } public void setSeed(int[] seed) { } public void setSeed(long seed) { } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/TestRandomGenerator.java100644 1750 1750 2701 11532241241 30445 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Random; /** * Dummy AbstractRandomGenerator concrete subclass that just wraps a * java.util.Random instance. Used by AbstractRandomGeneratorTest to test * default implementations in AbstractRandomGenerator. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class TestRandomGenerator extends AbstractRandomGenerator { private Random random = new Random(); @Override public void setSeed(long seed) { clear(); random.setSeed(seed); } @Override public double nextDouble() { return random.nextDouble(); } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/random/CorrelatedRandomVectorGeneratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/random/CorrelatedRandomVectorGeneratorTes100644 1750 1750 13017 11532241241 32553 0ustarlucluc 0 0 //Licensed to the Apache Software Foundation (ASF) under one //or more contributor license agreements. See the NOTICE file //distributed with this work for additional information //regarding copyright ownership. The ASF licenses this file //to you under the Apache License, Version 2.0 (the //"License"); you may not use this file except in compliance //with the License. You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, //software distributed under the License is distributed on an //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY //KIND, either express or implied. See the License for the //specific language governing permissions and limitations //under the License. package org.apache.commons.math.random; import junit.framework.TestCase; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance; import org.apache.commons.math.stat.descriptive.moment.VectorialMean; import org.apache.commons.math.util.FastMath; public class CorrelatedRandomVectorGeneratorTest extends TestCase { public CorrelatedRandomVectorGeneratorTest(String name) { super(name); mean = null; covariance = null; generator = null; } public void testRank() { assertEquals(3, generator.getRank()); } public void testMath226() throws DimensionMismatchException, NotPositiveDefiniteMatrixException { double[] mean = { 1, 1, 10, 1 }; double[][] cov = { { 1, 3, 2, 6 }, { 3, 13, 16, 2 }, { 2, 16, 38, -1 }, { 6, 2, -1, 197 } }; RealMatrix covRM = MatrixUtils.createRealMatrix(cov); JDKRandomGenerator jg = new JDKRandomGenerator(); jg.setSeed(5322145245211l); NormalizedRandomGenerator rg = new GaussianRandomGenerator(jg); CorrelatedRandomVectorGenerator sg = new CorrelatedRandomVectorGenerator(mean, covRM, 0.00001, rg); for (int i = 0; i < 10; i++) { double[] generated = sg.nextVector(); assertTrue(FastMath.abs(generated[0] - 1) > 0.1); } } public void testRootMatrix() { RealMatrix b = generator.getRootMatrix(); RealMatrix bbt = b.multiply(b.transpose()); for (int i = 0; i < covariance.getRowDimension(); ++i) { for (int j = 0; j < covariance.getColumnDimension(); ++j) { assertEquals(covariance.getEntry(i, j), bbt.getEntry(i, j), 1.0e-12); } } } public void testMeanAndCovariance() throws DimensionMismatchException { VectorialMean meanStat = new VectorialMean(mean.length); VectorialCovariance covStat = new VectorialCovariance(mean.length, true); for (int i = 0; i < 5000; ++i) { double[] v = generator.nextVector(); meanStat.increment(v); covStat.increment(v); } double[] estimatedMean = meanStat.getResult(); RealMatrix estimatedCovariance = covStat.getResult(); for (int i = 0; i < estimatedMean.length; ++i) { assertEquals(mean[i], estimatedMean[i], 0.07); for (int j = 0; j <= i; ++j) { assertEquals(covariance.getEntry(i, j), estimatedCovariance.getEntry(i, j), 0.1 * (1.0 + FastMath.abs(mean[i])) * (1.0 + FastMath.abs(mean[j]))); } } } @Override public void setUp() { try { mean = new double[] { 0.0, 1.0, -3.0, 2.3}; RealMatrix b = MatrixUtils.createRealMatrix(4, 3); int counter = 0; for (int i = 0; i < b.getRowDimension(); ++i) { for (int j = 0; j < b.getColumnDimension(); ++j) { b.setEntry(i, j, 1.0 + 0.1 * ++counter); } } RealMatrix bbt = b.multiply(b.transpose()); covariance = MatrixUtils.createRealMatrix(mean.length, mean.length); for (int i = 0; i < covariance.getRowDimension(); ++i) { covariance.setEntry(i, i, bbt.getEntry(i, i)); for (int j = 0; j < covariance.getColumnDimension(); ++j) { double s = bbt.getEntry(i, j); covariance.setEntry(i, j, s); covariance.setEntry(j, i, s); } } RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(17399225432l); GaussianRandomGenerator rawGenerator = new GaussianRandomGenerator(rg); generator = new CorrelatedRandomVectorGenerator(mean, covariance, 1.0e-12 * covariance.getNorm(), rawGenerator); } catch (DimensionMismatchException e) { fail(e.getMessage()); } catch (NotPositiveDefiniteMatrixException e) { fail("not positive definite matrix"); } } @Override public void tearDown() { mean = null; covariance = null; generator = null; } private double[] mean; private RealMatrix covariance; private CorrelatedRandomVectorGenerator generator; } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well512aTest.java100644 1750 1750 12313 11532241241 26672 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.junit.Test; public class Well512aTest { @Test public void testReferenceCode() { Well512a mt = new Well512a(new int[] { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000 }); int[] refInt = { 1634813289, 1876773016, -973836208, -2130023652, -1045460084, -1834384857, 1691032973, 609714289, 2033920362, 555915483, 6680992, 1958127415, 1866469645, -1471336965, 2049178762, -192324811, -2056050066, 810879705, 1405046309, -781317118, 1012782311, -1045081032, 728377508, 1473511660, 290489070, 326666761, 2018299979, -1876688058, 1239968501, 1464625040, 2025151042, -101397407, 1387902041, 210959839, 1366359326, -476473433, 153180037, -1607631523, -506743495, 17888738, 313865008, -340504498, 586684079, 1243699375, 753162229, -646761694, -739189655, -210120185, -1856358726, -628255542, -1812798197, 1416288088, 1077967722, -846846208, 1379850409, -580183344, -1858959, 210859778, 295841424, 1492774865, -1415543680, -344870570, -1942779197, 1549510646, -389544849, 314254218, 11784988, -1311757368, 1719514841, -764610517, 1296788970, -994707050, 783854563, 422654144, 387639079, 1219688425, 2144352572, -834212874, -1036550358, 935909479, -568610842, 1327498837, -588933178, 1910065754, -40851599, -182063170, 1302731458, 541311559, -1647345522, 805224371, -1721196679, 1518507830, -952689880, -433276260, 509675254, -777259954, 1277810106, 284054896, 936042202, 2036836351, 1956412426, -1186403024, 287795400, 2135311211, 720485927, 1500695024, -281656583, -1277937322, -1628968482, 1242814831, -2030700974, 1473867890, 440813549, -1357033971, 28384076, 1602731216, -641465746, -609054347, 635938444, 1472898176, 1476894555, -747974186, -1590337055, -884242108, -389736197, -2066984505, 1087103272, -1236446290, 31657463, 1835715432, -468439078, -2132633204, -434609235, 258308151, 1851926761, -1630139159, -1344617241, 1969204215, 619463174, -174392624, 207475487, -1619828078, 1327980298, -83968178, 445951782, -1786230541, 6279288, -580982231, 1550645552, 2006533941, 275746007, 455676647, 2019637349, 1115547704, -1313120106, -516213449, 73752461, -1382448112, 398589620, 1319888048, -1595572334, 1566934536, -1735685764, -1509545339, 1458173912, -549395819, -618827040, 1516624531, 1900757187, -1454200688, 965524719, 488355065, -1869294316, -810641680, -2059428251, 1454656431, 1329120541, -232185900, -994996943, 1855980910, -452077812, 1565630611, 759842266, 1241435187, -1390456063, 1946400597, -2032319771, 683667881, 905911106, 1983310786, 120010546, 526018017, -1946881912, 205004987, -1307250612, 2130980818, 2052864161, 189839787, 1789478047, 406168885, -1145186347, 8507675, 1277188815, 1492619042, 2009819675, -1627411598, -851016743, -1828234956, 1962622506, 2140398255, 236935165, -337237772, 1263419111, 516775236, -335741025, 1391328225, 455979249, -1457534664, -657606241, 485648133, 1762116343, 1194889600, 817834937, 321150162, 131159182, 290277758, -1876924740, -1770401129, 1291602973, -1003642974, -1580211929, 1520422021, -399171579, -24315308, 453805396, -659197747, -205656847, 466526550, 1444397201, 1178091401, -1157268826, -602394028, -1370668795, 1614896435, 1699071659, 1864753793, 1888518358, -1721244514, 1812776767, 668822227, -297283057, 2130183333, -1169618692, 912860240, -2028253096, 1244694278 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/Well44497aTest.java100644 1750 1750 40537 11532241241 27067 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.junit.Assert; import org.junit.Test; public class Well44497aTest { @Test public void testReferenceCode() { int[] base = { 740849862, 1202665156, -199039369, -259008301, -291878969, -1164428990, -1565918811, 491009864, -1883086670, 1383450241, 1244617256, 689006653, -1576746370, -1307940314, 1421489086, 1742094000, -595495729, 1047766204, 1875773301, -1637793284, 1379017098, 262792705, 191880010, -251000180, -1753047622, -972355720, 90626881, 1644693418, 1503365577, 439653419, 1806361562, 1268823869 }; int[] init = new int[1391]; for (int i = 0; i < init.length; ++i) { init[i] = base[i % base.length] + i; } Well44497a mt = new Well44497a(init); int[] refInt = { -1464956854, -1524360321, 986845646, -182050548, -818943186, -1744848370, 1392434650, -182648505, -2026593838, 1254866610, -410459761, -1392048371, -968730026, 1485793687, -728749746, -112685463, 275126404, -1101838984, 1193096287, 443511615, -510869213, 549869992, 1974458428, -1217587840, -335835016, -2048974745, 1066947099, -611611187, 1978925459, 688164478, -463344808, 56995910, 699288809, 606392470, 117418673, 1948706703, -485598135, 385841705, 1725261146, -919553921, 70643668, 2128611684, 1720197347, 738706713, 1162026860, -611442152, 1469145601, 2051653750, 609067755, -1971782890, -971114565, 776260144, 1619791127, -1547233838, 1502505722, 913168193, 1761269649, 81782996, 62251540, 1519079156, 1239007000, 489633356, -800433470, -2107278046, 495320431, 269446836, -2013306553, 1074614697, 1645125348, 584369930, -405429577, 1211134012, -2060113546, -2047824, -443978800, 271218497, -1002185964, 1519315874, -695096464, -79101601, -1521653608, 192426133, 1159511202, -1354494985, -477280535, 583522228, -661741458, -1251175621, -369487281, -2015449518, -2102058930, -645264919, -925270025, -1674575999, 1363844609, -831732660, -1668989157, -1861246633, 83763283, -1056074975, -519054258, -1546386261, 1691674654, -885968657, -1189571815, 2095154843, 1686743191, -1859471265, -261593938, 1721982136, -491120252, -949699153, 642525852, -2005306625, -1004765905, 742736856, 1653443876, 788423835, 1536155740, 879514143, -1510757104, 115238646, 28600662, 1485490803, 1272460710, 523153480, -766782926, 1332478031, 528775440, 302965264, -2046891123, 1108139271, 1611601128, 550846467, -439082190, 1244786747, 941120547, -35568474, 1756370964, 304870369, 1902684028, -408710726, 1673189520, 1180987663, -1488131864, 158973303, 154514890, -1387953397, 1453732833, -1342263302, -628153633, 4710424, 619931109, 721411332, -2135645486, 1688696681, -891749588, -1641122924, 1397432310, -865254619, -1635468227, -1827787970, -1311416657, -1022618057, 1411688086, -1579840139, -637954674, 2115653281, -1155985079, -1043532593, -374286955, -1825883832, -227940643, 1688394137, -524577925, -983222470, -1955769926, 626525757, -2009760930, -1855453635, -676923169, 754966926, -291202391, -2126042921, -1477304277, -1409345382, -1264640578, -441993991, -17611930, -1576809974, 2137694350, 1299022733, -762509116, -1087399293, 819303572, -14571174, -719035481, -1644675278, 1492736905, -15038081, 974773023, 1087127339, 1790024863, -1493135734, 1936273291, -442361741, 1639666948, 1147532756, 174955156, -1537685747, 187972574, 275303083, 1420277149, -1375787574, 1873043153, 38164241, 653451946, 687758113, 899667071, 1722219976, 2146668333, 587401069, -26582672, 2034645447, 1401801794, 1043291001, -1277898614, 2116116828, 1445274301, 150534325, 469242183, -937704471, 171074779, -204638071, 1269913689, -771734064, -12280461, -1182158859, 1704390140, -263303749, -848503723, -1822849148, -634064465, 1130988864, -1515750310, -908815400, 1487214333, 994482967, 853103628, 1711185413, 1520342001, 1067859186, 1693632130, -603831333, 292236742, -800655385, -1467184928, 221125007, -1697377800, 1293953144, 1730537111, 1073329737, 519625212, 689636032, 1127394154, -1496469136, -1214585810, 822152197, -1572579275, -527866383, -996792678, -2058452887, -1133767559, 576275042, 1579109209, -295089371, 1502267384, -724281876, -911879875, 1131096177, 333026744, 1238706603, 1067340063, -745697708, -973992204, 1560446744, -664017057, -616056490, 1099714049, 674159948, 383625825, 1411443110, 1862818263, -1896254899, 1322476914, -719144734, -1540101945, 988154902, 781856577, 2013381051, -2059071359, -142073207, 60252832, 2052050421, -666391497, 376633738, 1663011481, -1706886481, -1870003191, 1003819645, 898131216, 778824906, -656875645, -1730811011, -1751653787, 2056079904, 231977636, 1831419220, -465545074, -1505266471, 1034419975, -133864043, 1876779821, 1879792902, -100100435, -959264741, -472668436, 203584096, -46980157, -1478047098, -979669209, 809008494, 1279644171, 2055793632, 1385672419, -1756428826, -1790481031, -2089665073, -1608595011, 457322987, 1267418945, -19541848, -796352273, -1049973752, 30940894, -539710199, -1097391703, -779353550, -1328320498, -735447662, -918513196, 1516945649, 1218919237, -251287485, 1826366637, 353082340, 889839220, 399638904, -1462573609, -618450466, 1429903706, 2095548034, 1486594475, -1053248922, 74346322, -357998703, 1790710495, -146359619, 1581657509, -797737661, -920778913, 608399665, 646679359, 1861775150, -1014371223, 476735306, -1577737028, 383018939, 1234592859, 344770283, -472763155, 187217985, 1245828866, 1936329359, 61243025, -1979390025, 903671173, 302699505, -1677126111, -1194113496, 835857595, 706998946, 70931462, 1374113464, -1464459699, -231081598, 1366205112, 396990527, -1615015619, -968458597, 457632575, 24361353, -1120685182, 2101590608, 1654666456, -1208442054, 579414359, 1078056578, 217408674, -1560683025, 815178420, 1219326466, 450032327, 774403237, 54597342, -664057229, 447132403, 50603973, 435640301, -1224073863, -1339908037, 1775470944, -1378119263, -1375189988, -1287971162, 29816317, -1313418882, -1824967031, 443540716, 11064217, -1463969487, 1967601549, 124474667, 1230898256, -1741455555, 561643750, 933295231, -923145874, 245538199, 289478386, 200552280, -268887021, -1598221376, 1236123270, 318325803, 773964550, 191670680, 158043961, -762639146, -416703928, -721969492, 1664330785, -584949010, 1509045840, -2066001147, 1728613092, -1103375821, -1262079070, -2034789427, -418216342, -546365126, 1235751589, 1639799329, 2085089663, -697590049, -2007054256, -147701903, 209371702, -1868450893, 1241065116, 1537364837, -1035970557, 318040217, 150492098, 1841159805, -491979749, -1275490577, -1759443566, -697538216, -1589624976, -678703557, -189067001, 1539472677, -1396089831, 271512148, 180483983, 483714313, 703861378, 2122114992, -600097045, 522009268, 160429181, -744428886, 1541223403, -1211039718, -1167643980, 1551471162, -816207368, -1429258613, 1350901561, 1934120609, -961643277, -214772286, -2128270227, -1561239720, 1493926966, 1376671007, 94966082, 221846150, -164351411, -51309876, 497148497, 1233668542, 266257753, -773473851, 953946385, 420815294, -1390653175, 1834391782, 4704447, -891751440, -744104272, -1082756642, 1431640408, -1912055536, -159789461, -704946016, 1956368139, 642279822, -374415338, 1562655802, -272964020, 1071498305, 667364168, -1546405154, 341389690, 1360662999, 377696332, -437020076, -1668574556, 1242655350, -756555890, 645954261, 1914624235, 2134904445, -247737098, 143667521, -17668806, 1804148531, 414247300, 1030053929, -1595215075, 887532426, 553113691, 1173830167, -303724353, -280418143, -1143962122, -1898518451, 36464746, 1189572700, -1549967582, 1093341440, -452303819, -731023001, 1111173883, 1678013973, -836458212, -842956392, 212774049, -845621791, 966282353, -823130040, 700410571, 619075141, -304785045, -1816233676, -1789653997, -166914694, 690663021, -669570330, 1098624444, -987380984, 452844935, -1089825546, 1221160503, 1217375341, 512281644, -1106887134, 1665404458, -1462594714, -207498587, -789271490, -723469709, 512055365, 1445951882, 1692473633, -996873493, 1445046730, 993087194, -1666188562, -897427329, 1008869698, 1236029718, 1499207233, 1704947182, -1815799281, 686399988, -475436580, 1588892458, 884859588, -471913926, -487416631, 1323960741, -1257612174, -468909314, -1866654496, -1417895838, 1707647971, 997140465, -1358794225, 1929422460, -605622778, -1587468566, 469149623, 1121515927, 748484204, 1201983830, -1906623591, 76398473, 261109068, -796025669, -1964466661, 1739898262, -756850622, 1581369453, 1484675811, 484136467, -705983890, -1357931714, 548520423, 741992908, 1017931838, -2078503520, 2097871343, 569233897, -91903627, 1864053450, -876129714, 336670307, -1950420274, -872316480, -662220291, 275724295, 703565412, 1334248646, -217559198, 1044090753, 743502488, -1518545318, 20614180, -768582053, 976522354, -25129962, -983639284, 71722595, -119236393, 368844119, -795808244, 696073964, 1379765302, 235083623, 666280330, -1313689346, -643870520, 534522699, -250414377, -1239276164, 159264592, -1119503518, 1168161619, -1366518946, -1335653301, 248092140, 1390152547, 2051602724, -1023547981, -1479782621, -1785785862, 1609789158, -919124123, 1703200068, -852553456, 1573706142, -376011685, 305068766, -1231775451, -1536883494, -125122369, -896696968, 852651567, -458154391, 747781704, 1173040469, -1569200836, 312506093, -1680530410, 117086271, 794587661, -1231003908, -1048955503, 2119305423, 1636729108, -522378372, 1627421730, 545077470, -1683264872, 1486496559, -1793064672, 1908368749, -1226052295, 1399248776, -588193954, -1289386125, 534647065, 2126245059, -238362987, -1244573058, -1571832269, -2052693379, 1494767731, -528668449, -980826491, -151282847, -1468523556, 1876349941, -301654558, 1467960576, -741720848, -612158589, 92376910, 987915105, 1037689578, 793773489, -1387669541, 349490139, 564784004, -1161242130, 619703053, 2063233129, 190888106, 81845991, -1482466066, 283234313, 114355492, -1879406787, -1283370924, -1378903370, -730141747, 1570738286, -281348873, 2131743196, 795654462, -497365688, 437612465, 1928618254, 1433118279, -1801292119, -2059248836, -221673230, 163637697, -411319468, 244353317, 786753178, 489172932, 464627154, 1258915212, -229028334, -994675463, 1931657329, 1784181437, -97111947, 1728952452, -1329133577, -1606156362, 1341196121, 1679632329, -796545286, -1021125869, 1427825468, -214986389, 250791528, 1029777000, 90661677, 602529506, 2068040879, 1483801763, 2332097, -457467017, 672399614, 1542769193, 1781253216, -1967165705, -2052227925, -1248173215, -1676554121, 292413596, 209649573, 1750689340, 1946874730, -832845570, 1774178655, -450175610, -431901779, 613330756, 1969434259, 1251099237, -1320908513, -50659188, 273178515, -296290724, 1195998469, 1329813722, 759419114, 1003396150, -274557619, -548886303, -2055397788, -766678640, -464045978, -1835907569, -169406709, 820751456, 1778613303, -1582073956, -1728391771, -2075389498, -1606584632, -1702107251, -15724560, 45610235, -1967510298, -671487775, -1841110041, -913365944, 869680052, -798103472, -1564096927, -918899909, -810066882, 428829752, -1413487973, -844240890, 1343914280, -689285374, 1827745702, -799686631, 1696465705, -726159000, -1381157526, 1649221296, 1791106481, -1872852642, -485685063, 1534949133, -1611901907, -581776031, 242740701, -382394666, 668419384, 388297992, 748818886, 713804061, -1783774172, -1823401590, -1009098384, 2071462929, 1154475522, 1309810666, -1734475040, 1212095416, 988288210, -1457428115, 1699730041, -1804729443, -1922824494, 1000076038, -226555981, 131425181, -1071582828, 357680377, 1574190179, 996651958, 965704429, -47651768, 243931978, 808955117, -652323633, 544967309, -1199510217, 702795379, 997685748, 1593927308, 2119371055, 1451401230, -41992913, 2033816081, -1030495962, 1764010175, 457470691, -2001190141, -373358035, -1950331268, -1291674220, 642934467, -1825725718, -1555687487, 1664472129, -24722338, 1899539596, 78519318, 1662555805, 1744711308, -2142888582, -1597853572, 118030659, 1596713428, 404304267, -1350880388, 648702031, 1185458591, 1798138033, 819516445, -1466759682, -751277607, -879817426, -1931050435, 1465603177, -1402344216, 768491239, -1404853657, -1915685264, -1845859847, 313163207, 1239598382, 1988767047, -555152530, -1925665864, -182399255, -1392390808, 64861291, -511875035, 1879964459, 918905020, -840773616, 459610189, -1522352470, -1821396360, 977274705, -60616465, -1846727880, 1208592937, -515359427, 1127607806, -395032287, 491869604, 2053794084, 568321750, 1597027438, 1355613070, -2069482724, 1899252555, 844726247, -625112193, 1146099491, -1037855139, 1203928737, 1875686061, 994108281, 1471873396, 2026801570, 4941446, -1066074241, -983738686, 2037429697, -836521112, -633388883, 1221918725, 2137035208, -369891832, 372509548, -110916409, 80517712, -658056946, 727893428, -1353651002, -475459562, -291323023, 1059377566, 591801919, 1018232602, -348255729, 1863827426, 246032476, -1026132864, -1356383176, -1224690998, 262442981, 1257773681, -1738604660, 77131430, -1320261233, -2342727, -1817187590, -1883997191, 1367221809, -1863623746, -1132606249, 149024763, -1228275128, -578030399, 356914163, 2109691820, -880313621 }; for (int i = 0; i < refInt.length; ++i) { Assert.assertEquals(refInt[i], mt.nextInt()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/AbstractRandomGeneratorTest.java100644 1750 1750 11256 11532241241 32156 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.stat.Frequency; /** * Test cases for the AbstractRandomGenerator class * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class AbstractRandomGeneratorTest extends RandomDataTest { protected TestRandomGenerator testGenerator = new TestRandomGenerator(); public AbstractRandomGeneratorTest(String name) { super(name); randomData = new RandomDataImpl(testGenerator); } @Override public void testNextInt() { try { testGenerator.nextInt(-1); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } Frequency freq = new Frequency(); int value = 0; for (int i=0; i= 0) && (value <= 3)); freq.addValue(value); } long[] observed = new long[4]; for (int i=0; i<4; i++) { observed[i] = freq.getCount(i); } /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001 * Change to 11.34 for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected,observed) < 16.27); } @Override public void testNextLong() { long q1 = Long.MAX_VALUE/4; long q2 = 2 * q1; long q3 = 3 * q1; Frequency freq = new Frequency(); long val = 0; int value = 0; for (int i=0; i= 0) && (value <= 3)); freq.addValue(value); } long[] observed = new long[4]; for (int i = 0; i < 4; i++) { observed[i] = freq.getCount(i); } /* * Use ChiSquare dist with df = 4-1 = 3, alpha = .001 Change to 11.34 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 16.27); } /** test dispersion and failure modes for nextLong() */ public void testNextLong() { try { randomData.nextLong(4, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } Frequency freq = new Frequency(); long value = 0; for (int i = 0; i < smallSampleSize; i++) { value = randomData.nextLong(0, 3); assertTrue("nextInt range", (value >= 0) && (value <= 3)); freq.addValue(value); } long[] observed = new long[4]; for (int i = 0; i < 4; i++) { observed[i] = freq.getCount(i); } /* * Use ChiSquare dist with df = 4-1 = 3, alpha = .001 Change to 11.34 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 16.27); } /** test dispersion and failure modes for nextSecureLong() */ public void testNextSecureLong() { try { randomData.nextSecureLong(4, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } Frequency freq = new Frequency(); long value = 0; for (int i = 0; i < smallSampleSize; i++) { value = randomData.nextSecureLong(0, 3); assertTrue("nextInt range", (value >= 0) && (value <= 3)); freq.addValue(value); } long[] observed = new long[4]; for (int i = 0; i < 4; i++) { observed[i] = freq.getCount(i); } /* * Use ChiSquare dist with df = 4-1 = 3, alpha = .001 Change to 11.34 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 16.27); } /** test dispersion and failure modes for nextSecureInt() */ public void testNextSecureInt() { try { randomData.nextSecureInt(4, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } Frequency freq = new Frequency(); int value = 0; for (int i = 0; i < smallSampleSize; i++) { value = randomData.nextSecureInt(0, 3); assertTrue("nextInt range", (value >= 0) && (value <= 3)); freq.addValue(value); } long[] observed = new long[4]; for (int i = 0; i < 4; i++) { observed[i] = freq.getCount(i); } /* * Use ChiSquare dist with df = 4-1 = 3, alpha = .001 Change to 11.34 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 16.27); } /** * Make sure that empirical distribution of random Poisson(4)'s has P(X <= * 5) close to actual cumulative Poisson probability and that nextPoisson * fails when mean is non-positive TODO: replace with statistical test, * adding test stat to TestStatistic */ public void testNextPoisson() { try { randomData.nextPoisson(0); fail("zero mean -- expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } Frequency f = new Frequency(); for (int i = 0; i < largeSampleSize; i++) { f.addValue(randomData.nextPoisson(4.0d)); } long cumFreq = f.getCount(0) + f.getCount(1) + f.getCount(2) + f.getCount(3) + f.getCount(4) + f.getCount(5); long sumFreq = f.getSumFreq(); double cumPct = Double.valueOf(cumFreq).doubleValue() / Double.valueOf(sumFreq).doubleValue(); assertEquals("cum Poisson(4)", cumPct, 0.7851, 0.2); try { randomData.nextPoisson(-1); fail("negative mean supplied -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } try { randomData.nextPoisson(0); fail("0 mean supplied -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } public void testNextPoissonConsistency() throws Exception { // Reseed randomGenerator to get fixed sequence randomData.reSeed(1000); // Small integral means for (int i = 1; i < 100; i++) { checkNextPoissonConsistency(i); } // non-integer means for (int i = 1; i < 10; i++) { checkNextPoissonConsistency(randomData.nextUniform(1, 1000)); } // large means // TODO: When MATH-282 is resolved, s/3000/10000 below for (int i = 1; i < 10; i++) { checkNextPoissonConsistency(randomData.nextUniform(1000, 3000)); } } /** * Verifies that nextPoisson(mean) generates an empirical distribution of values * consistent with PoissonDistributionImpl by generating 1000 values, computing a * grouped frequency distribution of the observed values and comparing this distribution * to the corresponding expected distribution computed using PoissonDistributionImpl. * Uses ChiSquare test of goodness of fit to evaluate the null hypothesis that the * distributions are the same. If the null hypothesis can be rejected with confidence * 1 - alpha, the check fails. */ public void checkNextPoissonConsistency(double mean) throws Exception { // Generate sample values final int sampleSize = 1000; // Number of deviates to generate final int minExpectedCount = 7; // Minimum size of expected bin count long maxObservedValue = 0; final double alpha = 0.001; // Probability of false failure Frequency frequency = new Frequency(); for (int i = 0; i < sampleSize; i++) { long value = randomData.nextPoisson(mean); if (value > maxObservedValue) { maxObservedValue = value; } frequency.addValue(value); } /* * Set up bins for chi-square test. * Ensure expected counts are all at least minExpectedCount. * Start with upper and lower tail bins. * Lower bin = [0, lower); Upper bin = [upper, +inf). */ PoissonDistribution poissonDistribution = new PoissonDistributionImpl(mean); int lower = 1; while (poissonDistribution.cumulativeProbability(lower - 1) * sampleSize < minExpectedCount) { lower++; } int upper = (int) (5 * mean); // Even for mean = 1, not much mass beyond 5 while ((1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize < minExpectedCount) { upper--; } // Set bin width for interior bins. For poisson, only need to look at end bins. int binWidth = 1; boolean widthSufficient = false; double lowerBinMass = 0; double upperBinMass = 0; while (!widthSufficient) { lowerBinMass = poissonDistribution.cumulativeProbability(lower, lower + binWidth - 1); upperBinMass = poissonDistribution.cumulativeProbability(upper - binWidth + 1, upper); widthSufficient = FastMath.min(lowerBinMass, upperBinMass) * sampleSize >= minExpectedCount; binWidth++; } /* * Determine interior bin bounds. Bins are * [1, lower = binBounds[0]), [lower, binBounds[1]), [binBounds[1], binBounds[2]), ... , * [binBounds[binCount - 2], upper = binBounds[binCount - 1]), [upper, +inf) * */ List binBounds = new ArrayList(); binBounds.add(lower); int bound = lower + binWidth; while (bound < upper - binWidth) { binBounds.add(bound); bound += binWidth; } binBounds.add(bound); binBounds.add(upper); // Compute observed and expected bin counts final int binCount = binBounds.size() + 1; long[] observed = new long[binCount]; double[] expected = new double[binCount]; // Bottom bin observed[0] = 0; for (int i = 0; i < lower; i++) { observed[0] += frequency.getCount(i); } expected[0] = poissonDistribution.cumulativeProbability(lower - 1) * sampleSize; // Top bin observed[binCount - 1] = 0; for (int i = upper; i <= maxObservedValue; i++) { observed[binCount - 1] += frequency.getCount(i); } expected[binCount - 1] = (1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize; // Interior bins for (int i = 1; i < binCount - 1; i++) { observed[i] = 0; for (int j = binBounds.get(i - 1); j < binBounds.get(i); j++) { observed[i] += frequency.getCount(j); } // Expected count is (mass in [binBounds[i], binBounds[i+1])) * sampleSize expected[i] = (poissonDistribution.cumulativeProbability(binBounds.get(i) - 1) - poissonDistribution.cumulativeProbability(binBounds.get(i - 1) -1)) * sampleSize; } // Use chisquare test to verify that generated values are poisson(mean)-distributed ChiSquareTest chiSquareTest = new ChiSquareTestImpl(); try { // Fail if we can reject null hypothesis that distributions are the same assertFalse(chiSquareTest.chiSquareTest(expected, observed, alpha)); } catch (AssertionFailedError ex) { StringBuilder msgBuffer = new StringBuilder(); DecimalFormat df = new DecimalFormat("#.##"); msgBuffer.append("Chisquare test failed for mean = "); msgBuffer.append(mean); msgBuffer.append(" p-value = "); msgBuffer.append(chiSquareTest.chiSquareTest(expected, observed)); msgBuffer.append(" chisquare statistic = "); msgBuffer.append(chiSquareTest.chiSquare(expected, observed)); msgBuffer.append(". \n"); msgBuffer.append("bin\t\texpected\tobserved\n"); for (int i = 0; i < expected.length; i++) { msgBuffer.append("["); msgBuffer.append(i == 0 ? 1: binBounds.get(i - 1)); msgBuffer.append(","); msgBuffer.append(i == binBounds.size() ? "inf": binBounds.get(i)); msgBuffer.append(")"); msgBuffer.append("\t\t"); msgBuffer.append(df.format(expected[i])); msgBuffer.append("\t\t"); msgBuffer.append(observed[i]); msgBuffer.append("\n"); } msgBuffer.append("This test can fail randomly due to sampling error with probability "); msgBuffer.append(alpha); msgBuffer.append("."); fail(msgBuffer.toString()); } } /** test dispersion and failure modes for nextHex() */ public void testNextHex() { try { randomData.nextHexString(-1); fail("negative length supplied -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } try { randomData.nextHexString(0); fail("zero length supplied -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } String hexString = randomData.nextHexString(3); if (hexString.length() != 3) { fail("incorrect length for generated string"); } hexString = randomData.nextHexString(1); if (hexString.length() != 1) { fail("incorrect length for generated string"); } try { hexString = randomData.nextHexString(0); fail("zero length requested -- expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } if (hexString.length() != 1) { fail("incorrect length for generated string"); } Frequency f = new Frequency(); for (int i = 0; i < smallSampleSize; i++) { hexString = randomData.nextHexString(100); if (hexString.length() != 100) { fail("incorrect length for generated string"); } for (int j = 0; j < hexString.length(); j++) { f.addValue(hexString.substring(j, j + 1)); } } double[] expected = new double[16]; long[] observed = new long[16]; for (int i = 0; i < 16; i++) { expected[i] = (double) smallSampleSize * 100 / 16; observed[i] = f.getCount(hex[i]); } /* * Use ChiSquare dist with df = 16-1 = 15, alpha = .001 Change to 30.58 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 37.70); } /** test dispersion and failure modes for nextHex() */ public void testNextSecureHex() { try { randomData.nextSecureHexString(-1); fail("negative length -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } try { randomData.nextSecureHexString(0); fail("zero length -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } String hexString = randomData.nextSecureHexString(3); if (hexString.length() != 3) { fail("incorrect length for generated string"); } hexString = randomData.nextSecureHexString(1); if (hexString.length() != 1) { fail("incorrect length for generated string"); } try { hexString = randomData.nextSecureHexString(0); fail("zero length requested -- expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } if (hexString.length() != 1) { fail("incorrect length for generated string"); } Frequency f = new Frequency(); for (int i = 0; i < smallSampleSize; i++) { hexString = randomData.nextSecureHexString(100); if (hexString.length() != 100) { fail("incorrect length for generated string"); } for (int j = 0; j < hexString.length(); j++) { f.addValue(hexString.substring(j, j + 1)); } } double[] expected = new double[16]; long[] observed = new long[16]; for (int i = 0; i < 16; i++) { expected[i] = (double) smallSampleSize * 100 / 16; observed[i] = f.getCount(hex[i]); } /* * Use ChiSquare dist with df = 16-1 = 15, alpha = .001 Change to 30.58 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 37.70); } /** test failure modes and dispersion of nextUniform() */ public void testNextUniform() { try { randomData.nextUniform(4, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } try { randomData.nextUniform(3, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } double[] expected = { 500, 500 }; long[] observed = { 0, 0 }; double lower = -1d; double upper = 20d; double midpoint = (lower + upper) / 2d; double result = 0; for (int i = 0; i < 1000; i++) { result = randomData.nextUniform(lower, upper); if ((result == lower) || (result == upper)) { fail("generated value equal to an endpoint: " + result); } if (result < midpoint) { observed[0]++; } else { observed[1]++; } } /* * Use ChiSquare dist with df = 2-1 = 1, alpha = .001 Change to 6.64 for * alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 10.83); } /** test exclusive endpoints of nextUniform **/ public void testNextUniformExclusiveEndpoints() { for (int i = 0; i < 1000; i++) { double u = randomData.nextUniform(0.99, 1); assertTrue(u > 0.99 && u < 1); } } /** test failure modes and distribution of nextGaussian() */ public void testNextGaussian() { try { randomData.nextGaussian(0, 0); fail("zero sigma -- IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } SummaryStatistics u = new SummaryStatistics(); for (int i = 0; i < largeSampleSize; i++) { u.addValue(randomData.nextGaussian(0, 1)); } double xbar = u.getMean(); double s = u.getStandardDeviation(); double n = u.getN(); /* * t-test at .001-level TODO: replace with externalized t-test, with * test statistic defined in TestStatistic */ assertTrue(FastMath.abs(xbar) / (s / FastMath.sqrt(n)) < 3.29); } /** test failure modes and distribution of nextExponential() */ public void testNextExponential() { try { randomData.nextExponential(-1); fail("negative mean -- expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { randomData.nextExponential(0); fail("zero mean -- expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } long cumFreq = 0; double v = 0; for (int i = 0; i < largeSampleSize; i++) { v = randomData.nextExponential(1); assertTrue("exponential deviate postive", v > 0); if (v < 2) cumFreq++; } /* * TODO: Replace with a statistical test, with statistic added to * TestStatistic. Check below compares observed cumulative distribution * evaluated at 2 with exponential CDF */ assertEquals("exponential cumulative distribution", (double) cumFreq / (double) largeSampleSize, 0.8646647167633873, .2); } /** test reseeding, algorithm/provider games */ public void testConfig() { randomData.reSeed(1000); double v = randomData.nextUniform(0, 1); randomData.reSeed(); assertTrue("different seeds", Math .abs(v - randomData.nextUniform(0, 1)) > 10E-12); randomData.reSeed(1000); assertEquals("same seeds", v, randomData.nextUniform(0, 1), 10E-12); randomData.reSeedSecure(1000); String hex = randomData.nextSecureHexString(40); randomData.reSeedSecure(); assertTrue("different seeds", !hex.equals(randomData .nextSecureHexString(40))); randomData.reSeedSecure(1000); assertTrue("same seeds", !hex .equals(randomData.nextSecureHexString(40))); /* * remove this test back soon, since it takes about 4 seconds * * try { randomData.setSecureAlgorithm("SHA1PRNG","SUN"); } catch * (NoSuchProviderException ex) { ; } assertTrue("different seeds", * !hex.equals(randomData.nextSecureHexString(40))); try { * randomData.setSecureAlgorithm("NOSUCHTHING","SUN"); * fail("expecting NoSuchAlgorithmException"); } catch * (NoSuchProviderException ex) { ; } catch (NoSuchAlgorithmException * ex) { ; } * * try { randomData.setSecureAlgorithm("SHA1PRNG","NOSUCHPROVIDER"); * fail("expecting NoSuchProviderException"); } catch * (NoSuchProviderException ex) { ; } */ // test reseeding without first using the generators RandomDataImpl rd = new RandomDataImpl(); rd.reSeed(100); rd.nextLong(1, 2); RandomDataImpl rd2 = new RandomDataImpl(); rd2.reSeedSecure(2000); rd2.nextSecureLong(1, 2); rd = new RandomDataImpl(); rd.reSeed(); rd.nextLong(1, 2); rd2 = new RandomDataImpl(); rd2.reSeedSecure(); rd2.nextSecureLong(1, 2); } /** tests for nextSample() sampling from Collection */ public void testNextSample() { Object[][] c = { { "0", "1" }, { "0", "2" }, { "0", "3" }, { "0", "4" }, { "1", "2" }, { "1", "3" }, { "1", "4" }, { "2", "3" }, { "2", "4" }, { "3", "4" } }; long[] observed = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; double[] expected = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }; HashSet cPop = new HashSet(); // {0,1,2,3,4} for (int i = 0; i < 5; i++) { cPop.add(Integer.toString(i)); } Object[] sets = new Object[10]; // 2-sets from 5 for (int i = 0; i < 10; i++) { HashSet hs = new HashSet(); hs.add(c[i][0]); hs.add(c[i][1]); sets[i] = hs; } for (int i = 0; i < 1000; i++) { Object[] cSamp = randomData.nextSample(cPop, 2); observed[findSample(sets, cSamp)]++; } /* * Use ChiSquare dist with df = 10-1 = 9, alpha = .001 Change to 21.67 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 27.88); // Make sure sample of size = size of collection returns same collection HashSet hs = new HashSet(); hs.add("one"); Object[] one = randomData.nextSample(hs, 1); String oneString = (String) one[0]; if ((one.length != 1) || !oneString.equals("one")) { fail("bad sample for set size = 1, sample size = 1"); } // Make sure we fail for sample size > collection size try { one = randomData.nextSample(hs, 2); fail("sample size > set size, expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } // Make sure we fail for empty collection try { hs = new HashSet(); one = randomData.nextSample(hs, 0); fail("n = k = 0, expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } @SuppressWarnings("unchecked") private int findSample(Object[] u, Object[] samp) { for (int i = 0; i < u.length; i++) { HashSet set = (HashSet) u[i]; HashSet sampSet = new HashSet(); for (int j = 0; j < samp.length; j++) { sampSet.add(samp[j]); } if (set.equals(sampSet)) { return i; } } fail("sample not found:{" + samp[0] + "," + samp[1] + "}"); return -1; } /** tests for nextPermutation */ public void testNextPermutation() { int[][] p = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 }, { 2, 0, 1 }, { 2, 1, 0 } }; long[] observed = { 0, 0, 0, 0, 0, 0 }; double[] expected = { 100, 100, 100, 100, 100, 100 }; for (int i = 0; i < 600; i++) { int[] perm = randomData.nextPermutation(3, 3); observed[findPerm(p, perm)]++; } /* * Use ChiSquare dist with df = 6-1 = 5, alpha = .001 Change to 15.09 * for alpha = .01 */ assertTrue("chi-square test -- will fail about 1 in 1000 times", testStatistic.chiSquare(expected, observed) < 20.52); // Check size = 1 boundary case int[] perm = randomData.nextPermutation(1, 1); if ((perm.length != 1) || (perm[0] != 0)) { fail("bad permutation for n = 1, sample k = 1"); // Make sure we fail for k size > n try { perm = randomData.nextPermutation(2, 3); fail("permutation k > n, expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } // Make sure we fail for n = 0 try { perm = randomData.nextPermutation(0, 0); fail("permutation k = n = 0, expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } // Make sure we fail for k < n < 0 try { perm = randomData.nextPermutation(-1, -3); fail("permutation k < n < 0, expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } } // Disable until we have equals //public void testSerial() { // assertEquals(randomData, TestUtils.serializeAndRecover(randomData)); //} private int findPerm(int[][] p, int[] samp) { for (int i = 0; i < p.length; i++) { boolean good = true; for (int j = 0; j < samp.length; j++) { if (samp[j] != p[i][j]) { good = false; } } if (good) { return i; } } fail("permutation not found"); return -1; } public void testNextInversionDeviate() throws Exception { // Set the seed for the default random generator randomData.reSeed(100); double[] quantiles = new double[10]; for (int i = 0; i < 10; i++) { quantiles[i] = randomData.nextUniform(0, 1); } // Reseed again so the inversion generator gets the same sequence randomData.reSeed(100); BetaDistributionImpl betaDistribution = new BetaDistributionImpl(2, 4); /* * Generate a sequence of deviates using inversion - the distribution function * evaluated at the random value from the distribution should match the uniform * random value used to generate it, which is stored in the quantiles[] array. */ for (int i = 0; i < 10; i++) { double value = randomData.nextInversionDeviate(betaDistribution); assertEquals(betaDistribution.cumulativeProbability(value), quantiles[i], 10E-9); } } public void testNextBeta() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new BetaDistributionImpl(2,5)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextBeta(2, 5); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextCauchy() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new CauchyDistributionImpl(1.2, 2.1)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextCauchy(1.2, 2.1); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextChiSquare() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new ChiSquaredDistributionImpl(12)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextChiSquare(12); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextF() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new FDistributionImpl(12, 5)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextF(12, 5); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextGamma() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new GammaDistributionImpl(4, 2)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextGamma(4, 2); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextT() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new TDistributionImpl(10)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextT(10); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextWeibull() throws Exception { double[] quartiles = TestUtils.getDistributionQuartiles(new WeibullDistributionImpl(1.2, 2.1)); long[] counts = new long[4]; randomData.reSeed(1000); for (int i = 0; i < 1000; i++) { double value = randomData.nextWeibull(1.2, 2.1); TestUtils.updateCounts(value, counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } public void testNextBinomial() throws Exception { BinomialDistributionTest testInstance = new BinomialDistributionTest(""); int[] densityPoints = testInstance.makeDensityTestPoints(); double[] densityValues = testInstance.makeDensityTestValues(); int sampleSize = 1000; int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues); BinomialDistributionImpl distribution = (BinomialDistributionImpl) testInstance.makeDistribution(); double[] expectedCounts = new double[length]; long[] observedCounts = new long[length]; for (int i = 0; i < length; i++) { expectedCounts[i] = sampleSize * densityValues[i]; } randomData.reSeed(1000); for (int i = 0; i < sampleSize; i++) { int value = randomData.nextBinomial(distribution.getNumberOfTrials(), distribution.getProbabilityOfSuccess()); for (int j = 0; j < length; j++) { if (value == densityPoints[j]) { observedCounts[j]++; } } } TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001); } public void testNextHypergeometric() throws Exception { HypergeometricDistributionTest testInstance = new HypergeometricDistributionTest(""); int[] densityPoints = testInstance.makeDensityTestPoints(); double[] densityValues = testInstance.makeDensityTestValues(); int sampleSize = 1000; int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues); HypergeometricDistributionImpl distribution = (HypergeometricDistributionImpl) testInstance.makeDistribution(); double[] expectedCounts = new double[length]; long[] observedCounts = new long[length]; for (int i = 0; i < length; i++) { expectedCounts[i] = sampleSize * densityValues[i]; } randomData.reSeed(1000); for (int i = 0; i < sampleSize; i++) { int value = randomData.nextHypergeometric(distribution.getPopulationSize(), distribution.getNumberOfSuccesses(), distribution.getSampleSize()); for (int j = 0; j < length; j++) { if (value == densityPoints[j]) { observedCounts[j]++; } } } TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001); } public void testNextPascal() throws Exception { PascalDistributionTest testInstance = new PascalDistributionTest(""); int[] densityPoints = testInstance.makeDensityTestPoints(); double[] densityValues = testInstance.makeDensityTestValues(); int sampleSize = 1000; int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues); PascalDistributionImpl distribution = (PascalDistributionImpl) testInstance.makeDistribution(); double[] expectedCounts = new double[length]; long[] observedCounts = new long[length]; for (int i = 0; i < length; i++) { expectedCounts[i] = sampleSize * densityValues[i]; } randomData.reSeed(1000); for (int i = 0; i < sampleSize; i++) { int value = randomData.nextPascal(distribution.getNumberOfSuccesses(), distribution.getProbabilityOfSuccess()); for (int j = 0; j < length; j++) { if (value == densityPoints[j]) { observedCounts[j]++; } } } TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001); } public void testNextZipf() throws Exception { ZipfDistributionTest testInstance = new ZipfDistributionTest(""); int[] densityPoints = testInstance.makeDensityTestPoints(); double[] densityValues = testInstance.makeDensityTestValues(); int sampleSize = 1000; int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues); ZipfDistributionImpl distribution = (ZipfDistributionImpl) testInstance.makeDistribution(); double[] expectedCounts = new double[length]; long[] observedCounts = new long[length]; for (int i = 0; i < length; i++) { expectedCounts[i] = sampleSize * densityValues[i]; } randomData.reSeed(1000); for (int i = 0; i < sampleSize; i++) { int value = randomData.nextZipf(distribution.getNumberOfElements(), distribution.getExponent()); for (int j = 0; j < length; j++) { if (value == densityPoints[j]) { observedCounts[j]++; } } } TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java100644 1750 1750 22533 11532241241 31710 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import org.apache.commons.math.RetryTestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Test cases for the EmpiricalDistribution class * * @version $Revision: 1003907 $ $Date: 2010-10-03 00:23:34 +0200 (dim. 03 oct. 2010) $ */ public final class EmpiricalDistributionTest extends RetryTestCase { protected EmpiricalDistribution empiricalDistribution = null; protected EmpiricalDistribution empiricalDistribution2 = null; protected File file = null; protected URL url = null; protected double[] dataArray = null; public EmpiricalDistributionTest(String name) { super(name); } @Override public void setUp() throws IOException { empiricalDistribution = new EmpiricalDistributionImpl(100); url = getClass().getResource("testData.txt"); empiricalDistribution2 = new EmpiricalDistributionImpl(100); BufferedReader in = new BufferedReader(new InputStreamReader( url.openStream())); String str = null; ArrayList list = new ArrayList(); while ((str = in.readLine()) != null) { list.add(Double.valueOf(str)); } in.close(); in = null; dataArray = new double[list.size()]; int i = 0; for (Double data : list) { dataArray[i] = data.doubleValue(); i++; } } /** * Test EmpiricalDistrbution.load() using sample data file.
        * Check that the sampleCount, mu and sigma match data in * the sample data file. */ public void testLoad() throws Exception { empiricalDistribution.load(url); // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1 // Make sure that loaded distribution matches this assertEquals(empiricalDistribution.getSampleStats().getN(),1000,10E-7); //TODO: replace with statistical tests assertEquals (empiricalDistribution.getSampleStats().getMean(), 5.069831575018909,10E-7); assertEquals (empiricalDistribution.getSampleStats().getStandardDeviation(), 1.0173699343977738,10E-7); } /** * Test EmpiricalDistrbution.load(double[]) using data taken from * sample data file.
        * Check that the sampleCount, mu and sigma match data in * the sample data file. */ public void testDoubleLoad() throws Exception { empiricalDistribution2.load(dataArray); // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1 // Make sure that loaded distribution matches this assertEquals(empiricalDistribution2.getSampleStats().getN(),1000,10E-7); //TODO: replace with statistical tests assertEquals (empiricalDistribution2.getSampleStats().getMean(), 5.069831575018909,10E-7); assertEquals (empiricalDistribution2.getSampleStats().getStandardDeviation(), 1.0173699343977738,10E-7); double[] bounds = ((EmpiricalDistributionImpl) empiricalDistribution2).getGeneratorUpperBounds(); assertEquals(bounds.length, 100); assertEquals(bounds[99], 1.0, 10e-12); } /** * Generate 1000 random values and make sure they look OK.
        * Note that there is a non-zero (but very small) probability that * these tests will fail even if the code is working as designed. */ public void testNext() throws Exception { tstGen(0.1); tstDoubleGen(0.1); } /** * Make sure exception thrown if digest getNext is attempted * before loading empiricalDistribution. */ public void testNexFail() { try { empiricalDistribution.getNextValue(); empiricalDistribution2.getNextValue(); fail("Expecting IllegalStateException"); } catch (IllegalStateException ex) { // expected } } /** * Make sure we can handle a grid size that is too fine */ public void testGridTooFine() throws Exception { empiricalDistribution = new EmpiricalDistributionImpl(1001); tstGen(0.1); empiricalDistribution2 = new EmpiricalDistributionImpl(1001); tstDoubleGen(0.1); } /** * How about too fat? */ public void testGridTooFat() throws Exception { empiricalDistribution = new EmpiricalDistributionImpl(1); tstGen(5); // ridiculous tolerance; but ridiculous grid size // really just checking to make sure we do not bomb empiricalDistribution2 = new EmpiricalDistributionImpl(1); tstDoubleGen(5); } /** * Test bin index overflow problem (BZ 36450) */ public void testBinIndexOverflow() throws Exception { double[] x = new double[] {9474.94326071674, 2080107.8865462579}; new EmpiricalDistributionImpl().load(x); } public void testSerialization() { // Empty EmpiricalDistribution dist = new EmpiricalDistributionImpl(); EmpiricalDistribution dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(dist); verifySame(dist, dist2); // Loaded empiricalDistribution2.load(dataArray); dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(empiricalDistribution2); verifySame(empiricalDistribution2, dist2); } public void testLoadNullDoubleArray() { EmpiricalDistribution dist = new EmpiricalDistributionImpl(); try { dist.load((double[]) null); fail("load((double[]) null) expected NullPointerException"); } catch (NullPointerException e) { // expected } } public void testLoadNullURL() throws Exception { EmpiricalDistribution dist = new EmpiricalDistributionImpl(); try { dist.load((URL) null); fail("load((URL) null) expected NullPointerException"); } catch (NullPointerException e) { // expected } } public void testLoadNullFile() throws Exception { EmpiricalDistribution dist = new EmpiricalDistributionImpl(); try { dist.load((File) null); fail("load((File) null) expected NullPointerException"); } catch (NullPointerException e) { // expected } } /** * MATH-298 */ public void testGetBinUpperBounds() { double[] testData = {0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10}; EmpiricalDistributionImpl dist = new EmpiricalDistributionImpl(5); dist.load(testData); double[] expectedBinUpperBounds = {2, 4, 6, 8, 10}; double[] expectedGeneratorUpperBounds = {4d/13d, 7d/13d, 9d/13d, 11d/13d, 1}; double tol = 10E-12; TestUtils.assertEquals(expectedBinUpperBounds, dist.getUpperBounds(), tol); TestUtils.assertEquals(expectedGeneratorUpperBounds, dist.getGeneratorUpperBounds(), tol); } private void verifySame(EmpiricalDistribution d1, EmpiricalDistribution d2) { assertEquals(d1.isLoaded(), d2.isLoaded()); assertEquals(d1.getBinCount(), d2.getBinCount()); assertEquals(d1.getSampleStats(), d2.getSampleStats()); if (d1.isLoaded()) { for (int i = 0; i < d1.getUpperBounds().length; i++) { assertEquals(d1.getUpperBounds()[i], d2.getUpperBounds()[i], 0); } assertEquals(d1.getBinStats(), d2.getBinStats()); } } private void tstGen(double tolerance)throws Exception { empiricalDistribution.load(url); SummaryStatistics stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { stats.addValue(empiricalDistribution.getNextValue()); } assertEquals("mean", stats.getMean(),5.069831575018909,tolerance); assertEquals ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance); } private void tstDoubleGen(double tolerance)throws Exception { empiricalDistribution2.load(dataArray); SummaryStatistics stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { stats.addValue(empiricalDistribution2.getNextValue()); } assertEquals("mean", stats.getMean(),5.069831575018909,tolerance); assertEquals ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/RealMatrixImplTest.java100644 1750 1750 113602 11532241243 30307 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link RealMatrixImpl} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ @Deprecated public final class RealMatrixImplTest extends TestCase { // 3 x 3 identity matrix protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} }; // Test data for group operations protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} }; protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}}; protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} }; protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d}, {-1d,0d,-8d} }; protected double[] testDataRow1 = {1d,2d,3d}; protected double[] testDataCol3 = {3d,3d,8d}; protected double[][] testDataInv = { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} }; protected double[] preMultTest = {8,12,33}; protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}}; protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}}; protected double[][] testDataPlusInv = { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} }; // lu decomposition tests protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} }; protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d}, {0.33333333333333,0d,0.33333333333333} }; // singular matrices protected double[][] singular = { {2d,3d}, {2d,3d} }; protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d}, {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} }; protected double[][] detData2 = { {1d, 3d}, {2d, 4d}}; // vectors protected double[] testVector = {1,2,3}; protected double[] testVector2 = {1,2,3,4}; // submatrix accessor tests protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5}, {2, 4, 6, 8}, {4, 5, 6, 7}}; // array selections protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}}; protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}}; protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}}; // effective permutations protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}}; protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}}; // contiguous ranges protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}}; protected double[][] subRows23Cols00 = {{2} , {4}}; protected double[][] subRows00Cols33 = {{4}}; // row matrices protected double[][] subRow0 = {{1,2,3,4}}; protected double[][] subRow3 = {{4,5,6,7}}; // column matrices protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}}; protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public RealMatrixImplTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(testData2); assertEquals("testData row dimension",3,m.getRowDimension()); assertEquals("testData column dimension",3,m.getColumnDimension()); assertTrue("testData is square",m.isSquare()); assertEquals("testData2 row dimension",m2.getRowDimension(),2); assertEquals("testData2 column dimension",m2.getColumnDimension(),3); assertTrue("testData2 is not square",!m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { RealMatrixImpl m1 = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(m1.getData()); assertEquals(m2,m1); RealMatrixImpl m3 = new RealMatrixImpl(testData); RealMatrixImpl m4 = new RealMatrixImpl(m3.getData(), false); assertEquals(m4,m3); } /** test add */ public void testAdd() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl mInv = new RealMatrixImpl(testDataInv); RealMatrix mPlusMInv = m.add(mInv); double[][] sumEntries = mPlusMInv.getData(); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals("sum entry entry", testDataPlusInv[row][col],sumEntries[row][col], entryTolerance); } } } /** test add failure */ public void testAddFail() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test norm */ public void testNorm() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(testData2); assertEquals("testData norm",14d,m.getNorm(),entryTolerance); assertEquals("testData2 norm",7d,m2.getNorm(),entryTolerance); } /** test Frobenius norm */ public void testFrobeniusNorm() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(testData2); assertEquals("testData Frobenius norm", FastMath.sqrt(117.0), m.getFrobeniusNorm(), entryTolerance); assertEquals("testData2 Frobenius norm", FastMath.sqrt(52.0), m2.getFrobeniusNorm(), entryTolerance); } /** test m-n = m + -n */ public void testPlusMinus() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m2 = new RealMatrixImpl(testDataInv); TestUtils.assertEquals("m-n = m + -n",m.subtract(m2), m2.scalarMultiply(-1d).add(m),entryTolerance); try { m.subtract(new RealMatrixImpl(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl mInv = new RealMatrixImpl(testDataInv); RealMatrixImpl identity = new RealMatrixImpl(id); RealMatrixImpl m2 = new RealMatrixImpl(testData2); TestUtils.assertEquals("inverse multiply",m.multiply(mInv), identity,entryTolerance); TestUtils.assertEquals("inverse multiply",mInv.multiply(m), identity,entryTolerance); TestUtils.assertEquals("identity multiply",m.multiply(identity), m,entryTolerance); TestUtils.assertEquals("identity multiply",identity.multiply(mInv), mInv,entryTolerance); TestUtils.assertEquals("identity multiply",m2.multiply(identity), m2,entryTolerance); try { m.multiply(new RealMatrixImpl(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } //Additional Test for RealMatrixImplTest.testMultiply private double[][] d3 = new double[][] {{1,2,3,4},{5,6,7,8}}; private double[][] d4 = new double[][] {{1},{2},{3},{4}}; private double[][] d5 = new double[][] {{30},{70}}; public void testMultiply2() { RealMatrix m3 = new RealMatrixImpl(d3); RealMatrix m4 = new RealMatrixImpl(d4); RealMatrix m5 = new RealMatrixImpl(d5); TestUtils.assertEquals("m3*m4=m5", m3.multiply(m4), m5, entryTolerance); } /** test trace */ public void testTrace() { RealMatrix m = new RealMatrixImpl(id); assertEquals("identity trace",3d,m.getTrace(),entryTolerance); m = new RealMatrixImpl(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test sclarAdd */ public void testScalarAdd() { RealMatrix m = new RealMatrixImpl(testData); TestUtils.assertEquals("scalar add",new RealMatrixImpl(testDataPlus2), m.scalarAdd(2d),entryTolerance); } /** test operate */ public void testOperate() { RealMatrix m = new RealMatrixImpl(id); TestUtils.assertEquals("identity operate", testVector, m.operate(testVector), entryTolerance); TestUtils.assertEquals("identity operate", testVector, m.operate(new ArrayRealVector(testVector)).getData(), entryTolerance); m = new RealMatrixImpl(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test issue MATH-209 */ public void testMath209() { RealMatrix a = new RealMatrixImpl(new double[][] { { 1, 2 }, { 3, 4 }, { 5, 6 } }, false); double[] b = a.operate(new double[] { 1, 1 }); assertEquals(a.getRowDimension(), b.length); assertEquals( 3.0, b[0], 1.0e-12); assertEquals( 7.0, b[1], 1.0e-12); assertEquals(11.0, b[2], 1.0e-12); } /** test transpose */ public void testTranspose() { RealMatrix m = new RealMatrixImpl(testData); RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose(); RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse(); TestUtils.assertEquals("inverse-transpose", mIT, mTI, normTolerance); m = new RealMatrixImpl(testData2); RealMatrix mt = new RealMatrixImpl(testData2T); TestUtils.assertEquals("transpose",mt,m.transpose(),normTolerance); } /** test preMultiply by vector */ public void testPremultiplyVector() { RealMatrix m = new RealMatrixImpl(testData); TestUtils.assertEquals("premultiply", m.preMultiply(testVector), preMultTest, normTolerance); TestUtils.assertEquals("premultiply", m.preMultiply(new ArrayRealVector(testVector).getData()), preMultTest, normTolerance); m = new RealMatrixImpl(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { RealMatrix m3 = new RealMatrixImpl(d3); RealMatrix m4 = new RealMatrixImpl(d4); RealMatrix m5 = new RealMatrixImpl(d5); TestUtils.assertEquals("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance); RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl mInv = new RealMatrixImpl(testDataInv); RealMatrixImpl identity = new RealMatrixImpl(id); TestUtils.assertEquals("inverse multiply",m.preMultiply(mInv), identity,entryTolerance); TestUtils.assertEquals("inverse multiply",mInv.preMultiply(m), identity,entryTolerance); TestUtils.assertEquals("identity multiply",m.preMultiply(identity), m,entryTolerance); TestUtils.assertEquals("identity multiply",identity.preMultiply(mInv), mInv,entryTolerance); try { m.preMultiply(new RealMatrixImpl(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { RealMatrix m = new RealMatrixImpl(testData); TestUtils.assertEquals("get row",m.getRow(0),testDataRow1,entryTolerance); TestUtils.assertEquals("get col",m.getColumn(2),testDataCol3,entryTolerance); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { RealMatrix m = new RealMatrixImpl(testData); assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance); try { m.getEntry(10, 4); fail ("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}}; RealMatrix m = new RealMatrixImpl(matrixData); // One more with three rows, two columns double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}}; RealMatrix n = new RealMatrixImpl(matrixData2); // Now multiply m by n RealMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example double[][] coefficientsData = {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}}; RealMatrix coefficients = new RealMatrixImpl(coefficientsData); double[] constants = {1, -2, 1}; double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(2 * solution[0] + 3 * solution[1] -2 * solution[2], constants[0], 1E-12); assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2], constants[1], 1E-12); assertEquals(4 * solution[0] - 3 * solution[1] -5 * solution[2], constants[2], 1E-12); } // test submatrix accessors public void testGetSubMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0, false); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3, false); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3, false); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }, false); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }, false); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkGetSubMatrix(m, null, 1, 0, 2, 4, true); checkGetSubMatrix(m, null, -1, 1, 2, 2, true); checkGetSubMatrix(m, null, 1, 0, 2, 2, true); checkGetSubMatrix(m, null, 1, 0, 2, 4, true); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }, true); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }, true); } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn, boolean mustFail) { try { RealMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn); assertEquals(new RealMatrixImpl(reference), sub); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns, boolean mustFail) { try { RealMatrix sub = m.getSubMatrix(selectedRows, selectedColumns); assertEquals(new RealMatrixImpl(reference), sub); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } public void testCopySubMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); checkCopy(m, subRows23Cols00, 2 , 3 , 0, 0, false); checkCopy(m, subRows00Cols33, 0 , 0 , 3, 3, false); checkCopy(m, subRows01Cols23, 0 , 1 , 2, 3, false); checkCopy(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }, false); checkCopy(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }, false); checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkCopy(m, null, 1, 0, 2, 4, true); checkCopy(m, null, -1, 1, 2, 2, true); checkCopy(m, null, 1, 0, 2, 2, true); checkCopy(m, null, 1, 0, 2, 4, true); checkCopy(m, null, new int[] {}, new int[] { 0 }, true); checkCopy(m, null, new int[] { 0 }, new int[] { 4 }, true); } private void checkCopy(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn, boolean mustFail) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub); assertEquals(new RealMatrixImpl(reference), new RealMatrixImpl(sub)); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } private void checkCopy(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns, boolean mustFail) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(selectedRows, selectedColumns, sub); assertEquals(new RealMatrixImpl(reference), new RealMatrixImpl(sub)); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } public void testGetRowMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); RealMatrix mRow0 = new RealMatrixImpl(subRow0); RealMatrix mRow3 = new RealMatrixImpl(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); RealMatrix mRow3 = new RealMatrixImpl(subRow3); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowMatrix(0, mRow3); assertEquals(mRow3, m.getRowMatrix(0)); try { m.setRowMatrix(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); RealMatrix mColumn1 = new RealMatrixImpl(subColumn1); RealMatrix mColumn3 = new RealMatrixImpl(subColumn3); assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnMatrix() { RealMatrix m = new RealMatrixImpl(subTestData); RealMatrix mColumn3 = new RealMatrixImpl(subColumn3); assertNotSame(mColumn3, m.getColumnMatrix(1)); m.setColumnMatrix(1, mColumn3); assertEquals(mColumn3, m.getColumnMatrix(1)); try { m.setColumnMatrix(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetRowVector() { RealMatrix m = new RealMatrixImpl(subTestData); RealVector mRow0 = new ArrayRealVector(subRow0[0]); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertEquals("Row0", mRow0, m.getRowVector(0)); assertEquals("Row3", mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowVector() { RealMatrix m = new RealMatrixImpl(subTestData); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowVector(0, mRow3); assertEquals(mRow3, m.getRowVector(0)); try { m.setRowVector(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnVector() { RealMatrix m = new RealMatrixImpl(subTestData); RealVector mColumn1 = columnToVector(subColumn1); RealVector mColumn3 = columnToVector(subColumn3); assertEquals("Column1", mColumn1, m.getColumnVector(1)); assertEquals("Column3", mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnVector() { RealMatrix m = new RealMatrixImpl(subTestData); RealVector mColumn3 = columnToVector(subColumn3); assertNotSame(mColumn3, m.getColumnVector(1)); m.setColumnVector(1, mColumn3); assertEquals(mColumn3, m.getColumnVector(1)); try { m.setColumnVector(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private RealVector columnToVector(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayRealVector(data, false); } public void testGetRow() { RealMatrix m = new RealMatrixImpl(subTestData); checkArrays(subRow0[0], m.getRow(0)); checkArrays(subRow3[0], m.getRow(3)); try { m.getRow(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRow(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRow() { RealMatrix m = new RealMatrixImpl(subTestData); assertTrue(subRow3[0][0] != m.getRow(0)[0]); m.setRow(0, subRow3[0]); checkArrays(subRow3[0], m.getRow(0)); try { m.setRow(-1, subRow3[0]); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRow(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumn() { RealMatrix m = new RealMatrixImpl(subTestData); double[] mColumn1 = columnToArray(subColumn1); double[] mColumn3 = columnToArray(subColumn3); checkArrays(mColumn1, m.getColumn(1)); checkArrays(mColumn3, m.getColumn(3)); try { m.getColumn(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumn(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumn() { RealMatrix m = new RealMatrixImpl(subTestData); double[] mColumn3 = columnToArray(subColumn3); assertTrue(mColumn3[0] != m.getColumn(1)[0]); m.setColumn(1, mColumn3); checkArrays(mColumn3, m.getColumn(1)); try { m.setColumn(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumn(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private double[] columnToArray(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return data; } private void checkArrays(double[] expected, double[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], actual[i]); } } public void testEqualsAndHashCode() { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrixImpl m1 = (RealMatrixImpl) m.copy(); RealMatrixImpl mt = (RealMatrixImpl) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(new RealMatrixImpl(bigSingular))); } public void testToString() { RealMatrixImpl m = new RealMatrixImpl(testData); assertEquals("RealMatrixImpl{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", m.toString()); m = new RealMatrixImpl(); assertEquals("RealMatrixImpl{}", m.toString()); } public void testSetSubMatrix() throws Exception { RealMatrixImpl m = new RealMatrixImpl(testData); m.setSubMatrix(detData2,1,1); RealMatrix expected = MatrixUtils.createRealMatrix (new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(detData2,0,0); expected = MatrixUtils.createRealMatrix (new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(testDataPlus2,0,0); expected = MatrixUtils.createRealMatrix (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}}); assertEquals(expected, m); // dimension overflow try { m.setSubMatrix(testData,1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData,-1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData,1,-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null,1,1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } RealMatrixImpl m2 = new RealMatrixImpl(); try { m2.setSubMatrix(testData,0,1); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } try { m2.setSubMatrix(testData,1,0); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } // ragged try { m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new double[][] {{}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testWalk() throws MatrixIndexException, MatrixVisitorException { int rows = 150; int columns = 75; RealMatrix m = new RealMatrixImpl(rows, columns); m.walkInRowOrder(new SetVisitor()); GetVisitor getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new RealMatrixImpl(rows, columns); m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new RealMatrixImpl(rows, columns); m.walkInColumnOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new RealMatrixImpl(rows, columns); m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new RealMatrixImpl(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new RealMatrixImpl(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new RealMatrixImpl(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new RealMatrixImpl(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } } public void testSerial() { RealMatrixImpl m = new RealMatrixImpl(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } private static class SetVisitor extends DefaultRealMatrixChangingVisitor { @Override public double visit(int i, int j, double value) { return i + j / 1024.0; } } private static class GetVisitor extends DefaultRealMatrixPreservingVisitor { private int count = 0; @Override public void visit(int i, int j, double value) { ++count; assertEquals(i + j / 1024.0, value, 0.0); } public int getCount() { return count; } } //--------------- -----------------Protected methods /** extracts the l and u matrices from compact lu representation */ protected void splitLU(RealMatrix lu, double[][] lowerData, double[][] upperData) throws InvalidMatrixException { if (!lu.isSquare() || lowerData.length != lowerData[0].length || upperData.length != upperData[0].length || lowerData.length != upperData.length || lowerData.length != lu.getRowDimension()) { throw new InvalidMatrixException("incorrect dimensions"); } int n = lu.getRowDimension(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j < i) { lowerData[i][j] = lu.getEntry(i, j); upperData[i][j] = 0d; } else if (i == j) { lowerData[i][j] = 1d; upperData[i][j] = lu.getEntry(i, j); } else { lowerData[i][j] = 0d; upperData[i][j] = lu.getEntry(i, j); } } } } /** Returns the result of applying the given row permutation to the matrix */ protected RealMatrix permuteRows(RealMatrix matrix, int[] permutation) { if (!matrix.isSquare() || matrix.getRowDimension() != permutation.length) { throw new IllegalArgumentException("dimension mismatch"); } int n = matrix.getRowDimension(); int m = matrix.getColumnDimension(); double out[][] = new double[m][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { out[i][j] = matrix.getEntry(permutation[i], j); } } return new RealMatrixImpl(out); } // /** Useful for debugging */ // private void dumpMatrix(RealMatrix m) { // for (int i = 0; i < m.getRowDimension(); i++) { // String os = ""; // for (int j = 0; j < m.getColumnDimension(); j++) { // os += m.getEntry(i, j) + " "; // } // System.out.println(os); // } // } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SparseRealMatrixTest.java100644 1750 1750 62323 11532241243 30626 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; /** * Test cases for the {@link OpenMapRealMatrix} class. * * @version $Revision: 902201 $ $Date: 2008-11-07 06:48:13 -0800 (Fri, 07 Nov * 2008) $ */ public final class SparseRealMatrixTest extends TestCase { // 3 x 3 identity matrix protected double[][] id = { { 1d, 0d, 0d }, { 0d, 1d, 0d }, { 0d, 0d, 1d } }; // Test data for group operations protected double[][] testData = { { 1d, 2d, 3d }, { 2d, 5d, 3d }, { 1d, 0d, 8d } }; protected double[][] testDataLU = { { 2d, 5d, 3d }, { .5d, -2.5d, 6.5d }, { 0.5d, 0.2d, .2d } }; protected double[][] testDataPlus2 = { { 3d, 4d, 5d }, { 4d, 7d, 5d }, { 3d, 2d, 10d } }; protected double[][] testDataMinus = { { -1d, -2d, -3d }, { -2d, -5d, -3d }, { -1d, 0d, -8d } }; protected double[] testDataRow1 = { 1d, 2d, 3d }; protected double[] testDataCol3 = { 3d, 3d, 8d }; protected double[][] testDataInv = { { -40d, 16d, 9d }, { 13d, -5d, -3d }, { 5d, -2d, -1d } }; protected double[] preMultTest = { 8, 12, 33 }; protected double[][] testData2 = { { 1d, 2d, 3d }, { 2d, 5d, 3d } }; protected double[][] testData2T = { { 1d, 2d }, { 2d, 5d }, { 3d, 3d } }; protected double[][] testDataPlusInv = { { -39d, 18d, 12d }, { 15d, 0d, 0d }, { 6d, -2d, 7d } }; // lu decomposition tests protected double[][] luData = { { 2d, 3d, 3d }, { 0d, 5d, 7d }, { 6d, 9d, 8d } }; protected double[][] luDataLUDecomposition = { { 6d, 9d, 8d }, { 0d, 5d, 7d }, { 0.33333333333333, 0d, 0.33333333333333 } }; // singular matrices protected double[][] singular = { { 2d, 3d }, { 2d, 3d } }; protected double[][] bigSingular = { { 1d, 2d, 3d, 4d }, { 2d, 5d, 3d, 4d }, { 7d, 3d, 256d, 1930d }, { 3d, 7d, 6d, 8d } }; // 4th // row // = // 1st // + // 2nd protected double[][] detData = { { 1d, 2d, 3d }, { 4d, 5d, 6d }, { 7d, 8d, 10d } }; protected double[][] detData2 = { { 1d, 3d }, { 2d, 4d } }; // vectors protected double[] testVector = { 1, 2, 3 }; protected double[] testVector2 = { 1, 2, 3, 4 }; // submatrix accessor tests protected double[][] subTestData = { { 1, 2, 3, 4 }, { 1.5, 2.5, 3.5, 4.5 }, { 2, 4, 6, 8 }, { 4, 5, 6, 7 } }; // array selections protected double[][] subRows02Cols13 = { { 2, 4 }, { 4, 8 } }; protected double[][] subRows03Cols12 = { { 2, 3 }, { 5, 6 } }; protected double[][] subRows03Cols123 = { { 2, 3, 4 }, { 5, 6, 7 } }; // effective permutations protected double[][] subRows20Cols123 = { { 4, 6, 8 }, { 2, 3, 4 } }; protected double[][] subRows31Cols31 = { { 7, 5 }, { 4.5, 2.5 } }; // contiguous ranges protected double[][] subRows01Cols23 = { { 3, 4 }, { 3.5, 4.5 } }; protected double[][] subRows23Cols00 = { { 2 }, { 4 } }; protected double[][] subRows00Cols33 = { { 4 } }; // row matrices protected double[][] subRow0 = { { 1, 2, 3, 4 } }; protected double[][] subRow3 = { { 4, 5, 6, 7 } }; // column matrices protected double[][] subColumn1 = { { 2 }, { 2.5 }, { 4 }, { 5 } }; protected double[][] subColumn3 = { { 4 }, { 4.5 }, { 8 }, { 7 } }; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public SparseRealMatrixTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix m2 = createSparseMatrix(testData2); assertEquals("testData row dimension", 3, m.getRowDimension()); assertEquals("testData column dimension", 3, m.getColumnDimension()); assertTrue("testData is square", m.isSquare()); assertEquals("testData2 row dimension", m2.getRowDimension(), 2); assertEquals("testData2 column dimension", m2.getColumnDimension(), 3); assertTrue("testData2 is not square", !m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { OpenMapRealMatrix m1 = createSparseMatrix(testData); RealMatrix m2 = m1.copy(); assertEquals(m1.getClass(), m2.getClass()); assertEquals((m2), m1); OpenMapRealMatrix m3 = createSparseMatrix(testData); RealMatrix m4 = m3.copy(); assertEquals(m3.getClass(), m4.getClass()); assertEquals((m4), m3); } /** test add */ public void testAdd() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix mInv = createSparseMatrix(testDataInv); OpenMapRealMatrix mDataPlusInv = createSparseMatrix(testDataPlusInv); RealMatrix mPlusMInv = m.add(mInv); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals("sum entry entry", mDataPlusInv.getEntry(row, col), mPlusMInv.getEntry(row, col), entryTolerance); } } } /** test add failure */ public void testAddFail() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix m2 = createSparseMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test norm */ public void testNorm() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix m2 = createSparseMatrix(testData2); assertEquals("testData norm", 14d, m.getNorm(), entryTolerance); assertEquals("testData2 norm", 7d, m2.getNorm(), entryTolerance); } /** test m-n = m + -n */ public void testPlusMinus() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix n = createSparseMatrix(testDataInv); assertClose("m-n = m + -n", m.subtract(n), n.scalarMultiply(-1d).add(m), entryTolerance); try { m.subtract(createSparseMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix mInv = createSparseMatrix(testDataInv); OpenMapRealMatrix identity = createSparseMatrix(id); OpenMapRealMatrix m2 = createSparseMatrix(testData2); assertClose("inverse multiply", m.multiply(mInv), identity, entryTolerance); assertClose("inverse multiply", m.multiply(new BlockRealMatrix(testDataInv)), identity, entryTolerance); assertClose("inverse multiply", mInv.multiply(m), identity, entryTolerance); assertClose("identity multiply", m.multiply(identity), m, entryTolerance); assertClose("identity multiply", identity.multiply(mInv), mInv, entryTolerance); assertClose("identity multiply", m2.multiply(identity), m2, entryTolerance); try { m.multiply(createSparseMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } // Additional Test for Array2DRowRealMatrixTest.testMultiply private double[][] d3 = new double[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } }; private double[][] d4 = new double[][] { { 1 }, { 2 }, { 3 }, { 4 } }; private double[][] d5 = new double[][] { { 30 }, { 70 } }; public void testMultiply2() { RealMatrix m3 = createSparseMatrix(d3); RealMatrix m4 = createSparseMatrix(d4); RealMatrix m5 = createSparseMatrix(d5); assertClose("m3*m4=m5", m3.multiply(m4), m5, entryTolerance); } /** test trace */ public void testTrace() { RealMatrix m = createSparseMatrix(id); assertEquals("identity trace", 3d, m.getTrace(), entryTolerance); m = createSparseMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test sclarAdd */ public void testScalarAdd() { RealMatrix m = createSparseMatrix(testData); assertClose("scalar add", createSparseMatrix(testDataPlus2), m.scalarAdd(2d), entryTolerance); } /** test operate */ public void testOperate() { RealMatrix m = createSparseMatrix(id); assertClose("identity operate", testVector, m.operate(testVector), entryTolerance); assertClose("identity operate", testVector, m.operate( new ArrayRealVector(testVector)).getData(), entryTolerance); m = createSparseMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test issue MATH-209 */ public void testMath209() { RealMatrix a = createSparseMatrix(new double[][] { { 1, 2 }, { 3, 4 }, { 5, 6 } }); double[] b = a.operate(new double[] { 1, 1 }); assertEquals(a.getRowDimension(), b.length); assertEquals(3.0, b[0], 1.0e-12); assertEquals(7.0, b[1], 1.0e-12); assertEquals(11.0, b[2], 1.0e-12); } /** test transpose */ public void testTranspose() { RealMatrix m = createSparseMatrix(testData); RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose(); RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse(); assertClose("inverse-transpose", mIT, mTI, normTolerance); m = createSparseMatrix(testData2); RealMatrix mt = createSparseMatrix(testData2T); assertClose("transpose",mt,m.transpose(),normTolerance); } /** test preMultiply by vector */ public void testPremultiplyVector() { RealMatrix m = createSparseMatrix(testData); assertClose("premultiply", m.preMultiply(testVector), preMultTest, normTolerance); assertClose("premultiply", m.preMultiply( new ArrayRealVector(testVector).getData()), preMultTest, normTolerance); m = createSparseMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { RealMatrix m3 = createSparseMatrix(d3); RealMatrix m4 = createSparseMatrix(d4); RealMatrix m5 = createSparseMatrix(d5); assertClose("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance); OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix mInv = createSparseMatrix(testDataInv); OpenMapRealMatrix identity = createSparseMatrix(id); assertClose("inverse multiply", m.preMultiply(mInv), identity, entryTolerance); assertClose("inverse multiply", mInv.preMultiply(m), identity, entryTolerance); assertClose("identity multiply", m.preMultiply(identity), m, entryTolerance); assertClose("identity multiply", identity.preMultiply(mInv), mInv, entryTolerance); try { m.preMultiply(createSparseMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { RealMatrix m = createSparseMatrix(testData); assertClose("get row", m.getRow(0), testDataRow1, entryTolerance); assertClose("get col", m.getColumn(2), testDataCol3, entryTolerance); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { RealMatrix m = createSparseMatrix(testData); assertEquals("get entry", m.getEntry(0, 1), 2d, entryTolerance); try { m.getEntry(10, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns double[][] matrixData = { { 1d, 2d, 3d }, { 2d, 5d, 3d } }; RealMatrix m = createSparseMatrix(matrixData); // One more with three rows, two columns double[][] matrixData2 = { { 1d, 2d }, { 2d, 5d }, { 1d, 7d } }; RealMatrix n = createSparseMatrix(matrixData2); // Now multiply m by n RealMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example double[][] coefficientsData = { { 2, 3, -2 }, { -1, 7, 6 }, { 4, -3, -5 } }; RealMatrix coefficients = createSparseMatrix(coefficientsData); double[] constants = { 1, -2, 1 }; double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(2 * solution[0] + 3 * solution[1] - 2 * solution[2], constants[0], 1E-12); assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2], constants[1], 1E-12); assertEquals(4 * solution[0] - 3 * solution[1] - 5 * solution[2], constants[2], 1E-12); } // test submatrix accessors public void testSubMatrix() { RealMatrix m = createSparseMatrix(subTestData); RealMatrix mRows23Cols00 = createSparseMatrix(subRows23Cols00); RealMatrix mRows00Cols33 = createSparseMatrix(subRows00Cols33); RealMatrix mRows01Cols23 = createSparseMatrix(subRows01Cols23); RealMatrix mRows02Cols13 = createSparseMatrix(subRows02Cols13); RealMatrix mRows03Cols12 = createSparseMatrix(subRows03Cols12); RealMatrix mRows03Cols123 = createSparseMatrix(subRows03Cols123); RealMatrix mRows20Cols123 = createSparseMatrix(subRows20Cols123); RealMatrix mRows31Cols31 = createSparseMatrix(subRows31Cols31); assertEquals("Rows23Cols00", mRows23Cols00, m.getSubMatrix(2, 3, 0, 0)); assertEquals("Rows00Cols33", mRows00Cols33, m.getSubMatrix(0, 0, 3, 3)); assertEquals("Rows01Cols23", mRows01Cols23, m.getSubMatrix(0, 1, 2, 3)); assertEquals("Rows02Cols13", mRows02Cols13, m.getSubMatrix(new int[] { 0, 2 }, new int[] { 1, 3 })); assertEquals("Rows03Cols12", mRows03Cols12, m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2 })); assertEquals("Rows03Cols123", mRows03Cols123, m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2, 3 })); assertEquals("Rows20Cols123", mRows20Cols123, m.getSubMatrix(new int[] { 2, 0 }, new int[] { 1, 2, 3 })); assertEquals("Rows31Cols31", mRows31Cols31, m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); assertEquals("Rows31Cols31", mRows31Cols31, m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); try { m.getSubMatrix(1, 0, 2, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(-1, 1, 2, 2); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(1, 0, 2, 2); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(1, 0, 2, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(new int[] {}, new int[] { 0 }); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(new int[] { 0 }, new int[] { 4 }); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetRowMatrix() { RealMatrix m = createSparseMatrix(subTestData); RealMatrix mRow0 = createSparseMatrix(subRow0); RealMatrix mRow3 = createSparseMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetColumnMatrix() { RealMatrix m = createSparseMatrix(subTestData); RealMatrix mColumn1 = createSparseMatrix(subColumn1); RealMatrix mColumn3 = createSparseMatrix(subColumn3); assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetRowVector() { RealMatrix m = createSparseMatrix(subTestData); RealVector mRow0 = new ArrayRealVector(subRow0[0]); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertEquals("Row0", mRow0, m.getRowVector(0)); assertEquals("Row3", mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetColumnVector() { RealMatrix m = createSparseMatrix(subTestData); RealVector mColumn1 = columnToVector(subColumn1); RealVector mColumn3 = columnToVector(subColumn3); assertEquals("Column1", mColumn1, m.getColumnVector(1)); assertEquals("Column3", mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } private RealVector columnToVector(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayRealVector(data, false); } public void testEqualsAndHashCode() { OpenMapRealMatrix m = createSparseMatrix(testData); OpenMapRealMatrix m1 = m.copy(); OpenMapRealMatrix mt = (OpenMapRealMatrix) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(createSparseMatrix(bigSingular))); } public void testToString() { OpenMapRealMatrix m = createSparseMatrix(testData); assertEquals("OpenMapRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", m.toString()); m = new OpenMapRealMatrix(1, 1); assertEquals("OpenMapRealMatrix{{0.0}}", m.toString()); } public void testSetSubMatrix() throws Exception { OpenMapRealMatrix m = createSparseMatrix(testData); m.setSubMatrix(detData2, 1, 1); RealMatrix expected = createSparseMatrix(new double[][] { { 1.0, 2.0, 3.0 }, { 2.0, 1.0, 3.0 }, { 1.0, 2.0, 4.0 } }); assertEquals(expected, m); m.setSubMatrix(detData2, 0, 0); expected = createSparseMatrix(new double[][] { { 1.0, 3.0, 3.0 }, { 2.0, 4.0, 3.0 }, { 1.0, 2.0, 4.0 } }); assertEquals(expected, m); m.setSubMatrix(testDataPlus2, 0, 0); expected = createSparseMatrix(new double[][] { { 3.0, 4.0, 5.0 }, { 4.0, 7.0, 5.0 }, { 3.0, 2.0, 10.0 } }); assertEquals(expected, m); // javadoc example OpenMapRealMatrix matrix = createSparseMatrix(new double[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 0, 1, 2 } }); matrix.setSubMatrix(new double[][] { { 3, 4 }, { 5, 6 } }, 1, 1); expected = createSparseMatrix(new double[][] { { 1, 2, 3, 4 }, { 5, 3, 4, 8 }, { 9, 5, 6, 2 } }); assertEquals(expected, matrix); // dimension overflow try { m.setSubMatrix(testData, 1, 1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData, -1, 1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData, 1, -1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null, 1, 1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } try { new OpenMapRealMatrix(0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // ragged try { m.setSubMatrix(new double[][] { { 1 }, { 2, 3 } }, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new double[][] { {} }, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testSerial() { OpenMapRealMatrix m = createSparseMatrix(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } // --------------- -----------------Protected methods /** verifies that two matrices are close (1-norm) */ protected void assertClose(String msg, RealMatrix m, RealMatrix n, double tolerance) { assertTrue(msg, m.subtract(n).getNorm() < tolerance); } /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, double[] m, double[] n, double tolerance) { if (m.length != n.length) { fail("vectors not same length"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i], n[i], tolerance); } } private OpenMapRealMatrix createSparseMatrix(double[][] data) { OpenMapRealMatrix matrix = new OpenMapRealMatrix(data.length, data[0].length); for (int row = 0; row < data.length; row++) { for (int col = 0; col < data[row].length; col++) { matrix.setEntry(row, col, data[row][col]); } } return matrix; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/FieldMatrixImplTest.java100644 1750 1750 127401 11532241243 30451 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionField; /** * Test cases for the {@link Array2DRowFieldMatrix} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public final class FieldMatrixImplTest extends TestCase { // 3 x 3 identity matrix protected Fraction[][] id = { {new Fraction(1),new Fraction(0),new Fraction(0)}, {new Fraction(0),new Fraction(1),new Fraction(0)}, {new Fraction(0),new Fraction(0),new Fraction(1)} }; // Test data for group operations protected Fraction[][] testData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)}, {new Fraction(1),new Fraction(0),new Fraction(8)} }; protected Fraction[][] testDataLU = {{new Fraction(2), new Fraction(5), new Fraction(3)}, {new Fraction(1, 2), new Fraction(-5, 2), new Fraction(13, 2)}, {new Fraction(1, 2), new Fraction(1, 5), new Fraction(1, 5)}}; protected Fraction[][] testDataPlus2 = { {new Fraction(3),new Fraction(4),new Fraction(5)}, {new Fraction(4),new Fraction(7),new Fraction(5)}, {new Fraction(3),new Fraction(2),new Fraction(10)} }; protected Fraction[][] testDataMinus = { {new Fraction(-1),new Fraction(-2),new Fraction(-3)}, {new Fraction(-2),new Fraction(-5),new Fraction(-3)}, {new Fraction(-1),new Fraction(0),new Fraction(-8)} }; protected Fraction[] testDataRow1 = {new Fraction(1),new Fraction(2),new Fraction(3)}; protected Fraction[] testDataCol3 = {new Fraction(3),new Fraction(3),new Fraction(8)}; protected Fraction[][] testDataInv = { {new Fraction(-40),new Fraction(16),new Fraction(9)}, {new Fraction(13),new Fraction(-5),new Fraction(-3)}, {new Fraction(5),new Fraction(-2),new Fraction(-1)} }; protected Fraction[] preMultTest = {new Fraction(8),new Fraction(12),new Fraction(33)}; protected Fraction[][] testData2 ={ {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)}}; protected Fraction[][] testData2T = { {new Fraction(1),new Fraction(2)}, {new Fraction(2),new Fraction(5)}, {new Fraction(3),new Fraction(3)}}; protected Fraction[][] testDataPlusInv = { {new Fraction(-39),new Fraction(18),new Fraction(12)}, {new Fraction(15),new Fraction(0),new Fraction(0)}, {new Fraction(6),new Fraction(-2),new Fraction(7)} }; // lu decomposition tests protected Fraction[][] luData = { {new Fraction(2),new Fraction(3),new Fraction(3)}, {new Fraction(0),new Fraction(5),new Fraction(7)}, {new Fraction(6),new Fraction(9),new Fraction(8)} }; protected Fraction[][] luDataLUDecomposition = { {new Fraction(6),new Fraction(9),new Fraction(8)}, {new Fraction(0),new Fraction(5),new Fraction(7)}, {new Fraction(1, 3),new Fraction(0),new Fraction(1, 3)} }; // singular matrices protected Fraction[][] singular = { {new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(3)} }; protected Fraction[][] bigSingular = {{new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}, {new Fraction(2),new Fraction(5),new Fraction(3),new Fraction(4)}, {new Fraction(7),new Fraction(3),new Fraction(256),new Fraction(1930)}, {new Fraction(3),new Fraction(7),new Fraction(6),new Fraction(8)}}; // 4th row = 1st + 2nd protected Fraction[][] detData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(4),new Fraction(5),new Fraction(6)}, {new Fraction(7),new Fraction(8),new Fraction(10)} }; protected Fraction[][] detData2 = { {new Fraction(1), new Fraction(3)}, {new Fraction(2), new Fraction(4)}}; // vectors protected Fraction[] testVector = {new Fraction(1),new Fraction(2),new Fraction(3)}; protected Fraction[] testVector2 = {new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}; // submatrix accessor tests protected Fraction[][] subTestData = {{new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4)}, {new Fraction(3, 2), new Fraction(5, 2), new Fraction(7, 2), new Fraction(9, 2)}, {new Fraction(2), new Fraction(4), new Fraction(6), new Fraction(8)}, {new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7)}}; // array selections protected Fraction[][] subRows02Cols13 = { {new Fraction(2), new Fraction(4)}, {new Fraction(4), new Fraction(8)}}; protected Fraction[][] subRows03Cols12 = { {new Fraction(2), new Fraction(3)}, {new Fraction(5), new Fraction(6)}}; protected Fraction[][] subRows03Cols123 = { {new Fraction(2), new Fraction(3), new Fraction(4)} , {new Fraction(5), new Fraction(6), new Fraction(7)}}; // effective permutations protected Fraction[][] subRows20Cols123 = { {new Fraction(4), new Fraction(6), new Fraction(8)} , {new Fraction(2), new Fraction(3), new Fraction(4)}}; protected Fraction[][] subRows31Cols31 = {{new Fraction(7), new Fraction(5)}, {new Fraction(9, 2), new Fraction(5, 2)}}; // contiguous ranges protected Fraction[][] subRows01Cols23 = {{new Fraction(3),new Fraction(4)} , {new Fraction(7, 2), new Fraction(9, 2)}}; protected Fraction[][] subRows23Cols00 = {{new Fraction(2)} , {new Fraction(4)}}; protected Fraction[][] subRows00Cols33 = {{new Fraction(4)}}; // row matrices protected Fraction[][] subRow0 = {{new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}}; protected Fraction[][] subRow3 = {{new Fraction(4),new Fraction(5),new Fraction(6),new Fraction(7)}}; // column matrices protected Fraction[][] subColumn1 = {{new Fraction(2)}, {new Fraction(5, 2)}, {new Fraction(4)}, {new Fraction(5)}}; protected Fraction[][] subColumn3 = {{new Fraction(4)}, {new Fraction(9, 2)}, {new Fraction(8)}, {new Fraction(7)}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public FieldMatrixImplTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(testData2); assertEquals("testData row dimension",3,m.getRowDimension()); assertEquals("testData column dimension",3,m.getColumnDimension()); assertTrue("testData is square",m.isSquare()); assertEquals("testData2 row dimension",m2.getRowDimension(),2); assertEquals("testData2 column dimension",m2.getColumnDimension(),3); assertTrue("testData2 is not square",!m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { Array2DRowFieldMatrix m1 = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(m1.getData()); assertEquals(m2,m1); Array2DRowFieldMatrix m3 = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m4 = new Array2DRowFieldMatrix(m3.getData(), false); assertEquals(m4,m3); } /** test add */ public void testAdd() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix mInv = new Array2DRowFieldMatrix(testDataInv); FieldMatrix mPlusMInv = m.add(mInv); Fraction[][] sumEntries = mPlusMInv.getData(); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals(testDataPlusInv[row][col],sumEntries[row][col]); } } } /** test add failure */ public void testAddFail() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test m-n = m + -n */ public void testPlusMinus() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(testDataInv); TestUtils.assertEquals(m.subtract(m2),m2.scalarMultiply(new Fraction(-1)).add(m)); try { m.subtract(new Array2DRowFieldMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix mInv = new Array2DRowFieldMatrix(testDataInv); Array2DRowFieldMatrix identity = new Array2DRowFieldMatrix(id); Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(testData2); TestUtils.assertEquals(m.multiply(mInv), identity); TestUtils.assertEquals(mInv.multiply(m), identity); TestUtils.assertEquals(m.multiply(identity), m); TestUtils.assertEquals(identity.multiply(mInv), mInv); TestUtils.assertEquals(m2.multiply(identity), m2); try { m.multiply(new Array2DRowFieldMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } //Additional Test for Array2DRowFieldMatrixTest.testMultiply private Fraction[][] d3 = new Fraction[][] {{new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)},{new Fraction(5),new Fraction(6),new Fraction(7),new Fraction(8)}}; private Fraction[][] d4 = new Fraction[][] {{new Fraction(1)},{new Fraction(2)},{new Fraction(3)},{new Fraction(4)}}; private Fraction[][] d5 = new Fraction[][] {{new Fraction(30)},{new Fraction(70)}}; public void testMultiply2() { FieldMatrix m3 = new Array2DRowFieldMatrix(d3); FieldMatrix m4 = new Array2DRowFieldMatrix(d4); FieldMatrix m5 = new Array2DRowFieldMatrix(d5); TestUtils.assertEquals(m3.multiply(m4), m5); } /** test trace */ public void testTrace() { FieldMatrix m = new Array2DRowFieldMatrix(id); assertEquals("identity trace",new Fraction(3),m.getTrace()); m = new Array2DRowFieldMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test sclarAdd */ public void testScalarAdd() { FieldMatrix m = new Array2DRowFieldMatrix(testData); TestUtils.assertEquals(new Array2DRowFieldMatrix(testDataPlus2), m.scalarAdd(new Fraction(2))); } /** test operate */ public void testOperate() { FieldMatrix m = new Array2DRowFieldMatrix(id); TestUtils.assertEquals(testVector, m.operate(testVector)); TestUtils.assertEquals(testVector, m.operate(new ArrayFieldVector(testVector)).getData()); m = new Array2DRowFieldMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test issue MATH-209 */ public void testMath209() { FieldMatrix a = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2) }, { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }, false); Fraction[] b = a.operate(new Fraction[] { new Fraction(1), new Fraction(1) }); assertEquals(a.getRowDimension(), b.length); assertEquals( new Fraction(3), b[0]); assertEquals( new Fraction(7), b[1]); assertEquals(new Fraction(11), b[2]); } /** test transpose */ public void testTranspose() { FieldMatrix m = new Array2DRowFieldMatrix(testData); FieldMatrix mIT = new FieldLUDecompositionImpl(m).getSolver().getInverse().transpose(); FieldMatrix mTI = new FieldLUDecompositionImpl(m.transpose()).getSolver().getInverse(); TestUtils.assertEquals(mIT, mTI); m = new Array2DRowFieldMatrix(testData2); FieldMatrix mt = new Array2DRowFieldMatrix(testData2T); TestUtils.assertEquals(mt, m.transpose()); } /** test preMultiply by vector */ public void testPremultiplyVector() { FieldMatrix m = new Array2DRowFieldMatrix(testData); TestUtils.assertEquals(m.preMultiply(testVector), preMultTest); TestUtils.assertEquals(m.preMultiply(new ArrayFieldVector(testVector).getData()), preMultTest); m = new Array2DRowFieldMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { FieldMatrix m3 = new Array2DRowFieldMatrix(d3); FieldMatrix m4 = new Array2DRowFieldMatrix(d4); FieldMatrix m5 = new Array2DRowFieldMatrix(d5); TestUtils.assertEquals(m4.preMultiply(m3), m5); Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix mInv = new Array2DRowFieldMatrix(testDataInv); Array2DRowFieldMatrix identity = new Array2DRowFieldMatrix(id); TestUtils.assertEquals(m.preMultiply(mInv), identity); TestUtils.assertEquals(mInv.preMultiply(m), identity); TestUtils.assertEquals(m.preMultiply(identity), m); TestUtils.assertEquals(identity.preMultiply(mInv), mInv); try { m.preMultiply(new Array2DRowFieldMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { FieldMatrix m = new Array2DRowFieldMatrix(testData); TestUtils.assertEquals(m.getRow(0), testDataRow1); TestUtils.assertEquals(m.getColumn(2), testDataCol3); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { FieldMatrix m = new Array2DRowFieldMatrix(testData); assertEquals("get entry",m.getEntry(0,1),new Fraction(2)); try { m.getEntry(10, 4); fail ("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns Fraction[][] matrixData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)} }; FieldMatrix m = new Array2DRowFieldMatrix(matrixData); // One more with three rows, two columns Fraction[][] matrixData2 = { {new Fraction(1),new Fraction(2)}, {new Fraction(2),new Fraction(5)}, {new Fraction(1), new Fraction(7)} }; FieldMatrix n = new Array2DRowFieldMatrix(matrixData2); // Now multiply m by n FieldMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p FieldMatrix pInverse = new FieldLUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example Fraction[][] coefficientsData = { {new Fraction(2), new Fraction(3), new Fraction(-2)}, {new Fraction(-1), new Fraction(7), new Fraction(6)}, {new Fraction(4), new Fraction(-3), new Fraction(-5)} }; FieldMatrix coefficients = new Array2DRowFieldMatrix(coefficientsData); Fraction[] constants = {new Fraction(1), new Fraction(-2), new Fraction(1)}; Fraction[] solution = new FieldLUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(new Fraction(2).multiply(solution[0]). add(new Fraction(3).multiply(solution[1])). subtract(new Fraction(2).multiply(solution[2])), constants[0]); assertEquals(new Fraction(-1).multiply(solution[0]). add(new Fraction(7).multiply(solution[1])). add(new Fraction(6).multiply(solution[2])), constants[1]); assertEquals(new Fraction(4).multiply(solution[0]). subtract(new Fraction(3).multiply(solution[1])). subtract(new Fraction(5).multiply(solution[2])), constants[2]); } // test submatrix accessors public void testGetSubMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, -1, 1, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkGetSubMatrix(FieldMatrix m, Fraction[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { FieldMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn); if (reference != null) { assertEquals(new Array2DRowFieldMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkGetSubMatrix(FieldMatrix m, Fraction[][] reference, int[] selectedRows, int[] selectedColumns) { try { FieldMatrix sub = m.getSubMatrix(selectedRows, selectedColumns); if (reference != null) { assertEquals(new Array2DRowFieldMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testCopySubMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); checkCopy(m, subRows23Cols00, 2 , 3 , 0, 0); checkCopy(m, subRows00Cols33, 0 , 0 , 3, 3); checkCopy(m, subRows01Cols23, 0 , 1 , 2, 3); checkCopy(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkCopy(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, -1, 1, 2, 2); checkCopy(m, null, 1, 0, 2, 2); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, new int[] {}, new int[] { 0 }); checkCopy(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkCopy(FieldMatrix m, Fraction[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { Fraction[][] sub = (reference == null) ? new Fraction[1][1] : new Fraction[reference.length][reference[0].length]; m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub); if (reference != null) { assertEquals(new Array2DRowFieldMatrix(reference), new Array2DRowFieldMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkCopy(FieldMatrix m, Fraction[][] reference, int[] selectedRows, int[] selectedColumns) { try { Fraction[][] sub = (reference == null) ? new Fraction[1][1] : new Fraction[reference.length][reference[0].length]; m.copySubMatrix(selectedRows, selectedColumns, sub); if (reference != null) { assertEquals(new Array2DRowFieldMatrix(reference), new Array2DRowFieldMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testGetRowMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldMatrix mRow0 = new Array2DRowFieldMatrix(subRow0); FieldMatrix mRow3 = new Array2DRowFieldMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldMatrix mRow3 = new Array2DRowFieldMatrix(subRow3); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowMatrix(0, mRow3); assertEquals(mRow3, m.getRowMatrix(0)); try { m.setRowMatrix(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldMatrix mColumn1 = new Array2DRowFieldMatrix(subColumn1); FieldMatrix mColumn3 = new Array2DRowFieldMatrix(subColumn3); assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnMatrix() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldMatrix mColumn3 = new Array2DRowFieldMatrix(subColumn3); assertNotSame(mColumn3, m.getColumnMatrix(1)); m.setColumnMatrix(1, mColumn3); assertEquals(mColumn3, m.getColumnMatrix(1)); try { m.setColumnMatrix(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetRowVector() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldVector mRow0 = new ArrayFieldVector(subRow0[0]); FieldVector mRow3 = new ArrayFieldVector(subRow3[0]); assertEquals("Row0", mRow0, m.getRowVector(0)); assertEquals("Row3", mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowVector() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldVector mRow3 = new ArrayFieldVector(subRow3[0]); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowVector(0, mRow3); assertEquals(mRow3, m.getRowVector(0)); try { m.setRowVector(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowVector(0, new ArrayFieldVector(FractionField.getInstance(), 5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnVector() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldVector mColumn1 = columnToVector(subColumn1); FieldVector mColumn3 = columnToVector(subColumn3); assertEquals("Column1", mColumn1, m.getColumnVector(1)); assertEquals("Column3", mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnVector() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); FieldVector mColumn3 = columnToVector(subColumn3); assertNotSame(mColumn3, m.getColumnVector(1)); m.setColumnVector(1, mColumn3); assertEquals(mColumn3, m.getColumnVector(1)); try { m.setColumnVector(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnVector(0, new ArrayFieldVector(FractionField.getInstance(), 5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private FieldVector columnToVector(Fraction[][] column) { Fraction[] data = new Fraction[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayFieldVector(data, false); } public void testGetRow() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); checkArrays(subRow0[0], m.getRow(0)); checkArrays(subRow3[0], m.getRow(3)); try { m.getRow(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRow(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRow() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); assertTrue(subRow3[0][0] != m.getRow(0)[0]); m.setRow(0, subRow3[0]); checkArrays(subRow3[0], m.getRow(0)); try { m.setRow(-1, subRow3[0]); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRow(0, new Fraction[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumn() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); Fraction[] mColumn1 = columnToArray(subColumn1); Fraction[] mColumn3 = columnToArray(subColumn3); checkArrays(mColumn1, m.getColumn(1)); checkArrays(mColumn3, m.getColumn(3)); try { m.getColumn(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumn(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumn() { FieldMatrix m = new Array2DRowFieldMatrix(subTestData); Fraction[] mColumn3 = columnToArray(subColumn3); assertTrue(mColumn3[0] != m.getColumn(1)[0]); m.setColumn(1, mColumn3); checkArrays(mColumn3, m.getColumn(1)); try { m.setColumn(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumn(0, new Fraction[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private Fraction[] columnToArray(Fraction[][] column) { Fraction[] data = new Fraction[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return data; } private void checkArrays(Fraction[] expected, Fraction[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], actual[i]); } } public void testEqualsAndHashCode() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); Array2DRowFieldMatrix m1 = (Array2DRowFieldMatrix) m.copy(); Array2DRowFieldMatrix mt = (Array2DRowFieldMatrix) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(new Array2DRowFieldMatrix(bigSingular))); } public void testToString() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); assertEquals("Array2DRowFieldMatrix{{1,2,3},{2,5,3},{1,0,8}}", m.toString()); m = new Array2DRowFieldMatrix(FractionField.getInstance()); assertEquals("Array2DRowFieldMatrix{}", m.toString()); } public void testSetSubMatrix() throws Exception { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); m.setSubMatrix(detData2,1,1); FieldMatrix expected = new Array2DRowFieldMatrix (new Fraction[][] { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(1),new Fraction(3)}, {new Fraction(1),new Fraction(2),new Fraction(4)} }); assertEquals(expected, m); m.setSubMatrix(detData2,0,0); expected = new Array2DRowFieldMatrix (new Fraction[][] { {new Fraction(1),new Fraction(3),new Fraction(3)}, {new Fraction(2),new Fraction(4),new Fraction(3)}, {new Fraction(1),new Fraction(2),new Fraction(4)} }); assertEquals(expected, m); m.setSubMatrix(testDataPlus2,0,0); expected = new Array2DRowFieldMatrix (new Fraction[][] { {new Fraction(3),new Fraction(4),new Fraction(5)}, {new Fraction(4),new Fraction(7),new Fraction(5)}, {new Fraction(3),new Fraction(2),new Fraction(10)} }); assertEquals(expected, m); // dimension overflow try { m.setSubMatrix(testData,1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData,-1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData,1,-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null,1,1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } Array2DRowFieldMatrix m2 = new Array2DRowFieldMatrix(FractionField.getInstance()); try { m2.setSubMatrix(testData,0,1); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } try { m2.setSubMatrix(testData,1,0); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } // ragged try { m.setSubMatrix(new Fraction[][] {{new Fraction(1)}, {new Fraction(2), new Fraction(3)}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new Fraction[][] {{}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testWalk() throws MatrixVisitorException { int rows = 150; int columns = 75; FieldMatrix m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInRowOrder(new SetVisitor()); GetVisitor getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInColumnOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } } public void testSerial() { Array2DRowFieldMatrix m = new Array2DRowFieldMatrix(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } private static class SetVisitor extends DefaultFieldMatrixChangingVisitor { public SetVisitor() { super(Fraction.ZERO); } @Override public Fraction visit(int i, int j, Fraction value) { return new Fraction(i * 1024 + j, 1024); } } private static class GetVisitor extends DefaultFieldMatrixPreservingVisitor { private int count; public GetVisitor() { super(Fraction.ZERO); count = 0; } @Override public void visit(int i, int j, Fraction value) { ++count; assertEquals(new Fraction(i * 1024 + j, 1024), value); } public int getCount() { return count; } } //--------------- -----------------Protected methods /** extracts the l and u matrices from compact lu representation */ protected void splitLU(FieldMatrix lu, Fraction[][] lowerData, Fraction[][] upperData) throws InvalidMatrixException { if (!lu.isSquare() || lowerData.length != lowerData[0].length || upperData.length != upperData[0].length || lowerData.length != upperData.length || lowerData.length != lu.getRowDimension()) { throw new InvalidMatrixException("incorrect dimensions"); } int n = lu.getRowDimension(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j < i) { lowerData[i][j] = lu.getEntry(i, j); upperData[i][j] = Fraction.ZERO; } else if (i == j) { lowerData[i][j] = Fraction.ONE; upperData[i][j] = lu.getEntry(i, j); } else { lowerData[i][j] = Fraction.ZERO; upperData[i][j] = lu.getEntry(i, j); } } } } /** Returns the result of applying the given row permutation to the matrix */ protected FieldMatrix permuteRows(FieldMatrix matrix, int[] permutation) { if (!matrix.isSquare() || matrix.getRowDimension() != permutation.length) { throw new IllegalArgumentException("dimension mismatch"); } int n = matrix.getRowDimension(); int m = matrix.getColumnDimension(); Fraction out[][] = new Fraction[m][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { out[i][j] = matrix.getEntry(permutation[i], j); } } return new Array2DRowFieldMatrix(out); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/BiDiagonalTransformerTest.java100644 1750 1750 21025 11532241243 31606 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.BiDiagonalTransformer; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; public class BiDiagonalTransformerTest { private double[][] testSquare = { { 24.0 / 25.0, 43.0 / 25.0 }, { 57.0 / 25.0, 24.0 / 25.0 } }; private double[][] testNonSquare = { { -540.0 / 625.0, 963.0 / 625.0, -216.0 / 625.0 }, { -1730.0 / 625.0, -744.0 / 625.0, 1008.0 / 625.0 }, { -720.0 / 625.0, 1284.0 / 625.0, -288.0 / 625.0 }, { -360.0 / 625.0, 192.0 / 625.0, 1756.0 / 625.0 }, }; @Test public void testDimensions() { checkdimensions(MatrixUtils.createRealMatrix(testSquare)); checkdimensions(MatrixUtils.createRealMatrix(testNonSquare)); checkdimensions(MatrixUtils.createRealMatrix(testNonSquare).transpose()); } private void checkdimensions(RealMatrix matrix) { final int m = matrix.getRowDimension(); final int n = matrix.getColumnDimension(); BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix); Assert.assertEquals(m, transformer.getU().getRowDimension()); Assert.assertEquals(m, transformer.getU().getColumnDimension()); Assert.assertEquals(m, transformer.getB().getRowDimension()); Assert.assertEquals(n, transformer.getB().getColumnDimension()); Assert.assertEquals(n, transformer.getV().getRowDimension()); Assert.assertEquals(n, transformer.getV().getColumnDimension()); } @Test public void testAEqualUSVt() { checkAEqualUSVt(MatrixUtils.createRealMatrix(testSquare)); checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare)); checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare).transpose()); } private void checkAEqualUSVt(RealMatrix matrix) { BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix); RealMatrix u = transformer.getU(); RealMatrix b = transformer.getB(); RealMatrix v = transformer.getV(); double norm = u.multiply(b).multiply(v.transpose()).subtract(matrix).getNorm(); Assert.assertEquals(0, norm, 1.0e-14); } @Test public void testUOrthogonal() { checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getU()); checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getU()); checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getU()); } @Test public void testVOrthogonal() { checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getV()); checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getV()); checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getV()); } private void checkOrthogonal(RealMatrix m) { RealMatrix mTm = m.transpose().multiply(m); RealMatrix id = MatrixUtils.createRealIdentityMatrix(mTm.getRowDimension()); Assert.assertEquals(0, mTm.subtract(id).getNorm(), 1.0e-14); } @Test public void testBBiDiagonal() { checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getB()); checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getB()); checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getB()); } private void checkBiDiagonal(RealMatrix m) { final int rows = m.getRowDimension(); final int cols = m.getColumnDimension(); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { if (rows < cols) { if ((i < j) || (i > j + 1)) { Assert.assertEquals(0, m.getEntry(i, j), 1.0e-16); } } else { if ((i < j - 1) || (i > j)) { Assert.assertEquals(0, m.getEntry(i, j), 1.0e-16); } } } } } @Test public void testSingularMatrix() { BiDiagonalTransformer transformer = new BiDiagonalTransformer(MatrixUtils.createRealMatrix(new double[][] { { 1.0, 2.0, 3.0 }, { 2.0, 3.0, 4.0 }, { 3.0, 5.0, 7.0 } })); final double s3 = FastMath.sqrt(3.0); final double s14 = FastMath.sqrt(14.0); final double s1553 = FastMath.sqrt(1553.0); RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { -1.0 / s14, 5.0 / (s3 * s14), 1.0 / s3 }, { -2.0 / s14, -4.0 / (s3 * s14), 1.0 / s3 }, { -3.0 / s14, 1.0 / (s3 * s14), -1.0 / s3 } }); RealMatrix bRef = MatrixUtils.createRealMatrix(new double[][] { { -s14, s1553 / s14, 0.0 }, { 0.0, -87 * s3 / (s14 * s1553), -s3 * s14 / s1553 }, { 0.0, 0.0, 0.0 } }); RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 0.0, 0.0 }, { 0.0, -23 / s1553, 32 / s1553 }, { 0.0, -32 / s1553, -23 / s1553 } }); // check values against known references RealMatrix u = transformer.getU(); Assert.assertEquals(0, u.subtract(uRef).getNorm(), 1.0e-14); RealMatrix b = transformer.getB(); Assert.assertEquals(0, b.subtract(bRef).getNorm(), 1.0e-14); RealMatrix v = transformer.getV(); Assert.assertEquals(0, v.subtract(vRef).getNorm(), 1.0e-14); // check the same cached instance is returned the second time Assert.assertTrue(u == transformer.getU()); Assert.assertTrue(b == transformer.getB()); Assert.assertTrue(v == transformer.getV()); } @Test public void testMatricesValues() { BiDiagonalTransformer transformer = new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)); final double s17 = FastMath.sqrt(17.0); RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { -8 / (5 * s17), 19 / (5 * s17) }, { -19 / (5 * s17), -8 / (5 * s17) } }); RealMatrix bRef = MatrixUtils.createRealMatrix(new double[][] { { -3 * s17 / 5, 32 * s17 / 85 }, { 0.0, -5 * s17 / 17 } }); RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 0.0 }, { 0.0, -1.0 } }); // check values against known references RealMatrix u = transformer.getU(); Assert.assertEquals(0, u.subtract(uRef).getNorm(), 1.0e-14); RealMatrix b = transformer.getB(); Assert.assertEquals(0, b.subtract(bRef).getNorm(), 1.0e-14); RealMatrix v = transformer.getV(); Assert.assertEquals(0, v.subtract(vRef).getNorm(), 1.0e-14); // check the same cached instance is returned the second time Assert.assertTrue(u == transformer.getU()); Assert.assertTrue(b == transformer.getB()); Assert.assertTrue(v == transformer.getV()); } @Test public void testUpperOrLower() { Assert.assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).isUpperBiDiagonal()); Assert.assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).isUpperBiDiagonal()); Assert.assertFalse(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).isUpperBiDiagonal()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/BlockRealMatrixTest.java100644 1750 1750 127563 11532241243 30453 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import java.util.Random; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link BlockRealMatrix} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public final class BlockRealMatrixTest extends TestCase { // 3 x 3 identity matrix protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} }; // Test data for group operations protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} }; protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}}; protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} }; protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d}, {-1d,0d,-8d} }; protected double[] testDataRow1 = {1d,2d,3d}; protected double[] testDataCol3 = {3d,3d,8d}; protected double[][] testDataInv = { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} }; protected double[] preMultTest = {8,12,33}; protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}}; protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}}; protected double[][] testDataPlusInv = { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} }; // lu decomposition tests protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} }; protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d}, {0.33333333333333,0d,0.33333333333333} }; // singular matrices protected double[][] singular = { {2d,3d}, {2d,3d} }; protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d}, {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} }; protected double[][] detData2 = { {1d, 3d}, {2d, 4d}}; // vectors protected double[] testVector = {1,2,3}; protected double[] testVector2 = {1,2,3,4}; // submatrix accessor tests protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5}, {2, 4, 6, 8}, {4, 5, 6, 7}}; // array selections protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}}; protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}}; protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}}; // effective permutations protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}}; protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}}; // contiguous ranges protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}}; protected double[][] subRows23Cols00 = {{2} , {4}}; protected double[][] subRows00Cols33 = {{4}}; // row matrices protected double[][] subRow0 = {{1,2,3,4}}; protected double[][] subRow3 = {{4,5,6,7}}; // column matrices protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}}; protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public BlockRealMatrixTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m2 = new BlockRealMatrix(testData2); assertEquals("testData row dimension",3,m.getRowDimension()); assertEquals("testData column dimension",3,m.getColumnDimension()); assertTrue("testData is square",m.isSquare()); assertEquals("testData2 row dimension",m2.getRowDimension(),2); assertEquals("testData2 column dimension",m2.getColumnDimension(),3); assertTrue("testData2 is not square",!m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { Random r = new Random(66636328996002l); BlockRealMatrix m1 = createRandomMatrix(r, 47, 83); BlockRealMatrix m2 = new BlockRealMatrix(m1.getData()); assertEquals(m1, m2); BlockRealMatrix m3 = new BlockRealMatrix(testData); BlockRealMatrix m4 = new BlockRealMatrix(m3.getData()); assertEquals(m3, m4); } /** test add */ public void testAdd() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix mInv = new BlockRealMatrix(testDataInv); RealMatrix mPlusMInv = m.add(mInv); double[][] sumEntries = mPlusMInv.getData(); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals("sum entry entry", testDataPlusInv[row][col],sumEntries[row][col], entryTolerance); } } } /** test add failure */ public void testAddFail() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m2 = new BlockRealMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test norm */ public void testNorm() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m2 = new BlockRealMatrix(testData2); assertEquals("testData norm",14d,m.getNorm(),entryTolerance); assertEquals("testData2 norm",7d,m2.getNorm(),entryTolerance); } /** test Frobenius norm */ public void testFrobeniusNorm() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m2 = new BlockRealMatrix(testData2); assertEquals("testData Frobenius norm", FastMath.sqrt(117.0), m.getFrobeniusNorm(), entryTolerance); assertEquals("testData2 Frobenius norm", FastMath.sqrt(52.0), m2.getFrobeniusNorm(), entryTolerance); } /** test m-n = m + -n */ public void testPlusMinus() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m2 = new BlockRealMatrix(testDataInv); assertClose(m.subtract(m2), m2.scalarMultiply(-1d).add(m), entryTolerance); try { m.subtract(new BlockRealMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix mInv = new BlockRealMatrix(testDataInv); BlockRealMatrix identity = new BlockRealMatrix(id); BlockRealMatrix m2 = new BlockRealMatrix(testData2); assertClose(m.multiply(mInv), identity, entryTolerance); assertClose(mInv.multiply(m), identity, entryTolerance); assertClose(m.multiply(identity), m, entryTolerance); assertClose(identity.multiply(mInv), mInv, entryTolerance); assertClose(m2.multiply(identity), m2, entryTolerance); try { m.multiply(new BlockRealMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testSeveralBlocks() { RealMatrix m = new BlockRealMatrix(35, 71); for (int i = 0; i < m.getRowDimension(); ++i) { for (int j = 0; j < m.getColumnDimension(); ++j) { m.setEntry(i, j, i + j / 1024.0); } } RealMatrix mT = m.transpose(); assertEquals(m.getRowDimension(), mT.getColumnDimension()); assertEquals(m.getColumnDimension(), mT.getRowDimension()); for (int i = 0; i < mT.getRowDimension(); ++i) { for (int j = 0; j < mT.getColumnDimension(); ++j) { assertEquals(m.getEntry(j, i), mT.getEntry(i, j), 0); } } RealMatrix mPm = m.add(m); for (int i = 0; i < mPm.getRowDimension(); ++i) { for (int j = 0; j < mPm.getColumnDimension(); ++j) { assertEquals(2 * m.getEntry(i, j), mPm.getEntry(i, j), 0); } } RealMatrix mPmMm = mPm.subtract(m); for (int i = 0; i < mPmMm.getRowDimension(); ++i) { for (int j = 0; j < mPmMm.getColumnDimension(); ++j) { assertEquals(m.getEntry(i, j), mPmMm.getEntry(i, j), 0); } } RealMatrix mTm = mT.multiply(m); for (int i = 0; i < mTm.getRowDimension(); ++i) { for (int j = 0; j < mTm.getColumnDimension(); ++j) { double sum = 0; for (int k = 0; k < mT.getColumnDimension(); ++k) { sum += (k + i / 1024.0) * (k + j / 1024.0); } assertEquals(sum, mTm.getEntry(i, j), 0); } } RealMatrix mmT = m.multiply(mT); for (int i = 0; i < mmT.getRowDimension(); ++i) { for (int j = 0; j < mmT.getColumnDimension(); ++j) { double sum = 0; for (int k = 0; k < m.getColumnDimension(); ++k) { sum += (i + k / 1024.0) * (j + k / 1024.0); } assertEquals(sum, mmT.getEntry(i, j), 0); } } RealMatrix sub1 = m.getSubMatrix(2, 9, 5, 20); for (int i = 0; i < sub1.getRowDimension(); ++i) { for (int j = 0; j < sub1.getColumnDimension(); ++j) { assertEquals((i + 2) + (j + 5) / 1024.0, sub1.getEntry(i, j), 0); } } RealMatrix sub2 = m.getSubMatrix(10, 12, 3, 70); for (int i = 0; i < sub2.getRowDimension(); ++i) { for (int j = 0; j < sub2.getColumnDimension(); ++j) { assertEquals((i + 10) + (j + 3) / 1024.0, sub2.getEntry(i, j), 0); } } RealMatrix sub3 = m.getSubMatrix(30, 34, 0, 5); for (int i = 0; i < sub3.getRowDimension(); ++i) { for (int j = 0; j < sub3.getColumnDimension(); ++j) { assertEquals((i + 30) + (j + 0) / 1024.0, sub3.getEntry(i, j), 0); } } RealMatrix sub4 = m.getSubMatrix(30, 32, 62, 65); for (int i = 0; i < sub4.getRowDimension(); ++i) { for (int j = 0; j < sub4.getColumnDimension(); ++j) { assertEquals((i + 30) + (j + 62) / 1024.0, sub4.getEntry(i, j), 0); } } } //Additional Test for BlockRealMatrixTest.testMultiply private double[][] d3 = new double[][] {{1,2,3,4},{5,6,7,8}}; private double[][] d4 = new double[][] {{1},{2},{3},{4}}; private double[][] d5 = new double[][] {{30},{70}}; public void testMultiply2() { RealMatrix m3 = new BlockRealMatrix(d3); RealMatrix m4 = new BlockRealMatrix(d4); RealMatrix m5 = new BlockRealMatrix(d5); assertClose(m3.multiply(m4), m5, entryTolerance); } /** test trace */ public void testTrace() { RealMatrix m = new BlockRealMatrix(id); assertEquals("identity trace",3d,m.getTrace(),entryTolerance); m = new BlockRealMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test scalarAdd */ public void testScalarAdd() { RealMatrix m = new BlockRealMatrix(testData); assertClose(new BlockRealMatrix(testDataPlus2), m.scalarAdd(2d), entryTolerance); } /** test operate */ public void testOperate() { RealMatrix m = new BlockRealMatrix(id); assertClose(testVector, m.operate(testVector), entryTolerance); assertClose(testVector, m.operate(new ArrayRealVector(testVector)).getData(), entryTolerance); m = new BlockRealMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testOperateLarge() { int p = (7 * BlockRealMatrix.BLOCK_SIZE) / 2; int q = (5 * BlockRealMatrix.BLOCK_SIZE) / 2; int r = 3 * BlockRealMatrix.BLOCK_SIZE; Random random = new Random(111007463902334l); RealMatrix m1 = createRandomMatrix(random, p, q); RealMatrix m2 = createRandomMatrix(random, q, r); RealMatrix m1m2 = m1.multiply(m2); for (int i = 0; i < r; ++i) { checkArrays(m1m2.getColumn(i), m1.operate(m2.getColumn(i))); } } public void testOperatePremultiplyLarge() { int p = (7 * BlockRealMatrix.BLOCK_SIZE) / 2; int q = (5 * BlockRealMatrix.BLOCK_SIZE) / 2; int r = 3 * BlockRealMatrix.BLOCK_SIZE; Random random = new Random(111007463902334l); RealMatrix m1 = createRandomMatrix(random, p, q); RealMatrix m2 = createRandomMatrix(random, q, r); RealMatrix m1m2 = m1.multiply(m2); for (int i = 0; i < p; ++i) { checkArrays(m1m2.getRow(i), m2.preMultiply(m1.getRow(i))); } } /** test issue MATH-209 */ public void testMath209() { RealMatrix a = new BlockRealMatrix(new double[][] { { 1, 2 }, { 3, 4 }, { 5, 6 } }); double[] b = a.operate(new double[] { 1, 1 }); assertEquals(a.getRowDimension(), b.length); assertEquals( 3.0, b[0], 1.0e-12); assertEquals( 7.0, b[1], 1.0e-12); assertEquals(11.0, b[2], 1.0e-12); } /** test transpose */ public void testTranspose() { RealMatrix m = new BlockRealMatrix(testData); RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose(); RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse(); assertClose(mIT, mTI, normTolerance); m = new BlockRealMatrix(testData2); RealMatrix mt = new BlockRealMatrix(testData2T); assertClose(mt, m.transpose(), normTolerance); } /** test preMultiply by vector */ public void testPremultiplyVector() { RealMatrix m = new BlockRealMatrix(testData); assertClose(m.preMultiply(testVector), preMultTest, normTolerance); assertClose(m.preMultiply(new ArrayRealVector(testVector).getData()), preMultTest, normTolerance); m = new BlockRealMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { RealMatrix m3 = new BlockRealMatrix(d3); RealMatrix m4 = new BlockRealMatrix(d4); RealMatrix m5 = new BlockRealMatrix(d5); assertClose(m4.preMultiply(m3), m5, entryTolerance); BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix mInv = new BlockRealMatrix(testDataInv); BlockRealMatrix identity = new BlockRealMatrix(id); assertClose(m.preMultiply(mInv), identity, entryTolerance); assertClose(mInv.preMultiply(m), identity, entryTolerance); assertClose(m.preMultiply(identity), m, entryTolerance); assertClose(identity.preMultiply(mInv), mInv, entryTolerance); try { m.preMultiply(new BlockRealMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { RealMatrix m = new BlockRealMatrix(testData); assertClose(m.getRow(0), testDataRow1, entryTolerance); assertClose(m.getColumn(2), testDataCol3, entryTolerance); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { RealMatrix m = new BlockRealMatrix(testData); assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance); try { m.getEntry(10, 4); fail ("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}}; RealMatrix m = new BlockRealMatrix(matrixData); // One more with three rows, two columns double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}}; RealMatrix n = new BlockRealMatrix(matrixData2); // Now multiply m by n RealMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example double[][] coefficientsData = {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}}; RealMatrix coefficients = new BlockRealMatrix(coefficientsData); double[] constants = {1, -2, 1}; double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(2 * solution[0] + 3 * solution[1] -2 * solution[2], constants[0], 1E-12); assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2], constants[1], 1E-12); assertEquals(4 * solution[0] - 3 * solution[1] -5 * solution[2], constants[2], 1E-12); } // test submatrix accessors public void testGetSubMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, -1, 1, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { RealMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn); if (reference != null) { assertEquals(new BlockRealMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns) { try { RealMatrix sub = m.getSubMatrix(selectedRows, selectedColumns); if (reference != null) { assertEquals(new BlockRealMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testGetSetMatrixLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); RealMatrix sub = new BlockRealMatrix(n - 4, n - 4).scalarAdd(1); m.setSubMatrix(sub.getData(), 2, 2); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if ((i < 2) || (i > n - 3) || (j < 2) || (j > n - 3)) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } assertEquals(sub, m.getSubMatrix(2, n - 3, 2, n - 3)); } public void testCopySubMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); checkCopy(m, subRows23Cols00, 2 , 3 , 0, 0); checkCopy(m, subRows00Cols33, 0 , 0 , 3, 3); checkCopy(m, subRows01Cols23, 0 , 1 , 2, 3); checkCopy(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkCopy(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, -1, 1, 2, 2); checkCopy(m, null, 1, 0, 2, 2); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, new int[] {}, new int[] { 0 }); checkCopy(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkCopy(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub); if (reference != null) { assertEquals(new BlockRealMatrix(reference), new BlockRealMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkCopy(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(selectedRows, selectedColumns, sub); if (reference != null) { assertEquals(new BlockRealMatrix(reference), new BlockRealMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testGetRowMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); RealMatrix mRow0 = new BlockRealMatrix(subRow0); RealMatrix mRow3 = new BlockRealMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); RealMatrix mRow3 = new BlockRealMatrix(subRow3); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowMatrix(0, mRow3); assertEquals(mRow3, m.getRowMatrix(0)); try { m.setRowMatrix(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowMatrixLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); RealMatrix sub = new BlockRealMatrix(1, n).scalarAdd(1); m.setRowMatrix(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } assertEquals(sub, m.getRowMatrix(2)); } public void testGetColumnMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); RealMatrix mColumn1 = new BlockRealMatrix(subColumn1); RealMatrix mColumn3 = new BlockRealMatrix(subColumn3); assertEquals(mColumn1, m.getColumnMatrix(1)); assertEquals(mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); RealMatrix mColumn3 = new BlockRealMatrix(subColumn3); assertNotSame(mColumn3, m.getColumnMatrix(1)); m.setColumnMatrix(1, mColumn3); assertEquals(mColumn3, m.getColumnMatrix(1)); try { m.setColumnMatrix(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnMatrixLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); RealMatrix sub = new BlockRealMatrix(n, 1).scalarAdd(1); m.setColumnMatrix(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } assertEquals(sub, m.getColumnMatrix(2)); } public void testGetRowVector() { RealMatrix m = new BlockRealMatrix(subTestData); RealVector mRow0 = new ArrayRealVector(subRow0[0]); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertEquals(mRow0, m.getRowVector(0)); assertEquals(mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowVector() { RealMatrix m = new BlockRealMatrix(subTestData); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowVector(0, mRow3); assertEquals(mRow3, m.getRowVector(0)); try { m.setRowVector(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowVectorLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); RealVector sub = new ArrayRealVector(n, 1.0); m.setRowVector(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } assertEquals(sub, m.getRowVector(2)); } public void testGetColumnVector() { RealMatrix m = new BlockRealMatrix(subTestData); RealVector mColumn1 = columnToVector(subColumn1); RealVector mColumn3 = columnToVector(subColumn3); assertEquals(mColumn1, m.getColumnVector(1)); assertEquals(mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnVector() { RealMatrix m = new BlockRealMatrix(subTestData); RealVector mColumn3 = columnToVector(subColumn3); assertNotSame(mColumn3, m.getColumnVector(1)); m.setColumnVector(1, mColumn3); assertEquals(mColumn3, m.getColumnVector(1)); try { m.setColumnVector(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnVectorLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); RealVector sub = new ArrayRealVector(n, 1.0); m.setColumnVector(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } assertEquals(sub, m.getColumnVector(2)); } private RealVector columnToVector(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayRealVector(data, false); } public void testGetRow() { RealMatrix m = new BlockRealMatrix(subTestData); checkArrays(subRow0[0], m.getRow(0)); checkArrays(subRow3[0], m.getRow(3)); try { m.getRow(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRow(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRow() { RealMatrix m = new BlockRealMatrix(subTestData); assertTrue(subRow3[0][0] != m.getRow(0)[0]); m.setRow(0, subRow3[0]); checkArrays(subRow3[0], m.getRow(0)); try { m.setRow(-1, subRow3[0]); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRow(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); double[] sub = new double[n]; Arrays.fill(sub, 1.0); m.setRow(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } checkArrays(sub, m.getRow(2)); } public void testGetColumn() { RealMatrix m = new BlockRealMatrix(subTestData); double[] mColumn1 = columnToArray(subColumn1); double[] mColumn3 = columnToArray(subColumn3); checkArrays(mColumn1, m.getColumn(1)); checkArrays(mColumn3, m.getColumn(3)); try { m.getColumn(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumn(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumn() { RealMatrix m = new BlockRealMatrix(subTestData); double[] mColumn3 = columnToArray(subColumn3); assertTrue(mColumn3[0] != m.getColumn(1)[0]); m.setColumn(1, mColumn3); checkArrays(mColumn3, m.getColumn(1)); try { m.setColumn(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumn(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnLarge() { int n = 3 * BlockRealMatrix.BLOCK_SIZE; RealMatrix m = new BlockRealMatrix(n, n); double[] sub = new double[n]; Arrays.fill(sub, 1.0); m.setColumn(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(0.0, m.getEntry(i, j), 0.0); } else { assertEquals(1.0, m.getEntry(i, j), 0.0); } } } checkArrays(sub, m.getColumn(2)); } private double[] columnToArray(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return data; } private void checkArrays(double[] expected, double[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], actual[i]); } } public void testEqualsAndHashCode() { BlockRealMatrix m = new BlockRealMatrix(testData); BlockRealMatrix m1 = m.copy(); BlockRealMatrix mt = m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(new BlockRealMatrix(bigSingular))); } public void testToString() { BlockRealMatrix m = new BlockRealMatrix(testData); assertEquals("BlockRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", m.toString()); } public void testSetSubMatrix() throws Exception { BlockRealMatrix m = new BlockRealMatrix(testData); m.setSubMatrix(detData2,1,1); RealMatrix expected = new BlockRealMatrix (new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(detData2,0,0); expected = new BlockRealMatrix (new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(testDataPlus2,0,0); expected = new BlockRealMatrix (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}}); assertEquals(expected, m); // javadoc example BlockRealMatrix matrix = new BlockRealMatrix (new double[][] {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1 , 2}}); matrix.setSubMatrix(new double[][] {{3, 4}, {5, 6}}, 1, 1); expected = new BlockRealMatrix (new double[][] {{1, 2, 3, 4}, {5, 3, 4, 8}, {9, 5 ,6, 2}}); assertEquals(expected, matrix); // dimension overflow try { m.setSubMatrix(testData,1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData,-1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData,1,-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null,1,1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } // ragged try { m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new double[][] {{}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testWalk() throws MatrixVisitorException { int rows = 150; int columns = 75; RealMatrix m = new BlockRealMatrix(rows, columns); m.walkInRowOrder(new SetVisitor()); GetVisitor getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockRealMatrix(rows, columns); m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new BlockRealMatrix(rows, columns); m.walkInColumnOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockRealMatrix(rows, columns); m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new BlockRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new BlockRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } } public void testSerial() { BlockRealMatrix m = new BlockRealMatrix(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } private static class SetVisitor extends DefaultRealMatrixChangingVisitor { @Override public double visit(int i, int j, double value) { return i + j / 1024.0; } } private static class GetVisitor extends DefaultRealMatrixPreservingVisitor { private int count = 0; @Override public void visit(int i, int j, double value) { ++count; assertEquals(i + j / 1024.0, value, 0.0); } public int getCount() { return count; } } //--------------- -----------------Protected methods /** verifies that two matrices are close (1-norm) */ protected void assertClose(RealMatrix m, RealMatrix n, double tolerance) { assertTrue(m.subtract(n).getNorm() < tolerance); } /** verifies that two vectors are close (sup norm) */ protected void assertClose(double[] m, double[] n, double tolerance) { if (m.length != n.length) { fail("vectors not same length"); } for (int i = 0; i < m.length; i++) { assertEquals(m[i], n[i], tolerance); } } private BlockRealMatrix createRandomMatrix(Random r, int rows, int columns) { BlockRealMatrix m = new BlockRealMatrix(rows, columns); for (int i = 0; i < rows; ++i) { for (int j = 0; j < columns; ++j) { m.setEntry(i, j, 200 * r.nextDouble() - 100); } } return m; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java100644 1750 1750 16706 11532241243 31136 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.linear.RealVector.Entry; import org.apache.commons.math.util.FastMath; import java.util.Iterator; import java.util.Random; /** * */ public class AbstractRealVectorTest extends TestCase { private double[] vec1 = { 1d, 2d, 3d, 4d, 5d }; private double[] vec2 = { -3d, 0d, 0d, 2d, 1d }; private static class TestVectorImpl extends AbstractRealVector { private double[] values; TestVectorImpl(double[] values) { this.values = values; } @Override public double[] getData() { return values; } @Override public AbstractRealVector copy() { return new TestVectorImpl(values.clone()); } UnsupportedOperationException unsupported() { return new UnsupportedOperationException("Test implementation only supports methods necessary for testing"); } @Override public RealVector add(RealVector v) throws IllegalArgumentException { RealVector result = new ArrayRealVector(v); return result.add(this); } @Override public RealVector subtract(RealVector v) throws IllegalArgumentException { RealVector result = new ArrayRealVector(v); return result.subtract(this).mapMultiplyToSelf(-1); } @Override public RealVector mapAddToSelf(double d) { for(int i=0; i it = v.iterator(); it.hasNext() && (e = it.next()) != null; i++) { assertEquals(vec2[i], e.getValue()); } } public void testSparseIterator() throws Exception { RealVector v = new TestVectorImpl(vec2.clone()); Entry e; int i = 0; double[] nonDefaultV2 = { -3d, 2d, 1d }; for(Iterator it = v.sparseIterator(); it.hasNext() && (e = it.next()) != null; i++) { assertEquals(nonDefaultV2[i], e.getValue()); } double [] onlyOne = {0d, 1.0, 0d}; v = new TestVectorImpl(onlyOne); for(Iterator it = v.sparseIterator(); it.hasNext() && (e = it.next()) != null; ) { assertEquals(onlyOne[1], e.getValue()); } } public void testClone() throws Exception { double[] d = new double[1000000]; Random r = new Random(1234); for(int i=0;i 0); double[] c = d.clone(); c[0] = 1; assertNotSame(c[0], d[0]); d[0] = 1; assertEquals(new ArrayRealVector(d).getNorm(), new ArrayRealVector(c).getNorm()); long cloneTime = 0; long setAndAddTime = 0; for(int i=0; i<10; i++) { long start = System.nanoTime(); double[] v = d.clone(); for(int j=0; j 4) cloneTime += System.nanoTime() - start; start = System.nanoTime(); v = new double[d.length]; for(int j=0; j 4) setAndAddTime += System.nanoTime() - start; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/MatrixIndexExceptionTest.java100644 1750 1750 2605 11532241243 31470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.exception.util.LocalizedFormats; import junit.framework.TestCase; /** * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class MatrixIndexExceptionTest extends TestCase { /** * */ public void testParameter(){ MatrixIndexException ex = new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE, 12, 0, 5); assertEquals(12, ex.getArguments()[0]); assertEquals(0, ex.getArguments()[1]); assertEquals(5, ex.getArguments()[2]); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SparseFieldVectorTest.java100644 1750 1750 24624 11532241243 30766 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionConversionException; import org.apache.commons.math.fraction.FractionField; import junit.framework.TestCase; /** * Test cases for the {@link SparseFieldVector} class. * * @version $Revision: 1003907 $ $Date: 2010-10-03 00:23:34 +0200 (dim. 03 oct. 2010) $ */ public class SparseFieldVectorTest extends TestCase { // protected Fraction[][] ma1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)}}; protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)}; protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)}; protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)}; protected Fraction[] vec4 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)}; protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)}; protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8),new Fraction(9)}; protected Fraction[][] mat1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)},{ new Fraction(7), new Fraction(8), new Fraction(9)}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; protected FractionField field = FractionField.getInstance(); public void testMapFunctions() throws FractionConversionException { SparseFieldVector v1 = new SparseFieldVector(field,vec1); //octave = v1 .+ 2.0 FieldVector v_mapAdd = v1.mapAdd(new Fraction(2)); Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)}; assertEquals("compare vectors" ,result_mapAdd,v_mapAdd.getData()); //octave = v1 .+ 2.0 FieldVector v_mapAddToSelf = v1.copy(); v_mapAddToSelf.mapAddToSelf(new Fraction(2)); Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)}; assertEquals("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData()); //octave = v1 .- 2.0 FieldVector v_mapSubtract = v1.mapSubtract(new Fraction(2)); Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)}; assertEquals("compare vectors" ,result_mapSubtract,v_mapSubtract.getData()); //octave = v1 .- 2.0 FieldVector v_mapSubtractToSelf = v1.copy(); v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2)); Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)}; assertEquals("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData()); //octave = v1 .* 2.0 FieldVector v_mapMultiply = v1.mapMultiply(new Fraction(2)); Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)}; assertEquals("compare vectors" ,result_mapMultiply,v_mapMultiply.getData()); //octave = v1 .* 2.0 FieldVector v_mapMultiplyToSelf = v1.copy(); v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2)); Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)}; assertEquals("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData()); //octave = v1 ./ 2.0 FieldVector v_mapDivide = v1.mapDivide(new Fraction(2)); Fraction[] result_mapDivide = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; assertEquals("compare vectors" ,result_mapDivide,v_mapDivide.getData()); //octave = v1 ./ 2.0 FieldVector v_mapDivideToSelf = v1.copy(); v_mapDivideToSelf.mapDivideToSelf(new Fraction(2)); Fraction[] result_mapDivideToSelf = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)}; assertEquals("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData()); //octave = v1 .^-1 FieldVector v_mapInv = v1.mapInv(); Fraction[] result_mapInv = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; assertEquals("compare vectors" ,result_mapInv,v_mapInv.getData()); //octave = v1 .^-1 FieldVector v_mapInvToSelf = v1.copy(); v_mapInvToSelf.mapInvToSelf(); Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)}; assertEquals("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData()); } public void testBasicFunctions() throws FractionConversionException { SparseFieldVector v1 = new SparseFieldVector(field,vec1); SparseFieldVector v2 = new SparseFieldVector(field,vec2); SparseFieldVector v2_t = new SparseFieldVector(field,vec2); //octave = v1 + v2 FieldVector v_add = v1.add(v2); Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)}; assertEquals("compare vect" ,v_add.getData(),result_add); SparseFieldVector vt2 = new SparseFieldVector(field,vec2); FieldVector v_add_i = v1.add(vt2); Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)}; assertEquals("compare vect" ,v_add_i.getData(),result_add_i); //octave = v1 - v2 SparseFieldVector v_subtract = v1.subtract(v2); Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); FieldVector v_subtract_i = v1.subtract(vt2); Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); // octave v1 .* v2 FieldVector v_ebeMultiply = v1.ebeMultiply(v2); Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)}; assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); FieldVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)}; assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); // octave v1 ./ v2 FieldVector v_ebeDivide = v1.ebeDivide(v2); Fraction[] result_ebeDivide = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); FieldVector v_ebeDivide_2 = v1.ebeDivide(v2_t); Fraction[] result_ebeDivide_2 = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)}; assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); // octave dot(v1,v2) Fraction dot = v1.dotProduct(v2); assertEquals("compare val ",new Fraction(32), dot); // octave dot(v1,v2_t) Fraction dot_2 = v1.dotProduct(v2_t); assertEquals("compare val ",new Fraction(32), dot_2); FieldMatrix m_outerProduct = v1.outerProduct(v2); assertEquals("compare val ",new Fraction(4), m_outerProduct.getEntry(0,0)); FieldMatrix m_outerProduct_2 = v1.outerProduct(v2_t); assertEquals("compare val ",new Fraction(4), m_outerProduct_2.getEntry(0,0)); } public void testMisc() { SparseFieldVector v1 = new SparseFieldVector(field,vec1); String out1 = v1.toString(); assertTrue("some output ", out1.length()!=0); try { v1.checkVectorDimensions(2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } } public void testPredicates() { SparseFieldVector v = new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) }); v.setEntry(0, field.getZero()); assertEquals(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) })); assertNotSame(v, new SparseFieldVector(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2), new Fraction(3) })); } /** verifies that two vectors are close (sup norm) */ protected void assertEquals(String msg, Fraction[] m, Fraction[] n) { if (m.length != n.length) { fail("vectors have different lengths"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i],n[i]); } } /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, Fraction[] m, Fraction[] n, double tolerance) { if (m.length != n.length) { fail("vectors have different lengths"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i].doubleValue(),n[i].doubleValue(), tolerance); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java100644 1750 1750 10447 11532241243 30354 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.MathException; public class CholeskySolverTest extends TestCase { private double[][] testData = new double[][] { { 1, 2, 4, 7, 11 }, { 2, 13, 23, 38, 58 }, { 4, 23, 77, 122, 182 }, { 7, 38, 122, 294, 430 }, { 11, 58, 182, 430, 855 } }; public CholeskySolverTest(String name) { super(name); } /** test solve dimension errors */ public void testSolveDimensionErrors() throws MathException { DecompositionSolver solver = new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]); try { solver.solve(b); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } } /** test solve */ public void testSolve() throws MathException { DecompositionSolver solver = new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { 78, -13, 1 }, { 414, -62, -1 }, { 1312, -202, -37 }, { 2989, -542, 145 }, { 5510, -1465, 201 } }); RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] { { 1, 0, 1 }, { 0, 1, 1 }, { 2, 1, -4 }, { 2, 2, 2 }, { 5, -3, 0 } }); // using RealMatrix assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 1.0e-13); // using double[] for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, new ArrayRealVector(solver.solve(b.getColumn(i))).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using ArrayRealVector for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, solver.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using RealVector with an alternate implementation for (int i = 0; i < b.getColumnDimension(); ++i) { ArrayRealVectorTest.RealVectorTestImpl v = new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i)); assertEquals(0, solver.solve(v).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } } /** test determinant */ public void testDeterminant() throws MathException { assertEquals(7290000.0, getDeterminant(MatrixUtils.createRealMatrix(testData)), 1.0e-15); } private double getDeterminant(RealMatrix m) throws MathException { return new CholeskyDecompositionImpl(m).getDeterminant(); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/LUSolverTest.java100644 1750 1750 15356 11532241243 27117 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; public class LUSolverTest extends TestCase { private double[][] testData = { { 1.0, 2.0, 3.0}, { 2.0, 5.0, 3.0}, { 1.0, 0.0, 8.0} }; private double[][] luData = { { 2.0, 3.0, 3.0 }, { 0.0, 5.0, 7.0 }, { 6.0, 9.0, 8.0 } }; // singular matrices private double[][] singular = { { 2.0, 3.0 }, { 2.0, 3.0 } }; private double[][] bigSingular = { { 1.0, 2.0, 3.0, 4.0 }, { 2.0, 5.0, 3.0, 4.0 }, { 7.0, 3.0, 256.0, 1930.0 }, { 3.0, 7.0, 6.0, 8.0 } }; // 4th row = 1st + 2nd public LUSolverTest(String name) { super(name); } /** test threshold impact */ public void testThreshold() { final RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 2.0, 3.0}, { 2.0, 5.0, 3.0}, { 4.000001, 9.0, 9.0} }); assertFalse(new LUDecompositionImpl(matrix, 1.0e-5).getSolver().isNonSingular()); assertTrue(new LUDecompositionImpl(matrix, 1.0e-10).getSolver().isNonSingular()); } /** test singular */ public void testSingular() { DecompositionSolver solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver(); assertTrue(solver.isNonSingular()); solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(singular)).getSolver(); assertFalse(solver.isNonSingular()); solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(bigSingular)).getSolver(); assertFalse(solver.isNonSingular()); } /** test solve dimension errors */ public void testSolveDimensionErrors() { DecompositionSolver solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]); try { solver.solve(b); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } } /** test solve singularity errors */ public void testSolveSingularityErrors() { DecompositionSolver solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(singular)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]); try { solver.solve(b); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } try { solver.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } try { solver.solve(b.getColumnVector(0)); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } try { solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } } /** test solve */ public void testSolve() { DecompositionSolver solver = new LUDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { 1, 0 }, { 2, -5 }, { 3, 1 } }); RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] { { 19, -71 }, { -6, 22 }, { -2, 9 } }); // using RealMatrix assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 1.0e-13); // using double[] for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, new ArrayRealVector(solver.solve(b.getColumn(i))).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using ArrayRealVector for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, solver.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using RealVector with an alternate implementation for (int i = 0; i < b.getColumnDimension(); ++i) { ArrayRealVectorTest.RealVectorTestImpl v = new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i)); assertEquals(0, solver.solve(v).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } } /** test determinant */ public void testDeterminant() { assertEquals( -1, getDeterminant(MatrixUtils.createRealMatrix(testData)), 1.0e-15); assertEquals(-10, getDeterminant(MatrixUtils.createRealMatrix(luData)), 1.0e-14); assertEquals( 0, getDeterminant(MatrixUtils.createRealMatrix(singular)), 1.0e-17); assertEquals( 0, getDeterminant(MatrixUtils.createRealMatrix(bigSingular)), 1.0e-10); } private double getDeterminant(RealMatrix m) { return new LUDecompositionImpl(m).getDeterminant(); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/RealVectorFormatTest.java100644 1750 1750 2131 11532241243 30566 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Locale; public class RealVectorFormatTest extends RealVectorFormatAbstractTest { @Override protected char getDecimalCharacter() { return '.'; } @Override protected Locale getLocale() { return Locale.US; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/Array2DRowRealMatrixTest.java100644 1750 1750 115147 11532241243 31350 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link Array2DRowRealMatrix} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public final class Array2DRowRealMatrixTest extends TestCase { // 3 x 3 identity matrix protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} }; // Test data for group operations protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} }; protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}}; protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} }; protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d}, {-1d,0d,-8d} }; protected double[] testDataRow1 = {1d,2d,3d}; protected double[] testDataCol3 = {3d,3d,8d}; protected double[][] testDataInv = { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} }; protected double[] preMultTest = {8,12,33}; protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}}; protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}}; protected double[][] testDataPlusInv = { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} }; // lu decomposition tests protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} }; protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d}, {0.33333333333333,0d,0.33333333333333} }; // singular matrices protected double[][] singular = { {2d,3d}, {2d,3d} }; protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d}, {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} }; protected double[][] detData2 = { {1d, 3d}, {2d, 4d}}; // vectors protected double[] testVector = {1,2,3}; protected double[] testVector2 = {1,2,3,4}; // submatrix accessor tests protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5}, {2, 4, 6, 8}, {4, 5, 6, 7}}; // array selections protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}}; protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}}; protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}}; // effective permutations protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}}; protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}}; // contiguous ranges protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}}; protected double[][] subRows23Cols00 = {{2} , {4}}; protected double[][] subRows00Cols33 = {{4}}; // row matrices protected double[][] subRow0 = {{1,2,3,4}}; protected double[][] subRow3 = {{4,5,6,7}}; // column matrices protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}}; protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public Array2DRowRealMatrixTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2); assertEquals("testData row dimension",3,m.getRowDimension()); assertEquals("testData column dimension",3,m.getColumnDimension()); assertTrue("testData is square",m.isSquare()); assertEquals("testData2 row dimension",m2.getRowDimension(),2); assertEquals("testData2 column dimension",m2.getColumnDimension(),3); assertTrue("testData2 is not square",!m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { Array2DRowRealMatrix m1 = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(m1.getData()); assertEquals(m2,m1); Array2DRowRealMatrix m3 = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m4 = new Array2DRowRealMatrix(m3.getData(), false); assertEquals(m4,m3); } /** test add */ public void testAdd() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv); RealMatrix mPlusMInv = m.add(mInv); double[][] sumEntries = mPlusMInv.getData(); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals("sum entry entry", testDataPlusInv[row][col],sumEntries[row][col], entryTolerance); } } } /** test add failure */ public void testAddFail() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test norm */ public void testNorm() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2); assertEquals("testData norm",14d,m.getNorm(),entryTolerance); assertEquals("testData2 norm",7d,m2.getNorm(),entryTolerance); } /** test Frobenius norm */ public void testFrobeniusNorm() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2); assertEquals("testData Frobenius norm", FastMath.sqrt(117.0), m.getFrobeniusNorm(), entryTolerance); assertEquals("testData2 Frobenius norm", FastMath.sqrt(52.0), m2.getFrobeniusNorm(), entryTolerance); } /** test m-n = m + -n */ public void testPlusMinus() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testDataInv); TestUtils.assertEquals("m-n = m + -n",m.subtract(m2), m2.scalarMultiply(-1d).add(m),entryTolerance); try { m.subtract(new Array2DRowRealMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv); Array2DRowRealMatrix identity = new Array2DRowRealMatrix(id); Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2); TestUtils.assertEquals("inverse multiply",m.multiply(mInv), identity,entryTolerance); TestUtils.assertEquals("inverse multiply",mInv.multiply(m), identity,entryTolerance); TestUtils.assertEquals("identity multiply",m.multiply(identity), m,entryTolerance); TestUtils.assertEquals("identity multiply",identity.multiply(mInv), mInv,entryTolerance); TestUtils.assertEquals("identity multiply",m2.multiply(identity), m2,entryTolerance); try { m.multiply(new Array2DRowRealMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } //Additional Test for Array2DRowRealMatrixTest.testMultiply private double[][] d3 = new double[][] {{1,2,3,4},{5,6,7,8}}; private double[][] d4 = new double[][] {{1},{2},{3},{4}}; private double[][] d5 = new double[][] {{30},{70}}; public void testMultiply2() { RealMatrix m3 = new Array2DRowRealMatrix(d3); RealMatrix m4 = new Array2DRowRealMatrix(d4); RealMatrix m5 = new Array2DRowRealMatrix(d5); TestUtils.assertEquals("m3*m4=m5", m3.multiply(m4), m5, entryTolerance); } /** test trace */ public void testTrace() { RealMatrix m = new Array2DRowRealMatrix(id); assertEquals("identity trace",3d,m.getTrace(),entryTolerance); m = new Array2DRowRealMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test sclarAdd */ public void testScalarAdd() { RealMatrix m = new Array2DRowRealMatrix(testData); TestUtils.assertEquals("scalar add",new Array2DRowRealMatrix(testDataPlus2), m.scalarAdd(2d),entryTolerance); } /** test operate */ public void testOperate() { RealMatrix m = new Array2DRowRealMatrix(id); TestUtils.assertEquals("identity operate", testVector, m.operate(testVector), entryTolerance); TestUtils.assertEquals("identity operate", testVector, m.operate(new ArrayRealVector(testVector)).getData(), entryTolerance); m = new Array2DRowRealMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test issue MATH-209 */ public void testMath209() { RealMatrix a = new Array2DRowRealMatrix(new double[][] { { 1, 2 }, { 3, 4 }, { 5, 6 } }, false); double[] b = a.operate(new double[] { 1, 1 }); assertEquals(a.getRowDimension(), b.length); assertEquals( 3.0, b[0], 1.0e-12); assertEquals( 7.0, b[1], 1.0e-12); assertEquals(11.0, b[2], 1.0e-12); } /** test transpose */ public void testTranspose() { RealMatrix m = new Array2DRowRealMatrix(testData); RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose(); RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse(); TestUtils.assertEquals("inverse-transpose", mIT, mTI, normTolerance); m = new Array2DRowRealMatrix(testData2); RealMatrix mt = new Array2DRowRealMatrix(testData2T); TestUtils.assertEquals("transpose",mt,m.transpose(),normTolerance); } /** test preMultiply by vector */ public void testPremultiplyVector() { RealMatrix m = new Array2DRowRealMatrix(testData); TestUtils.assertEquals("premultiply", m.preMultiply(testVector), preMultTest, normTolerance); TestUtils.assertEquals("premultiply", m.preMultiply(new ArrayRealVector(testVector).getData()), preMultTest, normTolerance); m = new Array2DRowRealMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { RealMatrix m3 = new Array2DRowRealMatrix(d3); RealMatrix m4 = new Array2DRowRealMatrix(d4); RealMatrix m5 = new Array2DRowRealMatrix(d5); TestUtils.assertEquals("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance); Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv); Array2DRowRealMatrix identity = new Array2DRowRealMatrix(id); TestUtils.assertEquals("inverse multiply",m.preMultiply(mInv), identity,entryTolerance); TestUtils.assertEquals("inverse multiply",mInv.preMultiply(m), identity,entryTolerance); TestUtils.assertEquals("identity multiply",m.preMultiply(identity), m,entryTolerance); TestUtils.assertEquals("identity multiply",identity.preMultiply(mInv), mInv,entryTolerance); try { m.preMultiply(new Array2DRowRealMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { RealMatrix m = new Array2DRowRealMatrix(testData); TestUtils.assertEquals("get row",m.getRow(0),testDataRow1,entryTolerance); TestUtils.assertEquals("get col",m.getColumn(2),testDataCol3,entryTolerance); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { RealMatrix m = new Array2DRowRealMatrix(testData); assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance); try { m.getEntry(10, 4); fail ("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}}; RealMatrix m = new Array2DRowRealMatrix(matrixData); // One more with three rows, two columns double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}}; RealMatrix n = new Array2DRowRealMatrix(matrixData2); // Now multiply m by n RealMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example double[][] coefficientsData = {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}}; RealMatrix coefficients = new Array2DRowRealMatrix(coefficientsData); double[] constants = {1, -2, 1}; double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(2 * solution[0] + 3 * solution[1] -2 * solution[2], constants[0], 1E-12); assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2], constants[1], 1E-12); assertEquals(4 * solution[0] - 3 * solution[1] -5 * solution[2], constants[2], 1E-12); } // test submatrix accessors public void testGetSubMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0, false); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3, false); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3, false); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }, false); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }, false); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkGetSubMatrix(m, null, 1, 0, 2, 4, true); checkGetSubMatrix(m, null, -1, 1, 2, 2, true); checkGetSubMatrix(m, null, 1, 0, 2, 2, true); checkGetSubMatrix(m, null, 1, 0, 2, 4, true); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }, true); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }, true); } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn, boolean mustFail) { try { RealMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn); assertEquals(new Array2DRowRealMatrix(reference), sub); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } private void checkGetSubMatrix(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns, boolean mustFail) { try { RealMatrix sub = m.getSubMatrix(selectedRows, selectedColumns); assertEquals(new Array2DRowRealMatrix(reference), sub); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } public void testCopySubMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); checkCopy(m, subRows23Cols00, 2 , 3 , 0, 0, false); checkCopy(m, subRows00Cols33, 0 , 0 , 3, 3, false); checkCopy(m, subRows01Cols23, 0 , 1 , 2, 3, false); checkCopy(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }, false); checkCopy(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }, false); checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }, false); checkCopy(m, null, 1, 0, 2, 4, true); checkCopy(m, null, -1, 1, 2, 2, true); checkCopy(m, null, 1, 0, 2, 2, true); checkCopy(m, null, 1, 0, 2, 4, true); checkCopy(m, null, new int[] {}, new int[] { 0 }, true); checkCopy(m, null, new int[] { 0 }, new int[] { 4 }, true); } private void checkCopy(RealMatrix m, double[][] reference, int startRow, int endRow, int startColumn, int endColumn, boolean mustFail) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub); assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub)); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } private void checkCopy(RealMatrix m, double[][] reference, int[] selectedRows, int[] selectedColumns, boolean mustFail) { try { double[][] sub = (reference == null) ? new double[1][1] : new double[reference.length][reference[0].length]; m.copySubMatrix(selectedRows, selectedColumns, sub); assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub)); if (mustFail) { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (!mustFail) { throw e; } } } public void testGetRowMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealMatrix mRow0 = new Array2DRowRealMatrix(subRow0); RealMatrix mRow3 = new Array2DRowRealMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealMatrix mRow3 = new Array2DRowRealMatrix(subRow3); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowMatrix(0, mRow3); assertEquals(mRow3, m.getRowMatrix(0)); try { m.setRowMatrix(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealMatrix mColumn1 = new Array2DRowRealMatrix(subColumn1); RealMatrix mColumn3 = new Array2DRowRealMatrix(subColumn3); assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnMatrix() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealMatrix mColumn3 = new Array2DRowRealMatrix(subColumn3); assertNotSame(mColumn3, m.getColumnMatrix(1)); m.setColumnMatrix(1, mColumn3); assertEquals(mColumn3, m.getColumnMatrix(1)); try { m.setColumnMatrix(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetRowVector() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealVector mRow0 = new ArrayRealVector(subRow0[0]); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertEquals("Row0", mRow0, m.getRowVector(0)); assertEquals("Row3", mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowVector() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealVector mRow3 = new ArrayRealVector(subRow3[0]); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowVector(0, mRow3); assertEquals(mRow3, m.getRowVector(0)); try { m.setRowVector(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumnVector() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealVector mColumn1 = columnToVector(subColumn1); RealVector mColumn3 = columnToVector(subColumn3); assertEquals("Column1", mColumn1, m.getColumnVector(1)); assertEquals("Column3", mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnVector() { RealMatrix m = new Array2DRowRealMatrix(subTestData); RealVector mColumn3 = columnToVector(subColumn3); assertNotSame(mColumn3, m.getColumnVector(1)); m.setColumnVector(1, mColumn3); assertEquals(mColumn3, m.getColumnVector(1)); try { m.setColumnVector(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnVector(0, new ArrayRealVector(5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private RealVector columnToVector(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayRealVector(data, false); } public void testGetRow() { RealMatrix m = new Array2DRowRealMatrix(subTestData); checkArrays(subRow0[0], m.getRow(0)); checkArrays(subRow3[0], m.getRow(3)); try { m.getRow(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRow(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRow() { RealMatrix m = new Array2DRowRealMatrix(subTestData); assertTrue(subRow3[0][0] != m.getRow(0)[0]); m.setRow(0, subRow3[0]); checkArrays(subRow3[0], m.getRow(0)); try { m.setRow(-1, subRow3[0]); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRow(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetColumn() { RealMatrix m = new Array2DRowRealMatrix(subTestData); double[] mColumn1 = columnToArray(subColumn1); double[] mColumn3 = columnToArray(subColumn3); checkArrays(mColumn1, m.getColumn(1)); checkArrays(mColumn3, m.getColumn(3)); try { m.getColumn(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumn(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumn() { RealMatrix m = new Array2DRowRealMatrix(subTestData); double[] mColumn3 = columnToArray(subColumn3); assertTrue(mColumn3[0] != m.getColumn(1)[0]); m.setColumn(1, mColumn3); checkArrays(mColumn3, m.getColumn(1)); try { m.setColumn(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumn(0, new double[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } private double[] columnToArray(double[][] column) { double[] data = new double[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return data; } private void checkArrays(double[] expected, double[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], actual[i]); } } public void testEqualsAndHashCode() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); Array2DRowRealMatrix m1 = (Array2DRowRealMatrix) m.copy(); Array2DRowRealMatrix mt = (Array2DRowRealMatrix) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(new Array2DRowRealMatrix(bigSingular))); } public void testToString() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); assertEquals("Array2DRowRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", m.toString()); m = new Array2DRowRealMatrix(); assertEquals("Array2DRowRealMatrix{}", m.toString()); } public void testSetSubMatrix() throws Exception { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); m.setSubMatrix(detData2,1,1); RealMatrix expected = MatrixUtils.createRealMatrix (new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(detData2,0,0); expected = MatrixUtils.createRealMatrix (new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}}); assertEquals(expected, m); m.setSubMatrix(testDataPlus2,0,0); expected = MatrixUtils.createRealMatrix (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}}); assertEquals(expected, m); // dimension overflow try { m.setSubMatrix(testData,1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData,-1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData,1,-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null,1,1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(); try { m2.setSubMatrix(testData,0,1); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } try { m2.setSubMatrix(testData,1,0); fail("expecting IllegalStateException"); } catch (IllegalStateException e) { // expected } // ragged try { m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new double[][] {{}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testWalk() throws MatrixVisitorException { int rows = 150; int columns = 75; RealMatrix m = new Array2DRowRealMatrix(rows, columns); m.walkInRowOrder(new SetVisitor()); GetVisitor getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowRealMatrix(rows, columns); m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new Array2DRowRealMatrix(rows, columns); m.walkInColumnOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowRealMatrix(rows, columns); m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new Array2DRowRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } m = new Array2DRowRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new Array2DRowRealMatrix(rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(0.0, m.getEntry(i, 0), 0); assertEquals(0.0, m.getEntry(i, columns - 1), 0); } for (int j = 0; j < columns; ++j) { assertEquals(0.0, m.getEntry(0, j), 0); assertEquals(0.0, m.getEntry(rows - 1, j), 0); } } public void testSerial() { Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } private static class SetVisitor extends DefaultRealMatrixChangingVisitor { @Override public double visit(int i, int j, double value) { return i + j / 1024.0; } } private static class GetVisitor extends DefaultRealMatrixPreservingVisitor { private int count = 0; @Override public void visit(int i, int j, double value) { ++count; assertEquals(i + j / 1024.0, value, 0.0); } public int getCount() { return count; } } //--------------- -----------------Protected methods /** extracts the l and u matrices from compact lu representation */ protected void splitLU(RealMatrix lu, double[][] lowerData, double[][] upperData) throws InvalidMatrixException { if (!lu.isSquare() || lowerData.length != lowerData[0].length || upperData.length != upperData[0].length || lowerData.length != upperData.length || lowerData.length != lu.getRowDimension()) { throw new InvalidMatrixException("incorrect dimensions"); } int n = lu.getRowDimension(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j < i) { lowerData[i][j] = lu.getEntry(i, j); upperData[i][j] = 0d; } else if (i == j) { lowerData[i][j] = 1d; upperData[i][j] = lu.getEntry(i, j); } else { lowerData[i][j] = 0d; upperData[i][j] = lu.getEntry(i, j); } } } } /** Returns the result of applying the given row permutation to the matrix */ protected RealMatrix permuteRows(RealMatrix matrix, int[] permutation) { if (!matrix.isSquare() || matrix.getRowDimension() != permutation.length) { throw new IllegalArgumentException("dimension mismatch"); } int n = matrix.getRowDimension(); int m = matrix.getColumnDimension(); double out[][] = new double[m][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { out[i][j] = matrix.getEntry(permutation[i], j); } } return new Array2DRowRealMatrix(out); } // /** Useful for debugging */ // private void dumpMatrix(RealMatrix m) { // for (int i = 0; i < m.getRowDimension(); i++) { // String os = ""; // for (int j = 0; j < m.getColumnDimension(); j++) { // os += m.getEntry(i, j) + " "; // } // System.out.println(os); // } // } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/QRSolverTest.java100644 1750 1750 20036 11532241243 27110 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Random; import org.apache.commons.math.linear.MatrixVisitorException; import junit.framework.TestCase; public class QRSolverTest extends TestCase { double[][] testData3x3NonSingular = { { 12, -51, 4 }, { 6, 167, -68 }, { -4, 24, -41 } }; double[][] testData3x3Singular = { { 1, 2, 2 }, { 2, 4, 6 }, { 4, 8, 12 } }; double[][] testData3x4 = { { 12, -51, 4, 1 }, { 6, 167, -68, 2 }, { -4, 24, -41, 3 } }; double[][] testData4x3 = { { 12, -51, 4 }, { 6, 167, -68 }, { -4, 24, -41 }, { -5, 34, 7 } }; public QRSolverTest(String name) { super(name); } /** test rank */ public void testRank() { DecompositionSolver solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3NonSingular)).getSolver(); assertTrue(solver.isNonSingular()); solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3Singular)).getSolver(); assertFalse(solver.isNonSingular()); solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x4)).getSolver(); assertTrue(solver.isNonSingular()); solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData4x3)).getSolver(); assertTrue(solver.isNonSingular()); } /** test solve dimension errors */ public void testSolveDimensionErrors() { DecompositionSolver solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3NonSingular)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]); try { solver.solve(b); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(b.getColumnVector(0)); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } } /** test solve rank errors */ public void testSolveRankErrors() { DecompositionSolver solver = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3Singular)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[3][2]); try { solver.solve(b); fail("an exception should have been thrown"); } catch (InvalidMatrixException iae) { // expected behavior } try { solver.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (InvalidMatrixException iae) { // expected behavior } try { solver.solve(b.getColumnVector(0)); fail("an exception should have been thrown"); } catch (InvalidMatrixException iae) { // expected behavior } } /** test solve */ public void testSolve() { QRDecomposition decomposition = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3NonSingular)); DecompositionSolver solver = decomposition.getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { -102, 12250 }, { 544, 24500 }, { 167, -36750 } }); RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] { { 1, 2515 }, { 2, 422 }, { -3, 898 } }); // using RealMatrix assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 2.0e-16 * xRef.getNorm()); // using double[] for (int i = 0; i < b.getColumnDimension(); ++i) { final double[] x = solver.solve(b.getColumn(i)); final double error = new ArrayRealVector(x).subtract(xRef.getColumnVector(i)).getNorm(); assertEquals(0, error, 3.0e-16 * xRef.getColumnVector(i).getNorm()); } // using ArrayRealVector for (int i = 0; i < b.getColumnDimension(); ++i) { final RealVector x = solver.solve(b.getColumnVector(i)); final double error = x.subtract(xRef.getColumnVector(i)).getNorm(); assertEquals(0, error, 3.0e-16 * xRef.getColumnVector(i).getNorm()); } // using RealVector with an alternate implementation for (int i = 0; i < b.getColumnDimension(); ++i) { ArrayRealVectorTest.RealVectorTestImpl v = new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i)); final RealVector x = solver.solve(v); final double error = x.subtract(xRef.getColumnVector(i)).getNorm(); assertEquals(0, error, 3.0e-16 * xRef.getColumnVector(i).getNorm()); } } public void testOverdetermined() throws MatrixVisitorException { final Random r = new Random(5559252868205245l); int p = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; RealMatrix a = createTestMatrix(r, p, q); RealMatrix xRef = createTestMatrix(r, q, BlockRealMatrix.BLOCK_SIZE + 3); // build a perturbed system: A.X + noise = B RealMatrix b = a.multiply(xRef); final double noise = 0.001; b.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() { @Override public double visit(int row, int column, double value) { return value * (1.0 + noise * (2 * r.nextDouble() - 1)); } }); // despite perturbation, the least square solution should be pretty good RealMatrix x = new QRDecompositionImpl(a).getSolver().solve(b); assertEquals(0, x.subtract(xRef).getNorm(), 0.01 * noise * p * q); } public void testUnderdetermined() throws MatrixVisitorException { final Random r = new Random(42185006424567123l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; RealMatrix a = createTestMatrix(r, p, q); RealMatrix xRef = createTestMatrix(r, q, BlockRealMatrix.BLOCK_SIZE + 3); RealMatrix b = a.multiply(xRef); RealMatrix x = new QRDecompositionImpl(a).getSolver().solve(b); // too many equations, the system cannot be solved at all assertTrue(x.subtract(xRef).getNorm() / (p * q) > 0.01); // the last unknown should have been set to 0 assertEquals(0.0, x.getSubMatrix(p, q - 1, 0, x.getColumnDimension() - 1).getNorm()); } private RealMatrix createTestMatrix(final Random r, final int rows, final int columns) throws MatrixVisitorException { RealMatrix m = MatrixUtils.createRealMatrix(rows, columns); m.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor(){ @Override public double visit(int row, int column, double value) { return 2.0 * r.nextDouble() - 1.0; } }); return m; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/FieldLUDecompositionImplTest.java100644 1750 1750 30577 11532241243 32251 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionField; public class FieldLUDecompositionImplTest extends TestCase { private Fraction[][] testData = { { new Fraction(1), new Fraction(2), new Fraction(3)}, { new Fraction(2), new Fraction(5), new Fraction(3)}, { new Fraction(1), new Fraction(0), new Fraction(8)} }; private Fraction[][] testDataMinus = { { new Fraction(-1), new Fraction(-2), new Fraction(-3)}, { new Fraction(-2), new Fraction(-5), new Fraction(-3)}, { new Fraction(-1), new Fraction(0), new Fraction(-8)} }; private Fraction[][] luData = { { new Fraction(2), new Fraction(3), new Fraction(3) }, { new Fraction(2), new Fraction(3), new Fraction(7) }, { new Fraction(6), new Fraction(6), new Fraction(8) } }; // singular matrices private Fraction[][] singular = { { new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(3) } }; private Fraction[][] bigSingular = { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(2), new Fraction(5), new Fraction(3), new Fraction(4) }, { new Fraction(7), new Fraction(3), new Fraction(256), new Fraction(1930) }, { new Fraction(3), new Fraction(7), new Fraction(6), new Fraction(8) } }; // 4th row = 1st + 2nd public FieldLUDecompositionImplTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { FieldMatrix matrix = new Array2DRowFieldMatrix(testData); FieldLUDecomposition LU = new FieldLUDecompositionImpl(matrix); assertEquals(testData.length, LU.getL().getRowDimension()); assertEquals(testData.length, LU.getL().getColumnDimension()); assertEquals(testData.length, LU.getU().getRowDimension()); assertEquals(testData.length, LU.getU().getColumnDimension()); assertEquals(testData.length, LU.getP().getRowDimension()); assertEquals(testData.length, LU.getP().getColumnDimension()); } /** test non-square matrix */ public void testNonSquare() { try { new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(new Fraction[][] { { Fraction.ZERO, Fraction.ZERO }, { Fraction.ZERO, Fraction.ZERO }, { Fraction.ZERO, Fraction.ZERO } })); fail("Expected InvalidMatrixException"); } catch (InvalidMatrixException ime) { // expected behavior } } /** test PA = LU */ public void testPAEqualLU() { FieldMatrix matrix = new Array2DRowFieldMatrix(testData); FieldLUDecomposition lu = new FieldLUDecompositionImpl(matrix); FieldMatrix l = lu.getL(); FieldMatrix u = lu.getU(); FieldMatrix p = lu.getP(); TestUtils.assertEquals(p.multiply(matrix), l.multiply(u)); matrix = new Array2DRowFieldMatrix(testDataMinus); lu = new FieldLUDecompositionImpl(matrix); l = lu.getL(); u = lu.getU(); p = lu.getP(); TestUtils.assertEquals(p.multiply(matrix), l.multiply(u)); matrix = new Array2DRowFieldMatrix(FractionField.getInstance(), 17, 17); for (int i = 0; i < matrix.getRowDimension(); ++i) { matrix.setEntry(i, i, Fraction.ONE); } lu = new FieldLUDecompositionImpl(matrix); l = lu.getL(); u = lu.getU(); p = lu.getP(); TestUtils.assertEquals(p.multiply(matrix), l.multiply(u)); matrix = new Array2DRowFieldMatrix(singular); lu = new FieldLUDecompositionImpl(matrix); assertFalse(lu.getSolver().isNonSingular()); assertNull(lu.getL()); assertNull(lu.getU()); assertNull(lu.getP()); matrix = new Array2DRowFieldMatrix(bigSingular); lu = new FieldLUDecompositionImpl(matrix); assertFalse(lu.getSolver().isNonSingular()); assertNull(lu.getL()); assertNull(lu.getU()); assertNull(lu.getP()); } /** test that L is lower triangular with unit diagonal */ public void testLLowerTriangular() { FieldMatrix matrix = new Array2DRowFieldMatrix(testData); FieldMatrix l = new FieldLUDecompositionImpl(matrix).getL(); for (int i = 0; i < l.getRowDimension(); i++) { assertEquals(Fraction.ONE, l.getEntry(i, i)); for (int j = i + 1; j < l.getColumnDimension(); j++) { assertEquals(Fraction.ZERO, l.getEntry(i, j)); } } } /** test that U is upper triangular */ public void testUUpperTriangular() { FieldMatrix matrix = new Array2DRowFieldMatrix(testData); FieldMatrix u = new FieldLUDecompositionImpl(matrix).getU(); for (int i = 0; i < u.getRowDimension(); i++) { for (int j = 0; j < i; j++) { assertEquals(Fraction.ZERO, u.getEntry(i, j)); } } } /** test that P is a permutation matrix */ public void testPPermutation() { FieldMatrix matrix = new Array2DRowFieldMatrix(testData); FieldMatrix p = new FieldLUDecompositionImpl(matrix).getP(); FieldMatrix ppT = p.multiply(p.transpose()); FieldMatrix id = new Array2DRowFieldMatrix(FractionField.getInstance(), p.getRowDimension(), p.getRowDimension()); for (int i = 0; i < id.getRowDimension(); ++i) { id.setEntry(i, i, Fraction.ONE); } TestUtils.assertEquals(id, ppT); for (int i = 0; i < p.getRowDimension(); i++) { int zeroCount = 0; int oneCount = 0; int otherCount = 0; for (int j = 0; j < p.getColumnDimension(); j++) { final Fraction e = p.getEntry(i, j); if (e.equals(Fraction.ZERO)) { ++zeroCount; } else if (e.equals(Fraction.ONE)) { ++oneCount; } else { ++otherCount; } } assertEquals(p.getColumnDimension() - 1, zeroCount); assertEquals(1, oneCount); assertEquals(0, otherCount); } for (int j = 0; j < p.getColumnDimension(); j++) { int zeroCount = 0; int oneCount = 0; int otherCount = 0; for (int i = 0; i < p.getRowDimension(); i++) { final Fraction e = p.getEntry(i, j); if (e.equals(Fraction.ZERO)) { ++zeroCount; } else if (e.equals(Fraction.ONE)) { ++oneCount; } else { ++otherCount; } } assertEquals(p.getRowDimension() - 1, zeroCount); assertEquals(1, oneCount); assertEquals(0, otherCount); } } /** test singular */ public void testSingular() { FieldLUDecomposition lu = new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(testData)); assertTrue(lu.getSolver().isNonSingular()); lu = new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(singular)); assertFalse(lu.getSolver().isNonSingular()); lu = new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(bigSingular)); assertFalse(lu.getSolver().isNonSingular()); } /** test matrices values */ public void testMatricesValues1() { FieldLUDecomposition lu = new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(testData)); FieldMatrix lRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(0), new Fraction(0) }, { new Fraction(2), new Fraction(1), new Fraction(0) }, { new Fraction(1), new Fraction(-2), new Fraction(1) } }); FieldMatrix uRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(0), new Fraction(1), new Fraction(-3) }, { new Fraction(0), new Fraction(0), new Fraction(-1) } }); FieldMatrix pRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(0), new Fraction(0) }, { new Fraction(0), new Fraction(1), new Fraction(0) }, { new Fraction(0), new Fraction(0), new Fraction(1) } }); int[] pivotRef = { 0, 1, 2 }; // check values against known references FieldMatrix l = lu.getL(); TestUtils.assertEquals(lRef, l); FieldMatrix u = lu.getU(); TestUtils.assertEquals(uRef, u); FieldMatrix p = lu.getP(); TestUtils.assertEquals(pRef, p); int[] pivot = lu.getPivot(); for (int i = 0; i < pivotRef.length; ++i) { assertEquals(pivotRef[i], pivot[i]); } // check the same cached instance is returned the second time assertTrue(l == lu.getL()); assertTrue(u == lu.getU()); assertTrue(p == lu.getP()); } /** test matrices values */ public void testMatricesValues2() { FieldLUDecomposition lu = new FieldLUDecompositionImpl(new Array2DRowFieldMatrix(luData)); FieldMatrix lRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(0), new Fraction(0) }, { new Fraction(3), new Fraction(1), new Fraction(0) }, { new Fraction(1), new Fraction(0), new Fraction(1) } }); FieldMatrix uRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(2), new Fraction(3), new Fraction(3) }, { new Fraction(0), new Fraction(-3), new Fraction(-1) }, { new Fraction(0), new Fraction(0), new Fraction(4) } }); FieldMatrix pRef = new Array2DRowFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(0), new Fraction(0) }, { new Fraction(0), new Fraction(0), new Fraction(1) }, { new Fraction(0), new Fraction(1), new Fraction(0) } }); int[] pivotRef = { 0, 2, 1 }; // check values against known references FieldMatrix l = lu.getL(); TestUtils.assertEquals(lRef, l); FieldMatrix u = lu.getU(); TestUtils.assertEquals(uRef, u); FieldMatrix p = lu.getP(); TestUtils.assertEquals(pRef, p); int[] pivot = lu.getPivot(); for (int i = 0; i < pivotRef.length; ++i) { assertEquals(pivotRef[i], pivot[i]); } // check the same cached instance is returned the second time assertTrue(l == lu.getL()); assertTrue(u == lu.getU()); assertTrue(p == lu.getP()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/InvalidMatrixExceptionTest.java100644 1750 1750 2316 11532241243 32006 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class InvalidMatrixExceptionTest extends TestCase { public void testConstructorMessage(){ String msg = "message"; InvalidMatrixException ex = new InvalidMatrixException(msg); assertEquals(msg, ex.getMessage()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SparseFieldMatrixTest.java100644 1750 1750 76562 11532241243 31000 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; import org.apache.commons.math.Field; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionConversionException; import org.apache.commons.math.fraction.FractionField; /** * Test cases for the {@link SparseFieldMatrix} class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class SparseFieldMatrixTest extends TestCase { // 3 x 3 identity matrix protected Fraction[][] id = { {new Fraction(1), new Fraction(0), new Fraction(0) }, { new Fraction(0), new Fraction(1), new Fraction(0) }, { new Fraction(0), new Fraction(0), new Fraction(1) } }; // Test data for group operations protected Fraction[][] testData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) }, { new Fraction(1), new Fraction(0), new Fraction(8) } }; protected Fraction[][] testDataLU = null; protected Fraction[][] testDataPlus2 = { { new Fraction(3), new Fraction(4), new Fraction(5) }, { new Fraction(4), new Fraction(7), new Fraction(5) }, { new Fraction(3), new Fraction(2), new Fraction(10) } }; protected Fraction[][] testDataMinus = { { new Fraction(-1), new Fraction(-2), new Fraction(-3) }, { new Fraction(-2), new Fraction(-5), new Fraction(-3) }, { new Fraction(-1), new Fraction(0), new Fraction(-8) } }; protected Fraction[] testDataRow1 = { new Fraction(1), new Fraction(2), new Fraction(3) }; protected Fraction[] testDataCol3 = { new Fraction(3), new Fraction(3), new Fraction(8) }; protected Fraction[][] testDataInv = { { new Fraction(-40), new Fraction(16), new Fraction(9) }, { new Fraction(13), new Fraction(-5), new Fraction(-3) }, { new Fraction(5), new Fraction(-2), new Fraction(-1) } }; protected Fraction[] preMultTest = { new Fraction(8), new Fraction(12), new Fraction(33) }; protected Fraction[][] testData2 = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) } }; protected Fraction[][] testData2T = { { new Fraction(1), new Fraction(2) }, { new Fraction(2), new Fraction(5) }, { new Fraction(3), new Fraction(3) } }; protected Fraction[][] testDataPlusInv = { { new Fraction(-39), new Fraction(18), new Fraction(12) }, { new Fraction(15), new Fraction(0), new Fraction(0) }, { new Fraction(6), new Fraction(-2), new Fraction(7) } }; // lu decomposition tests protected Fraction[][] luData = { { new Fraction(2), new Fraction(3), new Fraction(3) }, { new Fraction(0), new Fraction(5), new Fraction(7) }, { new Fraction(6), new Fraction(9), new Fraction(8) } }; protected Fraction[][] luDataLUDecomposition = null; // singular matrices protected Fraction[][] singular = { { new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(3) } }; protected Fraction[][] bigSingular = { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(2), new Fraction(5), new Fraction(3), new Fraction(4) }, { new Fraction(7), new Fraction(3), new Fraction(256), new Fraction(1930) }, { new Fraction(3), new Fraction(7), new Fraction(6), new Fraction(8) } }; // 4th // row // = // 1st // + // 2nd protected Fraction[][] detData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(4), new Fraction(5), new Fraction(6) }, { new Fraction(7), new Fraction(8), new Fraction(10) } }; protected Fraction[][] detData2 = { { new Fraction(1), new Fraction(3) }, { new Fraction(2), new Fraction(4) } }; // vectors protected Fraction[] testVector = { new Fraction(1), new Fraction(2), new Fraction(3) }; protected Fraction[] testVector2 = { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }; // submatrix accessor tests protected Fraction[][] subTestData = null; // array selections protected Fraction[][] subRows02Cols13 = { {new Fraction(2), new Fraction(4) }, { new Fraction(4), new Fraction(8) } }; protected Fraction[][] subRows03Cols12 = { { new Fraction(2), new Fraction(3) }, { new Fraction(5), new Fraction(6) } }; protected Fraction[][] subRows03Cols123 = { { new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6), new Fraction(7) } }; // effective permutations protected Fraction[][] subRows20Cols123 = { { new Fraction(4), new Fraction(6), new Fraction(8) }, { new Fraction(2), new Fraction(3), new Fraction(4) } }; protected Fraction[][] subRows31Cols31 = null; // contiguous ranges protected Fraction[][] subRows01Cols23 = null; protected Fraction[][] subRows23Cols00 = { { new Fraction(2) }, { new Fraction(4) } }; protected Fraction[][] subRows00Cols33 = { { new Fraction(4) } }; // row matrices protected Fraction[][] subRow0 = { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) } }; protected Fraction[][] subRow3 = { { new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7) } }; // column matrices protected Fraction[][] subColumn1 = null; protected Fraction[][] subColumn3 = null; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; protected Field field = FractionField.getInstance(); public SparseFieldMatrixTest(String name) { super(name); setupFractionArrays(); } private void setupFractionArrays() { try { testDataLU = new Fraction[][]{ { new Fraction(2), new Fraction(5), new Fraction(3) }, { new Fraction(.5d), new Fraction(-2.5d), new Fraction(6.5d) }, { new Fraction(0.5d), new Fraction(0.2d), new Fraction(.2d) } }; luDataLUDecomposition = new Fraction[][]{ { new Fraction(6), new Fraction(9), new Fraction(8) }, { new Fraction(0), new Fraction(5), new Fraction(7) }, { new Fraction(0.33333333333333), new Fraction(0), new Fraction(0.33333333333333) } }; subTestData = new Fraction [][]{ { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(1.5), new Fraction(2.5), new Fraction(3.5), new Fraction(4.5) }, { new Fraction(2), new Fraction(4), new Fraction(6), new Fraction(8) }, { new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7) } }; subRows31Cols31 = new Fraction[][]{ { new Fraction(7), new Fraction(5) }, { new Fraction(4.5), new Fraction(2.5) } }; subRows01Cols23 = new Fraction[][]{ { new Fraction(3), new Fraction(4) }, { new Fraction(3.5), new Fraction(4.5) } }; subColumn1 = new Fraction [][]{ { new Fraction(2) }, { new Fraction(2.5) }, { new Fraction(4) }, { new Fraction(5) } }; subColumn3 = new Fraction[][]{ { new Fraction(4) }, { new Fraction(4.5) }, { new Fraction(8) }, { new Fraction(7) } }; } catch (FractionConversionException e) { // ignore, can't happen } } /** test dimensions */ public void testDimensions() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix m2 = createSparseMatrix(testData2); assertEquals("testData row dimension", 3, m.getRowDimension()); assertEquals("testData column dimension", 3, m.getColumnDimension()); assertTrue("testData is square", m.isSquare()); assertEquals("testData2 row dimension", m2.getRowDimension(), 2); assertEquals("testData2 column dimension", m2.getColumnDimension(), 3); assertTrue("testData2 is not square", !m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { SparseFieldMatrix m1 = createSparseMatrix(testData); FieldMatrix m2 = m1.copy(); assertEquals(m1.getClass(), m2.getClass()); assertEquals((m2), m1); SparseFieldMatrix m3 = createSparseMatrix(testData); FieldMatrix m4 = m3.copy(); assertEquals(m3.getClass(), m4.getClass()); assertEquals((m4), m3); } /** test add */ public void testAdd() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix mInv = createSparseMatrix(testDataInv); SparseFieldMatrix mDataPlusInv = createSparseMatrix(testDataPlusInv); FieldMatrix mPlusMInv = m.add(mInv); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals("sum entry entry", mDataPlusInv.getEntry(row, col).doubleValue(), mPlusMInv.getEntry(row, col).doubleValue(), entryTolerance); } } } /** test add failure */ public void testAddFail() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix m2 = createSparseMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test m-n = m + -n */ public void testPlusMinus() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix n = createSparseMatrix(testDataInv); assertClose("m-n = m + -n", m.subtract(n), n.scalarMultiply(new Fraction(-1)).add(m), entryTolerance); try { m.subtract(createSparseMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix mInv = createSparseMatrix(testDataInv); SparseFieldMatrix identity = createSparseMatrix(id); SparseFieldMatrix m2 = createSparseMatrix(testData2); assertClose("inverse multiply", m.multiply(mInv), identity, entryTolerance); assertClose("inverse multiply", m.multiply(new Array2DRowFieldMatrix(testDataInv)), identity, entryTolerance); assertClose("inverse multiply", mInv.multiply(m), identity, entryTolerance); assertClose("identity multiply", m.multiply(identity), m, entryTolerance); assertClose("identity multiply", identity.multiply(mInv), mInv, entryTolerance); assertClose("identity multiply", m2.multiply(identity), m2, entryTolerance); try { m.multiply(createSparseMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } // Additional Test for Array2DRowRealMatrixTest.testMultiply private Fraction[][] d3 = new Fraction[][] { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8) } }; private Fraction[][] d4 = new Fraction[][] { { new Fraction(1) }, { new Fraction(2) }, { new Fraction(3) }, { new Fraction(4) } }; private Fraction[][] d5 = new Fraction[][] { { new Fraction(30) }, { new Fraction(70) } }; public void testMultiply2() { FieldMatrix m3 = createSparseMatrix(d3); FieldMatrix m4 = createSparseMatrix(d4); FieldMatrix m5 = createSparseMatrix(d5); assertClose("m3*m4=m5", m3.multiply(m4), m5, entryTolerance); } /** test trace */ public void testTrace() { FieldMatrix m = createSparseMatrix(id); assertEquals("identity trace", 3d, m.getTrace().doubleValue(), entryTolerance); m = createSparseMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test sclarAdd */ public void testScalarAdd() { FieldMatrix m = createSparseMatrix(testData); assertClose("scalar add", createSparseMatrix(testDataPlus2), m.scalarAdd(new Fraction(2)), entryTolerance); } /** test operate */ public void testOperate() { FieldMatrix m = createSparseMatrix(id); assertClose("identity operate", testVector, m.operate(testVector), entryTolerance); assertClose("identity operate", testVector, m.operate( new ArrayFieldVector(testVector)).getData(), entryTolerance); m = createSparseMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test issue MATH-209 */ public void testMath209() { FieldMatrix a = createSparseMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2) }, { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }); Fraction[] b = a.operate(new Fraction[] { new Fraction(1), new Fraction(1) }); assertEquals(a.getRowDimension(), b.length); assertEquals(3.0, b[0].doubleValue(), 1.0e-12); assertEquals(7.0, b[1].doubleValue(), 1.0e-12); assertEquals(11.0, b[2].doubleValue(), 1.0e-12); } /** test transpose */ public void testTranspose() { FieldMatrix m = createSparseMatrix(testData); FieldMatrix mIT = new FieldLUDecompositionImpl(m).getSolver().getInverse().transpose(); FieldMatrix mTI = new FieldLUDecompositionImpl(m.transpose()).getSolver().getInverse(); assertClose("inverse-transpose", mIT, mTI, normTolerance); m = createSparseMatrix(testData2); FieldMatrix mt = createSparseMatrix(testData2T); assertClose("transpose",mt,m.transpose(),normTolerance); } /** test preMultiply by vector */ public void testPremultiplyVector() { FieldMatrix m = createSparseMatrix(testData); assertClose("premultiply", m.preMultiply(testVector), preMultTest, normTolerance); assertClose("premultiply", m.preMultiply( new ArrayFieldVector(testVector).getData()), preMultTest, normTolerance); m = createSparseMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { FieldMatrix m3 = createSparseMatrix(d3); FieldMatrix m4 = createSparseMatrix(d4); FieldMatrix m5 = createSparseMatrix(d5); assertClose("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance); SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix mInv = createSparseMatrix(testDataInv); SparseFieldMatrix identity = createSparseMatrix(id); assertClose("inverse multiply", m.preMultiply(mInv), identity, entryTolerance); assertClose("inverse multiply", mInv.preMultiply(m), identity, entryTolerance); assertClose("identity multiply", m.preMultiply(identity), m, entryTolerance); assertClose("identity multiply", identity.preMultiply(mInv), mInv, entryTolerance); try { m.preMultiply(createSparseMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { FieldMatrix m = createSparseMatrix(testData); assertClose("get row", m.getRow(0), testDataRow1, entryTolerance); assertClose("get col", m.getColumn(2), testDataCol3, entryTolerance); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { FieldMatrix m = createSparseMatrix(testData); assertEquals("get entry", m.getEntry(0, 1).doubleValue(), 2d, entryTolerance); try { m.getEntry(10, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns Fraction[][] matrixData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) } }; FieldMatrix m = createSparseMatrix(matrixData); // One more with three rows, two columns Fraction[][] matrixData2 = { { new Fraction(1), new Fraction(2) }, { new Fraction(2), new Fraction(5) }, { new Fraction(1), new Fraction(7) } }; FieldMatrix n = createSparseMatrix(matrixData2); // Now multiply m by n FieldMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p FieldMatrix pInverse = new FieldLUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example Fraction[][] coefficientsData = { { new Fraction(2), new Fraction(3), new Fraction(-2) }, { new Fraction(-1), new Fraction(7), new Fraction(6) }, { new Fraction(4), new Fraction(-3), new Fraction(-5) } }; FieldMatrix coefficients = createSparseMatrix(coefficientsData); Fraction[] constants = { new Fraction(1), new Fraction(-2), new Fraction(1) }; Fraction[] solution = new FieldLUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals((new Fraction(2).multiply((solution[0])).add(new Fraction(3).multiply(solution[1])).subtract(new Fraction(2).multiply(solution[2]))).doubleValue(), constants[0].doubleValue(), 1E-12); assertEquals(((new Fraction(-1).multiply(solution[0])).add(new Fraction(7).multiply(solution[1])).add(new Fraction(6).multiply(solution[2]))).doubleValue(), constants[1].doubleValue(), 1E-12); assertEquals(((new Fraction(4).multiply(solution[0])).subtract(new Fraction(3).multiply( solution[1])).subtract(new Fraction(5).multiply(solution[2]))).doubleValue(), constants[2].doubleValue(), 1E-12); } // test submatrix accessors public void testSubMatrix() { FieldMatrix m = createSparseMatrix(subTestData); FieldMatrix mRows23Cols00 = createSparseMatrix(subRows23Cols00); FieldMatrix mRows00Cols33 = createSparseMatrix(subRows00Cols33); FieldMatrix mRows01Cols23 = createSparseMatrix(subRows01Cols23); FieldMatrix mRows02Cols13 = createSparseMatrix(subRows02Cols13); FieldMatrix mRows03Cols12 = createSparseMatrix(subRows03Cols12); FieldMatrix mRows03Cols123 = createSparseMatrix(subRows03Cols123); FieldMatrix mRows20Cols123 = createSparseMatrix(subRows20Cols123); FieldMatrix mRows31Cols31 = createSparseMatrix(subRows31Cols31); assertEquals("Rows23Cols00", mRows23Cols00, m.getSubMatrix(2, 3, 0, 0)); assertEquals("Rows00Cols33", mRows00Cols33, m.getSubMatrix(0, 0, 3, 3)); assertEquals("Rows01Cols23", mRows01Cols23, m.getSubMatrix(0, 1, 2, 3)); assertEquals("Rows02Cols13", mRows02Cols13, m.getSubMatrix(new int[] { 0, 2 }, new int[] { 1, 3 })); assertEquals("Rows03Cols12", mRows03Cols12, m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2 })); assertEquals("Rows03Cols123", mRows03Cols123, m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2, 3 })); assertEquals("Rows20Cols123", mRows20Cols123, m.getSubMatrix(new int[] { 2, 0 }, new int[] { 1, 2, 3 })); assertEquals("Rows31Cols31", mRows31Cols31, m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); assertEquals("Rows31Cols31", mRows31Cols31, m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); try { m.getSubMatrix(1, 0, 2, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(-1, 1, 2, 2); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(1, 0, 2, 2); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(1, 0, 2, 4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(new int[] {}, new int[] { 0 }); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getSubMatrix(new int[] { 0 }, new int[] { 4 }); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetRowMatrix() { FieldMatrix m = createSparseMatrix(subTestData); FieldMatrix mRow0 = createSparseMatrix(subRow0); FieldMatrix mRow3 = createSparseMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetColumnMatrix() { FieldMatrix m = createSparseMatrix(subTestData); FieldMatrix mColumn1 = createSparseMatrix(subColumn1); FieldMatrix mColumn3 = createSparseMatrix(subColumn3); assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetRowVector() { FieldMatrix m = createSparseMatrix(subTestData); FieldVector mRow0 = new ArrayFieldVector(subRow0[0]); FieldVector mRow3 = new ArrayFieldVector(subRow3[0]); assertEquals("Row0", mRow0, m.getRowVector(0)); assertEquals("Row3", mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testGetColumnVector() { FieldMatrix m = createSparseMatrix(subTestData); FieldVector mColumn1 = columnToVector(subColumn1); FieldVector mColumn3 = columnToVector(subColumn3); assertEquals("Column1", mColumn1, m.getColumnVector(1)); assertEquals("Column3", mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } private FieldVector columnToVector(Fraction[][] column) { Fraction[] data = new Fraction[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayFieldVector(data, false); } public void testEqualsAndHashCode() { SparseFieldMatrix m = createSparseMatrix(testData); SparseFieldMatrix m1 = (SparseFieldMatrix) m.copy(); SparseFieldMatrix mt = (SparseFieldMatrix) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(createSparseMatrix(bigSingular))); } /* Disable for now public void testToString() { SparseFieldMatrix m = createSparseMatrix(testData); assertEquals("SparseFieldMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", m.toString()); m = new SparseFieldMatrix(field, 1, 1); assertEquals("SparseFieldMatrix{{0.0}}", m.toString()); } */ public void testSetSubMatrix() throws Exception { SparseFieldMatrix m = createSparseMatrix(testData); m.setSubMatrix(detData2, 1, 1); FieldMatrix expected = createSparseMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(1), new Fraction(3) }, { new Fraction(1), new Fraction(2), new Fraction(4) } }); assertEquals(expected, m); m.setSubMatrix(detData2, 0, 0); expected = createSparseMatrix(new Fraction[][] { { new Fraction(1), new Fraction(3), new Fraction(3) }, { new Fraction(2), new Fraction(4), new Fraction(3) }, { new Fraction(1), new Fraction(2), new Fraction(4) } }); assertEquals(expected, m); m.setSubMatrix(testDataPlus2, 0, 0); expected = createSparseMatrix(new Fraction[][] { { new Fraction(3), new Fraction(4), new Fraction(5) }, { new Fraction(4), new Fraction(7), new Fraction(5) }, { new Fraction(3), new Fraction(2), new Fraction(10) } }); assertEquals(expected, m); // javadoc example SparseFieldMatrix matrix = createSparseMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8) }, { new Fraction(9), new Fraction(0), new Fraction(1), new Fraction(2) } }); matrix.setSubMatrix(new Fraction[][] { { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }, 1, 1); expected = createSparseMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(3), new Fraction(4), new Fraction(8) }, { new Fraction(9), new Fraction(5), new Fraction(6), new Fraction(2) } }); assertEquals(expected, matrix); // dimension overflow try { m.setSubMatrix(testData, 1, 1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData, -1, 1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData, 1, -1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null, 1, 1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } try { new SparseFieldMatrix(field, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // ragged try { m.setSubMatrix(new Fraction[][] { { new Fraction(1) }, { new Fraction(2), new Fraction(3) } }, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new Fraction[][] { {} }, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } // --------------- -----------------Protected methods /** verifies that two matrices are close (1-norm) */ protected void assertClose(String msg, FieldMatrix m, FieldMatrix n, double tolerance) { for(int i=0; i < m.getRowDimension(); i++){ for(int j=0; j < m.getColumnDimension(); j++){ assertEquals(msg, m.getEntry(i,j).doubleValue(), n.getEntry(i,j).doubleValue(), tolerance); } } } /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, Fraction[] m, Fraction[] n, double tolerance) { if (m.length != n.length) { fail("vectors not same length"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i].doubleValue(), n[i].doubleValue(), tolerance); } } private SparseFieldMatrix createSparseMatrix(Fraction[][] data) { SparseFieldMatrix matrix = new SparseFieldMatrix(field, data.length, data[0].length); for (int row = 0; row < data.length; row++) { for (int col = 0; col < data[row].length; col++) { matrix.setEntry(row, col, data[row][col]); } } return matrix; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/QRDecompositionImplTest.java100644 1750 1750 22752 11532241243 31303 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Random; import org.apache.commons.math.linear.MatrixVisitorException; import junit.framework.TestCase; public class QRDecompositionImplTest extends TestCase { double[][] testData3x3NonSingular = { { 12, -51, 4 }, { 6, 167, -68 }, { -4, 24, -41 }, }; double[][] testData3x3Singular = { { 1, 4, 7, }, { 2, 5, 8, }, { 3, 6, 9, }, }; double[][] testData3x4 = { { 12, -51, 4, 1 }, { 6, 167, -68, 2 }, { -4, 24, -41, 3 }, }; double[][] testData4x3 = { { 12, -51, 4, }, { 6, 167, -68, }, { -4, 24, -41, }, { -5, 34, 7, }, }; private static final double entryTolerance = 10e-16; private static final double normTolerance = 10e-14; public QRDecompositionImplTest(String name) { super(name); } /** test dimensions * @throws MatrixVisitorException */ public void testDimensions() throws MatrixVisitorException { checkDimension(MatrixUtils.createRealMatrix(testData3x3NonSingular)); checkDimension(MatrixUtils.createRealMatrix(testData4x3)); checkDimension(MatrixUtils.createRealMatrix(testData3x4)); Random r = new Random(643895747384642l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; checkDimension(createTestMatrix(r, p, q)); checkDimension(createTestMatrix(r, q, p)); } private void checkDimension(RealMatrix m) { int rows = m.getRowDimension(); int columns = m.getColumnDimension(); QRDecomposition qr = new QRDecompositionImpl(m); assertEquals(rows, qr.getQ().getRowDimension()); assertEquals(rows, qr.getQ().getColumnDimension()); assertEquals(rows, qr.getR().getRowDimension()); assertEquals(columns, qr.getR().getColumnDimension()); } /** test A = QR * @throws MatrixVisitorException */ public void testAEqualQR() throws MatrixVisitorException { checkAEqualQR(MatrixUtils.createRealMatrix(testData3x3NonSingular)); checkAEqualQR(MatrixUtils.createRealMatrix(testData3x3Singular)); checkAEqualQR(MatrixUtils.createRealMatrix(testData3x4)); checkAEqualQR(MatrixUtils.createRealMatrix(testData4x3)); Random r = new Random(643895747384642l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; checkAEqualQR(createTestMatrix(r, p, q)); checkAEqualQR(createTestMatrix(r, q, p)); } private void checkAEqualQR(RealMatrix m) { QRDecomposition qr = new QRDecompositionImpl(m); double norm = qr.getQ().multiply(qr.getR()).subtract(m).getNorm(); assertEquals(0, norm, normTolerance); } /** test the orthogonality of Q * @throws MatrixVisitorException */ public void testQOrthogonal() throws MatrixVisitorException { checkQOrthogonal(MatrixUtils.createRealMatrix(testData3x3NonSingular)); checkQOrthogonal(MatrixUtils.createRealMatrix(testData3x3Singular)); checkQOrthogonal(MatrixUtils.createRealMatrix(testData3x4)); checkQOrthogonal(MatrixUtils.createRealMatrix(testData4x3)); Random r = new Random(643895747384642l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; checkQOrthogonal(createTestMatrix(r, p, q)); checkQOrthogonal(createTestMatrix(r, q, p)); } private void checkQOrthogonal(RealMatrix m) { QRDecomposition qr = new QRDecompositionImpl(m); RealMatrix eye = MatrixUtils.createRealIdentityMatrix(m.getRowDimension()); double norm = qr.getQT().multiply(qr.getQ()).subtract(eye).getNorm(); assertEquals(0, norm, normTolerance); } /** test that R is upper triangular */ public void testRUpperTriangular() throws MatrixVisitorException { RealMatrix matrix = MatrixUtils.createRealMatrix(testData3x3NonSingular); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); matrix = MatrixUtils.createRealMatrix(testData3x3Singular); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); matrix = MatrixUtils.createRealMatrix(testData3x4); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); matrix = MatrixUtils.createRealMatrix(testData4x3); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); Random r = new Random(643895747384642l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; matrix = createTestMatrix(r, p, q); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); matrix = createTestMatrix(r, p, q); checkUpperTriangular(new QRDecompositionImpl(matrix).getR()); } private void checkUpperTriangular(RealMatrix m) throws MatrixVisitorException { m.walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { @Override public void visit(int row, int column, double value) { if (column < row) { assertEquals(0.0, value, entryTolerance); } } }); } /** test that H is trapezoidal * @throws MatrixVisitorException */ public void testHTrapezoidal() throws MatrixVisitorException { RealMatrix matrix = MatrixUtils.createRealMatrix(testData3x3NonSingular); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); matrix = MatrixUtils.createRealMatrix(testData3x3Singular); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); matrix = MatrixUtils.createRealMatrix(testData3x4); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); matrix = MatrixUtils.createRealMatrix(testData4x3); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); Random r = new Random(643895747384642l); int p = (5 * BlockRealMatrix.BLOCK_SIZE) / 4; int q = (7 * BlockRealMatrix.BLOCK_SIZE) / 4; matrix = createTestMatrix(r, p, q); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); matrix = createTestMatrix(r, p, q); checkTrapezoidal(new QRDecompositionImpl(matrix).getH()); } private void checkTrapezoidal(RealMatrix m) throws MatrixVisitorException { m.walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { @Override public void visit(int row, int column, double value) { if (column > row) { assertEquals(0.0, value, entryTolerance); } } }); } /** test matrices values */ public void testMatricesValues() { QRDecomposition qr = new QRDecompositionImpl(MatrixUtils.createRealMatrix(testData3x3NonSingular)); RealMatrix qRef = MatrixUtils.createRealMatrix(new double[][] { { -12.0 / 14.0, 69.0 / 175.0, -58.0 / 175.0 }, { -6.0 / 14.0, -158.0 / 175.0, 6.0 / 175.0 }, { 4.0 / 14.0, -30.0 / 175.0, -165.0 / 175.0 } }); RealMatrix rRef = MatrixUtils.createRealMatrix(new double[][] { { -14.0, -21.0, 14.0 }, { 0.0, -175.0, 70.0 }, { 0.0, 0.0, 35.0 } }); RealMatrix hRef = MatrixUtils.createRealMatrix(new double[][] { { 26.0 / 14.0, 0.0, 0.0 }, { 6.0 / 14.0, 648.0 / 325.0, 0.0 }, { -4.0 / 14.0, 36.0 / 325.0, 2.0 } }); // check values against known references RealMatrix q = qr.getQ(); assertEquals(0, q.subtract(qRef).getNorm(), 1.0e-13); RealMatrix qT = qr.getQT(); assertEquals(0, qT.subtract(qRef.transpose()).getNorm(), 1.0e-13); RealMatrix r = qr.getR(); assertEquals(0, r.subtract(rRef).getNorm(), 1.0e-13); RealMatrix h = qr.getH(); assertEquals(0, h.subtract(hRef).getNorm(), 1.0e-13); // check the same cached instance is returned the second time assertTrue(q == qr.getQ()); assertTrue(r == qr.getR()); assertTrue(h == qr.getH()); } private RealMatrix createTestMatrix(final Random r, final int rows, final int columns) throws MatrixVisitorException { RealMatrix m = MatrixUtils.createRealMatrix(rows, columns); m.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor(){ @Override public double visit(int row, int column, double value) { return 2.0 * r.nextDouble() - 1.0; } }); return m; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java100644 1750 1750 60437 11532241243 30611 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.lang.reflect.Array; import junit.framework.TestCase; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.TestUtils; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionField; /** * Test cases for the {@link ArrayFieldVector} class. * * @version $Revision: 1003993 $ $Date: 2010-10-03 18:39:16 +0200 (dim. 03 oct. 2010) $ */ public class ArrayFieldVectorTest extends TestCase { // protected Fraction[][] ma1 = { {new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)} }; protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)}; protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)}; protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)}; protected Fraction[] vec4 = { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)}; protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)}; protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)}; protected Fraction[][] mat1 = { {new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)} }; // Testclass to test the FieldVector interface // only with enough content to support the test public static class FieldVectorTestImpl> implements FieldVector, Serializable { private static final long serialVersionUID = 3970959016014158539L; private final Field field; /** Entries of the vector. */ protected T[] data; /** Build an array of elements. * @param length size of the array to build * @return a new array */ @SuppressWarnings("unchecked") // field is of type T private T[] buildArray(final int length) { return (T[]) Array.newInstance(field.getZero().getClass(), length); } public FieldVectorTestImpl(T[] d) { field = d[0].getField(); data = d.clone(); } public Field getField() { return field; } private UnsupportedOperationException unsupported() { return new UnsupportedOperationException("Not supported, unneeded for test purposes"); } public FieldVector copy() { throw unsupported(); } public FieldVector add(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldVector add(T[] v) throws IllegalArgumentException { throw unsupported(); } public FieldVector subtract(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldVector subtract(T[] v) throws IllegalArgumentException { throw unsupported(); } public FieldVector mapAdd(T d) { throw unsupported(); } public FieldVector mapAddToSelf(T d) { throw unsupported(); } public FieldVector mapSubtract(T d) { throw unsupported(); } public FieldVector mapSubtractToSelf(T d) { throw unsupported(); } public FieldVector mapMultiply(T d) { T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].multiply(d); } return new FieldVectorTestImpl(out); } public FieldVector mapMultiplyToSelf(T d) { throw unsupported(); } public FieldVector mapDivide(T d) { throw unsupported(); } public FieldVector mapDivideToSelf(T d) { throw unsupported(); } public FieldVector mapInv() { throw unsupported(); } public FieldVector mapInvToSelf() { throw unsupported(); } public FieldVector ebeMultiply(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldVector ebeMultiply(T[] v) throws IllegalArgumentException { throw unsupported(); } public FieldVector ebeDivide(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldVector ebeDivide(T[] v) throws IllegalArgumentException { throw unsupported(); } public T[] getData() { return data.clone(); } public T dotProduct(FieldVector v) throws IllegalArgumentException { T dot = field.getZero(); for (int i = 0; i < data.length; i++) { dot = dot.add(data[i].multiply(v.getEntry(i))); } return dot; } public T dotProduct(T[] v) throws IllegalArgumentException { T dot = field.getZero(); for (int i = 0; i < data.length; i++) { dot = dot.add(data[i].multiply(v[i])); } return dot; } public FieldVector projection(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldVector projection(T[] v) throws IllegalArgumentException { throw unsupported(); } public FieldMatrix outerProduct(FieldVector v) throws IllegalArgumentException { throw unsupported(); } public FieldMatrix outerProduct(T[] v) throws IllegalArgumentException { throw unsupported(); } public T getEntry(int index) throws MatrixIndexException { return data[index]; } public int getDimension() { return data.length; } public FieldVector append(FieldVector v) { throw unsupported(); } public FieldVector append(T d) { throw unsupported(); } public FieldVector append(T[] a) { throw unsupported(); } public FieldVector getSubVector(int index, int n) throws MatrixIndexException { throw unsupported(); } public void setEntry(int index, T value) throws MatrixIndexException { throw unsupported(); } public void setSubVector(int index, FieldVector v) throws MatrixIndexException { throw unsupported(); } public void setSubVector(int index, T[] v) throws MatrixIndexException { throw unsupported(); } public void set(T value) { throw unsupported(); } public T[] toArray() { throw unsupported(); } } public void testConstructors() { ArrayFieldVector v0 = new ArrayFieldVector(FractionField.getInstance()); assertEquals(0, v0.getDimension()); ArrayFieldVector v1 = new ArrayFieldVector(FractionField.getInstance(), 7); assertEquals(7, v1.getDimension()); assertEquals(new Fraction(0), v1.getEntry(6)); ArrayFieldVector v2 = new ArrayFieldVector(5, new Fraction(123, 100)); assertEquals(5, v2.getDimension()); assertEquals(new Fraction(123, 100), v2.getEntry(4)); ArrayFieldVector v3 = new ArrayFieldVector(vec1); assertEquals(3, v3.getDimension()); assertEquals(new Fraction(2), v3.getEntry(1)); ArrayFieldVector v4 = new ArrayFieldVector(vec4, 3, 2); assertEquals(2, v4.getDimension()); assertEquals(new Fraction(4), v4.getEntry(0)); try { new ArrayFieldVector(vec4, 8, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } FieldVector v5_i = new ArrayFieldVector(dvec1); assertEquals(9, v5_i.getDimension()); assertEquals(new Fraction(9), v5_i.getEntry(8)); ArrayFieldVector v5 = new ArrayFieldVector(dvec1); assertEquals(9, v5.getDimension()); assertEquals(new Fraction(9), v5.getEntry(8)); ArrayFieldVector v6 = new ArrayFieldVector(dvec1, 3, 2); assertEquals(2, v6.getDimension()); assertEquals(new Fraction(4), v6.getEntry(0)); try { new ArrayFieldVector(dvec1, 8, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } ArrayFieldVector v7 = new ArrayFieldVector(v1); assertEquals(7, v7.getDimension()); assertEquals(new Fraction(0), v7.getEntry(6)); FieldVectorTestImpl v7_i = new FieldVectorTestImpl(vec1); ArrayFieldVector v7_2 = new ArrayFieldVector(v7_i); assertEquals(3, v7_2.getDimension()); assertEquals(new Fraction(2), v7_2.getEntry(1)); ArrayFieldVector v8 = new ArrayFieldVector(v1, true); assertEquals(7, v8.getDimension()); assertEquals(new Fraction(0), v8.getEntry(6)); assertNotSame("testData not same object ", v1.data, v8.data); ArrayFieldVector v8_2 = new ArrayFieldVector(v1, false); assertEquals(7, v8_2.getDimension()); assertEquals(new Fraction(0), v8_2.getEntry(6)); assertEquals(v1.data, v8_2.data); ArrayFieldVector v9 = new ArrayFieldVector(v1, v3); assertEquals(10, v9.getDimension()); assertEquals(new Fraction(1), v9.getEntry(7)); } public void testDataInOut() { ArrayFieldVector v1 = new ArrayFieldVector(vec1); ArrayFieldVector v2 = new ArrayFieldVector(vec2); ArrayFieldVector v4 = new ArrayFieldVector(vec4); FieldVectorTestImpl v2_t = new FieldVectorTestImpl(vec2); FieldVector v_append_1 = v1.append(v2); assertEquals(6, v_append_1.getDimension()); assertEquals(new Fraction(4), v_append_1.getEntry(3)); FieldVector v_append_2 = v1.append(new Fraction(2)); assertEquals(4, v_append_2.getDimension()); assertEquals(new Fraction(2), v_append_2.getEntry(3)); FieldVector v_append_3 = v1.append(vec2); assertEquals(6, v_append_3.getDimension()); assertEquals(new Fraction(4), v_append_3.getEntry(3)); FieldVector v_append_4 = v1.append(v2_t); assertEquals(6, v_append_4.getDimension()); assertEquals(new Fraction(4), v_append_4.getEntry(3)); FieldVector v_copy = v1.copy(); assertEquals(3, v_copy.getDimension()); assertNotSame("testData not same object ", v1.data, v_copy.getData()); Fraction[] a_frac = v1.toArray(); assertEquals(3, a_frac.length); assertNotSame("testData not same object ", v1.data, a_frac); // ArrayFieldVector vout4 = (ArrayFieldVector) v1.clone(); // assertEquals(3, vout4.getDimension()); // assertEquals(v1.data, vout4.data); FieldVector vout5 = v4.getSubVector(3, 3); assertEquals(3, vout5.getDimension()); assertEquals(new Fraction(5), vout5.getEntry(1)); try { v4.getSubVector(3, 7); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayFieldVector v_set1 = (ArrayFieldVector) v1.copy(); v_set1.setEntry(1, new Fraction(11)); assertEquals(new Fraction(11), v_set1.getEntry(1)); try { v_set1.setEntry(3, new Fraction(11)); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayFieldVector v_set2 = (ArrayFieldVector) v4.copy(); v_set2.set(3, v1); assertEquals(new Fraction(1), v_set2.getEntry(3)); assertEquals(new Fraction(7), v_set2.getEntry(6)); try { v_set2.set(7, v1); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayFieldVector v_set3 = (ArrayFieldVector) v1.copy(); v_set3.set(new Fraction(13)); assertEquals(new Fraction(13), v_set3.getEntry(2)); try { v_set3.getEntry(23); fail("ArrayIndexOutOfBoundsException expected"); } catch (ArrayIndexOutOfBoundsException ex) { // expected behavior } ArrayFieldVector v_set4 = (ArrayFieldVector) v4.copy(); v_set4.setSubVector(3, v2_t); assertEquals(new Fraction(4), v_set4.getEntry(3)); assertEquals(new Fraction(7), v_set4.getEntry(6)); try { v_set4.setSubVector(7, v2_t); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayFieldVector vout10 = (ArrayFieldVector) v1.copy(); ArrayFieldVector vout10_2 = (ArrayFieldVector) v1.copy(); assertEquals(vout10, vout10_2); vout10_2.setEntry(0, new Fraction(11, 10)); assertNotSame(vout10, vout10_2); } public void testMapFunctions() { ArrayFieldVector v1 = new ArrayFieldVector(vec1); //octave = v1 .+ 2.0 FieldVector v_mapAdd = v1.mapAdd(new Fraction(2)); Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)}; checkArray("compare vectors" ,result_mapAdd,v_mapAdd.getData()); //octave = v1 .+ 2.0 FieldVector v_mapAddToSelf = v1.copy(); v_mapAddToSelf.mapAddToSelf(new Fraction(2)); Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)}; checkArray("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData()); //octave = v1 .- 2.0 FieldVector v_mapSubtract = v1.mapSubtract(new Fraction(2)); Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)}; checkArray("compare vectors" ,result_mapSubtract,v_mapSubtract.getData()); //octave = v1 .- 2.0 FieldVector v_mapSubtractToSelf = v1.copy(); v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2)); Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)}; checkArray("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData()); //octave = v1 .* 2.0 FieldVector v_mapMultiply = v1.mapMultiply(new Fraction(2)); Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)}; checkArray("compare vectors" ,result_mapMultiply,v_mapMultiply.getData()); //octave = v1 .* 2.0 FieldVector v_mapMultiplyToSelf = v1.copy(); v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2)); Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)}; checkArray("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData()); //octave = v1 ./ 2.0 FieldVector v_mapDivide = v1.mapDivide(new Fraction(2)); Fraction[] result_mapDivide = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)}; checkArray("compare vectors" ,result_mapDivide,v_mapDivide.getData()); //octave = v1 ./ 2.0 FieldVector v_mapDivideToSelf = v1.copy(); v_mapDivideToSelf.mapDivideToSelf(new Fraction(2)); Fraction[] result_mapDivideToSelf = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)}; checkArray("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData()); //octave = v1 .^-1 FieldVector v_mapInv = v1.mapInv(); Fraction[] result_mapInv = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)}; checkArray("compare vectors" ,result_mapInv,v_mapInv.getData()); //octave = v1 .^-1 FieldVector v_mapInvToSelf = v1.copy(); v_mapInvToSelf.mapInvToSelf(); Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)}; checkArray("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData()); } public void testBasicFunctions() { ArrayFieldVector v1 = new ArrayFieldVector(vec1); ArrayFieldVector v2 = new ArrayFieldVector(vec2); new ArrayFieldVector(vec_null); FieldVectorTestImpl v2_t = new FieldVectorTestImpl(vec2); //octave = v1 + v2 ArrayFieldVector v_add = v1.add(v2); Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)}; checkArray("compare vect" ,v_add.getData(),result_add); FieldVectorTestImpl vt2 = new FieldVectorTestImpl(vec2); FieldVector v_add_i = v1.add(vt2); Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)}; checkArray("compare vect" ,v_add_i.getData(),result_add_i); //octave = v1 - v2 ArrayFieldVector v_subtract = v1.subtract(v2); Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; checkArray("compare vect" ,v_subtract.getData(),result_subtract); FieldVector v_subtract_i = v1.subtract(vt2); Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)}; checkArray("compare vect" ,v_subtract_i.getData(),result_subtract_i); // octave v1 .* v2 ArrayFieldVector v_ebeMultiply = v1.ebeMultiply(v2); Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)}; checkArray("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply); FieldVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)}; checkArray("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2); // octave v1 ./ v2 ArrayFieldVector v_ebeDivide = v1.ebeDivide(v2); Fraction[] result_ebeDivide = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)}; checkArray("compare vect" ,v_ebeDivide.getData(),result_ebeDivide); FieldVector v_ebeDivide_2 = v1.ebeDivide(v2_t); Fraction[] result_ebeDivide_2 = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)}; checkArray("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2); // octave dot(v1,v2) Fraction dot = v1.dotProduct(v2); assertEquals("compare val ",new Fraction(32), dot); // octave dot(v1,v2_t) Fraction dot_2 = v1.dotProduct(v2_t); assertEquals("compare val ",new Fraction(32), dot_2); FieldMatrix m_outerProduct = v1.outerProduct(v2); assertEquals("compare val ",new Fraction(4), m_outerProduct.getEntry(0,0)); FieldMatrix m_outerProduct_2 = v1.outerProduct(v2_t); assertEquals("compare val ",new Fraction(4), m_outerProduct_2.getEntry(0,0)); ArrayFieldVector v_projection = v1.projection(v2); Fraction[] result_projection = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)}; checkArray("compare vect", v_projection.getData(), result_projection); FieldVector v_projection_2 = v1.projection(v2_t); Fraction[] result_projection_2 = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)}; checkArray("compare vect", v_projection_2.getData(), result_projection_2); } public void testMisc() { ArrayFieldVector v1 = new ArrayFieldVector(vec1); ArrayFieldVector v4 = new ArrayFieldVector(vec4); FieldVector v4_2 = new ArrayFieldVector(vec4); String out1 = v1.toString(); assertTrue("some output ", out1.length()!=0); /* Fraction[] dout1 = v1.copyOut(); assertEquals(3, dout1.length); assertNotSame("testData not same object ", v1.data, dout1); */ try { v1.checkVectorDimensions(2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { v1.checkVectorDimensions(v4); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { v1.checkVectorDimensions(v4_2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } } public void testSerial() { ArrayFieldVector v = new ArrayFieldVector(vec1); assertEquals(v,TestUtils.serializeAndRecover(v)); } public void testZeroVectors() { // when the field is not specified, array cannot be empty try { new ArrayFieldVector(new Fraction[0]); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { new ArrayFieldVector(new Fraction[0], true); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { new ArrayFieldVector(new Fraction[0], false); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } // when the field is specified, array can be empty assertEquals(0, new ArrayFieldVector(FractionField.getInstance(), new Fraction[0]).getDimension()); assertEquals(0, new ArrayFieldVector(FractionField.getInstance(), new Fraction[0], true).getDimension()); assertEquals(0, new ArrayFieldVector(FractionField.getInstance(), new Fraction[0], false).getDimension()); } /** verifies that two vectors are equals */ protected void checkArray(String msg, Fraction[] m, Fraction[] n) { if (m.length != n.length) { fail("vectors have different lengths"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i],n[i]); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/BlockFieldMatrixTest.java100644 1750 1750 150345 11532241243 30605 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import java.util.Random; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionField; /** * Test cases for the {@link BlockFieldMatrix} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public final class BlockFieldMatrixTest extends TestCase { // 3 x 3 identity matrix protected Fraction[][] id = { {new Fraction(1),new Fraction(0),new Fraction(0)}, {new Fraction(0),new Fraction(1),new Fraction(0)}, {new Fraction(0),new Fraction(0),new Fraction(1)} }; // Test data for group operations protected Fraction[][] testData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)}, {new Fraction(1),new Fraction(0),new Fraction(8)} }; protected Fraction[][] testDataLU = { {new Fraction(2), new Fraction(5), new Fraction(3)}, {new Fraction(1, 2), new Fraction(-5, 2), new Fraction(13, 2)}, {new Fraction(1, 2), new Fraction(1, 5), new Fraction(1, 5)} }; protected Fraction[][] testDataPlus2 = { {new Fraction(3),new Fraction(4),new Fraction(5)}, {new Fraction(4),new Fraction(7),new Fraction(5)}, {new Fraction(3),new Fraction(2),new Fraction(10)} }; protected Fraction[][] testDataMinus = { {new Fraction(-1),new Fraction(-2),new Fraction(-3)}, {new Fraction(-2),new Fraction(-5),new Fraction(-3)}, {new Fraction(-1),new Fraction(0),new Fraction(-8)} }; protected Fraction[] testDataRow1 = {new Fraction(1),new Fraction(2),new Fraction(3)}; protected Fraction[] testDataCol3 = {new Fraction(3),new Fraction(3),new Fraction(8)}; protected Fraction[][] testDataInv = { {new Fraction(-40),new Fraction(16),new Fraction(9)}, {new Fraction(13),new Fraction(-5),new Fraction(-3)}, {new Fraction(5),new Fraction(-2),new Fraction(-1)} }; protected Fraction[] preMultTest = {new Fraction(8), new Fraction(12), new Fraction(33)}; protected Fraction[][] testData2 = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)} }; protected Fraction[][] testData2T = { {new Fraction(1),new Fraction(2)}, {new Fraction(2),new Fraction(5)}, {new Fraction(3),new Fraction(3)} }; protected Fraction[][] testDataPlusInv = { {new Fraction(-39),new Fraction(18),new Fraction(12)}, {new Fraction(15),new Fraction(0),new Fraction(0)}, {new Fraction(6),new Fraction(-2),new Fraction(7)} }; // lu decomposition tests protected Fraction[][] luData = { {new Fraction(2),new Fraction(3),new Fraction(3)}, {new Fraction(0),new Fraction(5),new Fraction(7)}, {new Fraction(6),new Fraction(9),new Fraction(8)} }; protected Fraction[][] luDataLUDecomposition = { {new Fraction(6),new Fraction(9),new Fraction(8)}, {new Fraction(0),new Fraction(5),new Fraction(7)}, {new Fraction(1, 3),new Fraction(0),new Fraction(1, 3)} }; // singular matrices protected Fraction[][] singular = { {new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(3)} }; protected Fraction[][] bigSingular = { {new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}, {new Fraction(2),new Fraction(5),new Fraction(3),new Fraction(4)}, {new Fraction(7),new Fraction(3),new Fraction(256),new Fraction(1930)}, {new Fraction(3),new Fraction(7),new Fraction(6),new Fraction(8)} }; // 4th row = 1st + 2nd protected Fraction[][] detData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(4),new Fraction(5),new Fraction(6)}, {new Fraction(7),new Fraction(8),new Fraction(10)} }; protected Fraction[][] detData2 = { {new Fraction(1), new Fraction(3)}, {new Fraction(2), new Fraction(4)}}; // vectors protected Fraction[] testVector = {new Fraction(1),new Fraction(2),new Fraction(3)}; protected Fraction[] testVector2 = {new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}; // submatrix accessor tests protected Fraction[][] subTestData = { {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4)}, {new Fraction(3, 2), new Fraction(5, 2), new Fraction(7, 2), new Fraction(9, 2)}, {new Fraction(2), new Fraction(4), new Fraction(6), new Fraction(8)}, {new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7)} }; // array selections protected Fraction[][] subRows02Cols13 = { {new Fraction(2), new Fraction(4)}, {new Fraction(4), new Fraction(8)}}; protected Fraction[][] subRows03Cols12 = { {new Fraction(2), new Fraction(3)}, {new Fraction(5), new Fraction(6)}}; protected Fraction[][] subRows03Cols123 = { {new Fraction(2), new Fraction(3), new Fraction(4)}, {new Fraction(5), new Fraction(6), new Fraction(7)} }; // effective permutations protected Fraction[][] subRows20Cols123 = { {new Fraction(4), new Fraction(6), new Fraction(8)}, {new Fraction(2), new Fraction(3), new Fraction(4)} }; protected Fraction[][] subRows31Cols31 = {{new Fraction(7), new Fraction(5)}, {new Fraction(9, 2), new Fraction(5, 2)}}; // contiguous ranges protected Fraction[][] subRows01Cols23 = {{new Fraction(3),new Fraction(4)} , {new Fraction(7, 2), new Fraction(9, 2)}}; protected Fraction[][] subRows23Cols00 = {{new Fraction(2)} , {new Fraction(4)}}; protected Fraction[][] subRows00Cols33 = {{new Fraction(4)}}; // row matrices protected Fraction[][] subRow0 = {{new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}}; protected Fraction[][] subRow3 = {{new Fraction(4),new Fraction(5),new Fraction(6),new Fraction(7)}}; // column matrices protected Fraction[][] subColumn1 = {{new Fraction(2)}, {new Fraction(5, 2)}, {new Fraction(4)}, {new Fraction(5)}}; protected Fraction[][] subColumn3 = {{new Fraction(4)}, {new Fraction(9, 2)}, {new Fraction(8)}, {new Fraction(7)}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public BlockFieldMatrixTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix m2 = new BlockFieldMatrix(testData2); assertEquals("testData row dimension",3,m.getRowDimension()); assertEquals("testData column dimension",3,m.getColumnDimension()); assertTrue("testData is square",m.isSquare()); assertEquals("testData2 row dimension",m2.getRowDimension(),2); assertEquals("testData2 column dimension",m2.getColumnDimension(),3); assertTrue("testData2 is not square",!m2.isSquare()); } /** test copy functions */ public void testCopyFunctions() { Random r = new Random(66636328996002l); BlockFieldMatrix m1 = createRandomMatrix(r, 47, 83); BlockFieldMatrix m2 = new BlockFieldMatrix(m1.getData()); assertEquals(m1, m2); BlockFieldMatrix m3 = new BlockFieldMatrix(testData); BlockFieldMatrix m4 = new BlockFieldMatrix(m3.getData()); assertEquals(m3, m4); } /** test add */ public void testAdd() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix mInv = new BlockFieldMatrix(testDataInv); FieldMatrix mPlusMInv = m.add(mInv); Fraction[][] sumEntries = mPlusMInv.getData(); for (int row = 0; row < m.getRowDimension(); row++) { for (int col = 0; col < m.getColumnDimension(); col++) { assertEquals(testDataPlusInv[row][col],sumEntries[row][col]); } } } /** test add failure */ public void testAddFail() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix m2 = new BlockFieldMatrix(testData2); try { m.add(m2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // ignored } } /** test m-n = m + -n */ public void testPlusMinus() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix m2 = new BlockFieldMatrix(testDataInv); TestUtils.assertEquals(m.subtract(m2), m2.scalarMultiply(new Fraction(-1)).add(m)); try { m.subtract(new BlockFieldMatrix(testData2)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } /** test multiply */ public void testMultiply() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix mInv = new BlockFieldMatrix(testDataInv); BlockFieldMatrix identity = new BlockFieldMatrix(id); BlockFieldMatrix m2 = new BlockFieldMatrix(testData2); TestUtils.assertEquals(m.multiply(mInv), identity); TestUtils.assertEquals(mInv.multiply(m), identity); TestUtils.assertEquals(m.multiply(identity), m); TestUtils.assertEquals(identity.multiply(mInv), mInv); TestUtils.assertEquals(m2.multiply(identity), m2); try { m.multiply(new BlockFieldMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testSeveralBlocks() { FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), 37, 41); for (int i = 0; i < m.getRowDimension(); ++i) { for (int j = 0; j < m.getColumnDimension(); ++j) { m.setEntry(i, j, new Fraction(i * 11 + j, 11)); } } FieldMatrix mT = m.transpose(); assertEquals(m.getRowDimension(), mT.getColumnDimension()); assertEquals(m.getColumnDimension(), mT.getRowDimension()); for (int i = 0; i < mT.getRowDimension(); ++i) { for (int j = 0; j < mT.getColumnDimension(); ++j) { assertEquals(m.getEntry(j, i), mT.getEntry(i, j)); } } FieldMatrix mPm = m.add(m); for (int i = 0; i < mPm.getRowDimension(); ++i) { for (int j = 0; j < mPm.getColumnDimension(); ++j) { assertEquals(m.getEntry(i, j).multiply(new Fraction(2)), mPm.getEntry(i, j)); } } FieldMatrix mPmMm = mPm.subtract(m); for (int i = 0; i < mPmMm.getRowDimension(); ++i) { for (int j = 0; j < mPmMm.getColumnDimension(); ++j) { assertEquals(m.getEntry(i, j), mPmMm.getEntry(i, j)); } } FieldMatrix mTm = mT.multiply(m); for (int i = 0; i < mTm.getRowDimension(); ++i) { for (int j = 0; j < mTm.getColumnDimension(); ++j) { Fraction sum = Fraction.ZERO; for (int k = 0; k < mT.getColumnDimension(); ++k) { sum = sum.add(new Fraction(k * 11 + i, 11).multiply(new Fraction(k * 11 + j, 11))); } assertEquals(sum, mTm.getEntry(i, j)); } } FieldMatrix mmT = m.multiply(mT); for (int i = 0; i < mmT.getRowDimension(); ++i) { for (int j = 0; j < mmT.getColumnDimension(); ++j) { Fraction sum = Fraction.ZERO; for (int k = 0; k < m.getColumnDimension(); ++k) { sum = sum.add(new Fraction(i * 11 + k, 11).multiply(new Fraction(j * 11 + k, 11))); } assertEquals(sum, mmT.getEntry(i, j)); } } FieldMatrix sub1 = m.getSubMatrix(2, 9, 5, 20); for (int i = 0; i < sub1.getRowDimension(); ++i) { for (int j = 0; j < sub1.getColumnDimension(); ++j) { assertEquals(new Fraction((i + 2) * 11 + (j + 5), 11), sub1.getEntry(i, j)); } } FieldMatrix sub2 = m.getSubMatrix(10, 12, 3, 40); for (int i = 0; i < sub2.getRowDimension(); ++i) { for (int j = 0; j < sub2.getColumnDimension(); ++j) { assertEquals(new Fraction((i + 10) * 11 + (j + 3), 11), sub2.getEntry(i, j)); } } FieldMatrix sub3 = m.getSubMatrix(30, 34, 0, 5); for (int i = 0; i < sub3.getRowDimension(); ++i) { for (int j = 0; j < sub3.getColumnDimension(); ++j) { assertEquals(new Fraction((i + 30) * 11 + (j + 0), 11), sub3.getEntry(i, j)); } } FieldMatrix sub4 = m.getSubMatrix(30, 32, 32, 35); for (int i = 0; i < sub4.getRowDimension(); ++i) { for (int j = 0; j < sub4.getColumnDimension(); ++j) { assertEquals(new Fraction((i + 30) * 11 + (j + 32), 11), sub4.getEntry(i, j)); } } } //Additional Test for BlockFieldMatrixTest.testMultiply private Fraction[][] d3 = new Fraction[][] { {new Fraction(1),new Fraction(2),new Fraction(3),new Fraction(4)}, {new Fraction(5),new Fraction(6),new Fraction(7),new Fraction(8)} }; private Fraction[][] d4 = new Fraction[][] { {new Fraction(1)}, {new Fraction(2)}, {new Fraction(3)}, {new Fraction(4)} }; private Fraction[][] d5 = new Fraction[][] {{new Fraction(30)},{new Fraction(70)}}; public void testMultiply2() { FieldMatrix m3 = new BlockFieldMatrix(d3); FieldMatrix m4 = new BlockFieldMatrix(d4); FieldMatrix m5 = new BlockFieldMatrix(d5); TestUtils.assertEquals(m3.multiply(m4), m5); } /** test trace */ public void testTrace() { FieldMatrix m = new BlockFieldMatrix(id); assertEquals(new Fraction(3),m.getTrace()); m = new BlockFieldMatrix(testData2); try { m.getTrace(); fail("Expecting NonSquareMatrixException"); } catch (NonSquareMatrixException ex) { // ignored } } /** test scalarAdd */ public void testScalarAdd() { FieldMatrix m = new BlockFieldMatrix(testData); TestUtils.assertEquals(new BlockFieldMatrix(testDataPlus2), m.scalarAdd(new Fraction(2))); } /** test operate */ public void testOperate() { FieldMatrix m = new BlockFieldMatrix(id); TestUtils.assertEquals(testVector, m.operate(testVector)); TestUtils.assertEquals(testVector, m.operate(new ArrayFieldVector(testVector)).getData()); m = new BlockFieldMatrix(bigSingular); try { m.operate(testVector); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testOperateLarge() { int p = (11 * BlockFieldMatrix.BLOCK_SIZE) / 10; int q = (11 * BlockFieldMatrix.BLOCK_SIZE) / 10; int r = BlockFieldMatrix.BLOCK_SIZE / 2; Random random = new Random(111007463902334l); FieldMatrix m1 = createRandomMatrix(random, p, q); FieldMatrix m2 = createRandomMatrix(random, q, r); FieldMatrix m1m2 = m1.multiply(m2); for (int i = 0; i < r; ++i) { TestUtils.assertEquals(m1m2.getColumn(i), m1.operate(m2.getColumn(i))); } } public void testOperatePremultiplyLarge() { int p = (11 * BlockFieldMatrix.BLOCK_SIZE) / 10; int q = (11 * BlockFieldMatrix.BLOCK_SIZE) / 10; int r = BlockFieldMatrix.BLOCK_SIZE / 2; Random random = new Random(111007463902334l); FieldMatrix m1 = createRandomMatrix(random, p, q); FieldMatrix m2 = createRandomMatrix(random, q, r); FieldMatrix m1m2 = m1.multiply(m2); for (int i = 0; i < p; ++i) { TestUtils.assertEquals(m1m2.getRow(i), m2.preMultiply(m1.getRow(i))); } } /** test issue MATH-209 */ public void testMath209() { FieldMatrix a = new BlockFieldMatrix(new Fraction[][] { { new Fraction(1), new Fraction(2) }, { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }); Fraction[] b = a.operate(new Fraction[] { new Fraction(1), new Fraction(1) }); assertEquals(a.getRowDimension(), b.length); assertEquals( new Fraction(3), b[0]); assertEquals( new Fraction(7), b[1]); assertEquals(new Fraction(11), b[2]); } /** test transpose */ public void testTranspose() { FieldMatrix m = new BlockFieldMatrix(testData); FieldMatrix mIT = new FieldLUDecompositionImpl(m).getSolver().getInverse().transpose(); FieldMatrix mTI = new FieldLUDecompositionImpl(m.transpose()).getSolver().getInverse(); TestUtils.assertEquals(mIT, mTI); m = new BlockFieldMatrix(testData2); FieldMatrix mt = new BlockFieldMatrix(testData2T); TestUtils.assertEquals(mt, m.transpose()); } /** test preMultiply by vector */ public void testPremultiplyVector() { FieldMatrix m = new BlockFieldMatrix(testData); TestUtils.assertEquals(m.preMultiply(testVector), preMultTest); TestUtils.assertEquals(m.preMultiply(new ArrayFieldVector(testVector).getData()), preMultTest); m = new BlockFieldMatrix(bigSingular); try { m.preMultiply(testVector); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testPremultiply() { FieldMatrix m3 = new BlockFieldMatrix(d3); FieldMatrix m4 = new BlockFieldMatrix(d4); FieldMatrix m5 = new BlockFieldMatrix(d5); TestUtils.assertEquals(m4.preMultiply(m3), m5); BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix mInv = new BlockFieldMatrix(testDataInv); BlockFieldMatrix identity = new BlockFieldMatrix(id); TestUtils.assertEquals(m.preMultiply(mInv), identity); TestUtils.assertEquals(mInv.preMultiply(m), identity); TestUtils.assertEquals(m.preMultiply(identity), m); TestUtils.assertEquals(identity.preMultiply(mInv), mInv); try { m.preMultiply(new BlockFieldMatrix(bigSingular)); fail("Expecting illegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } } public void testGetVectors() { FieldMatrix m = new BlockFieldMatrix(testData); TestUtils.assertEquals(m.getRow(0), testDataRow1); TestUtils.assertEquals(m.getColumn(2), testDataCol3); try { m.getRow(10); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } try { m.getColumn(-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // ignored } } public void testGetEntry() { FieldMatrix m = new BlockFieldMatrix(testData); assertEquals(m.getEntry(0,1),new Fraction(2)); try { m.getEntry(10, 4); fail ("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } /** test examples in user guide */ public void testExamples() { // Create a real matrix with two rows and three columns Fraction[][] matrixData = { {new Fraction(1),new Fraction(2),new Fraction(3)}, {new Fraction(2),new Fraction(5),new Fraction(3)} }; FieldMatrix m = new BlockFieldMatrix(matrixData); // One more with three rows, two columns Fraction[][] matrixData2 = { {new Fraction(1),new Fraction(2)}, {new Fraction(2),new Fraction(5)}, {new Fraction(1), new Fraction(7)} }; FieldMatrix n = new BlockFieldMatrix(matrixData2); // Now multiply m by n FieldMatrix p = m.multiply(n); assertEquals(2, p.getRowDimension()); assertEquals(2, p.getColumnDimension()); // Invert p FieldMatrix pInverse = new FieldLUDecompositionImpl(p).getSolver().getInverse(); assertEquals(2, pInverse.getRowDimension()); assertEquals(2, pInverse.getColumnDimension()); // Solve example Fraction[][] coefficientsData = { {new Fraction(2), new Fraction(3), new Fraction(-2)}, {new Fraction(-1), new Fraction(7), new Fraction(6)}, {new Fraction(4), new Fraction(-3), new Fraction(-5)} }; FieldMatrix coefficients = new BlockFieldMatrix(coefficientsData); Fraction[] constants = {new Fraction(1), new Fraction(-2), new Fraction(1)}; Fraction[] solution = new FieldLUDecompositionImpl(coefficients).getSolver().solve(constants); assertEquals(new Fraction(2).multiply(solution[0]). add(new Fraction(3).multiply(solution[1])). subtract(new Fraction(2).multiply(solution[2])), constants[0]); assertEquals(new Fraction(-1).multiply(solution[0]). add(new Fraction(7).multiply(solution[1])). add(new Fraction(6).multiply(solution[2])), constants[1]); assertEquals(new Fraction(4).multiply(solution[0]). subtract(new Fraction(3).multiply(solution[1])). subtract(new Fraction(5).multiply(solution[2])), constants[2]); } // test submatrix accessors public void testGetSubMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, -1, 1, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkGetSubMatrix(FieldMatrix m, Fraction[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { FieldMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn); if (reference != null) { assertEquals(new BlockFieldMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkGetSubMatrix(FieldMatrix m, Fraction[][] reference, int[] selectedRows, int[] selectedColumns) { try { FieldMatrix sub = m.getSubMatrix(selectedRows, selectedColumns); if (reference != null) { assertEquals(new BlockFieldMatrix(reference), sub); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testGetSetMatrixLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); FieldMatrix sub = new BlockFieldMatrix(FractionField.getInstance(), n - 4, n - 4).scalarAdd(new Fraction(1)); m.setSubMatrix(sub.getData(), 2, 2); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if ((i < 2) || (i > n - 3) || (j < 2) || (j > n - 3)) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } assertEquals(sub, m.getSubMatrix(2, n - 3, 2, n - 3)); } public void testCopySubMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); checkCopy(m, subRows23Cols00, 2 , 3 , 0, 0); checkCopy(m, subRows00Cols33, 0 , 0 , 3, 3); checkCopy(m, subRows01Cols23, 0 , 1 , 2, 3); checkCopy(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkCopy(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, -1, 1, 2, 2); checkCopy(m, null, 1, 0, 2, 2); checkCopy(m, null, 1, 0, 2, 4); checkCopy(m, null, new int[] {}, new int[] { 0 }); checkCopy(m, null, new int[] { 0 }, new int[] { 4 }); } private void checkCopy(FieldMatrix m, Fraction[][] reference, int startRow, int endRow, int startColumn, int endColumn) { try { Fraction[][] sub = (reference == null) ? new Fraction[1][1] : new Fraction[reference.length][reference[0].length]; m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub); if (reference != null) { assertEquals(new BlockFieldMatrix(reference), new BlockFieldMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } private void checkCopy(FieldMatrix m, Fraction[][] reference, int[] selectedRows, int[] selectedColumns) { try { Fraction[][] sub = (reference == null) ? new Fraction[1][1] : new Fraction[reference.length][reference[0].length]; m.copySubMatrix(selectedRows, selectedColumns, sub); if (reference != null) { assertEquals(new BlockFieldMatrix(reference), new BlockFieldMatrix(sub)); } else { fail("Expecting MatrixIndexException"); } } catch (MatrixIndexException e) { if (reference != null) { throw e; } } } public void testGetRowMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldMatrix mRow0 = new BlockFieldMatrix(subRow0); FieldMatrix mRow3 = new BlockFieldMatrix(subRow3); assertEquals("Row0", mRow0, m.getRowMatrix(0)); assertEquals("Row3", mRow3, m.getRowMatrix(3)); try { m.getRowMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldMatrix mRow3 = new BlockFieldMatrix(subRow3); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowMatrix(0, mRow3); assertEquals(mRow3, m.getRowMatrix(0)); try { m.setRowMatrix(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowMatrixLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); FieldMatrix sub = new BlockFieldMatrix(FractionField.getInstance(), 1, n).scalarAdd(new Fraction(1)); m.setRowMatrix(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } assertEquals(sub, m.getRowMatrix(2)); } public void testGetColumnMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldMatrix mColumn1 = new BlockFieldMatrix(subColumn1); FieldMatrix mColumn3 = new BlockFieldMatrix(subColumn3); assertEquals(mColumn1, m.getColumnMatrix(1)); assertEquals(mColumn3, m.getColumnMatrix(3)); try { m.getColumnMatrix(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnMatrix(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnMatrix() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldMatrix mColumn3 = new BlockFieldMatrix(subColumn3); assertNotSame(mColumn3, m.getColumnMatrix(1)); m.setColumnMatrix(1, mColumn3); assertEquals(mColumn3, m.getColumnMatrix(1)); try { m.setColumnMatrix(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnMatrix(0, m); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnMatrixLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); FieldMatrix sub = new BlockFieldMatrix(FractionField.getInstance(), n, 1).scalarAdd(new Fraction(1)); m.setColumnMatrix(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } assertEquals(sub, m.getColumnMatrix(2)); } public void testGetRowVector() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldVector mRow0 = new ArrayFieldVector(subRow0[0]); FieldVector mRow3 = new ArrayFieldVector(subRow3[0]); assertEquals(mRow0, m.getRowVector(0)); assertEquals(mRow3, m.getRowVector(3)); try { m.getRowVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRowVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRowVector() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldVector mRow3 = new ArrayFieldVector(subRow3[0]); assertNotSame(mRow3, m.getRowMatrix(0)); m.setRowVector(0, mRow3); assertEquals(mRow3, m.getRowVector(0)); try { m.setRowVector(-1, mRow3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRowVector(0, new ArrayFieldVector(FractionField.getInstance(), 5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowVectorLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); FieldVector sub = new ArrayFieldVector(n, new Fraction(1)); m.setRowVector(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } assertEquals(sub, m.getRowVector(2)); } public void testGetColumnVector() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldVector mColumn1 = columnToVector(subColumn1); FieldVector mColumn3 = columnToVector(subColumn3); assertEquals(mColumn1, m.getColumnVector(1)); assertEquals(mColumn3, m.getColumnVector(3)); try { m.getColumnVector(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumnVector(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumnVector() { FieldMatrix m = new BlockFieldMatrix(subTestData); FieldVector mColumn3 = columnToVector(subColumn3); assertNotSame(mColumn3, m.getColumnVector(1)); m.setColumnVector(1, mColumn3); assertEquals(mColumn3, m.getColumnVector(1)); try { m.setColumnVector(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumnVector(0, new ArrayFieldVector(FractionField.getInstance(), 5)); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnVectorLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); FieldVector sub = new ArrayFieldVector(n, new Fraction(1)); m.setColumnVector(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } assertEquals(sub, m.getColumnVector(2)); } private FieldVector columnToVector(Fraction[][] column) { Fraction[] data = new Fraction[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return new ArrayFieldVector(data, false); } public void testGetRow() { FieldMatrix m = new BlockFieldMatrix(subTestData); checkArrays(subRow0[0], m.getRow(0)); checkArrays(subRow3[0], m.getRow(3)); try { m.getRow(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getRow(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetRow() { FieldMatrix m = new BlockFieldMatrix(subTestData); assertTrue(subRow3[0][0] != m.getRow(0)[0]); m.setRow(0, subRow3[0]); checkArrays(subRow3[0], m.getRow(0)); try { m.setRow(-1, subRow3[0]); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setRow(0, new Fraction[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetRowLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); Fraction[] sub = new Fraction[n]; Arrays.fill(sub, new Fraction(1)); m.setRow(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } checkArrays(sub, m.getRow(2)); } public void testGetColumn() { FieldMatrix m = new BlockFieldMatrix(subTestData); Fraction[] mColumn1 = columnToArray(subColumn1); Fraction[] mColumn3 = columnToArray(subColumn3); checkArrays(mColumn1, m.getColumn(1)); checkArrays(mColumn3, m.getColumn(3)); try { m.getColumn(-1); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.getColumn(4); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } } public void testSetColumn() { FieldMatrix m = new BlockFieldMatrix(subTestData); Fraction[] mColumn3 = columnToArray(subColumn3); assertTrue(mColumn3[0] != m.getColumn(1)[0]); m.setColumn(1, mColumn3); checkArrays(mColumn3, m.getColumn(1)); try { m.setColumn(-1, mColumn3); fail("Expecting MatrixIndexException"); } catch (MatrixIndexException ex) { // expected } try { m.setColumn(0, new Fraction[5]); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ex) { // expected } } public void testGetSetColumnLarge() { int n = 3 * BlockFieldMatrix.BLOCK_SIZE; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), n, n); Fraction[] sub = new Fraction[n]; Arrays.fill(sub, new Fraction(1)); m.setColumn(2, sub); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j != 2) { assertEquals(new Fraction(0), m.getEntry(i, j)); } else { assertEquals(new Fraction(1), m.getEntry(i, j)); } } } checkArrays(sub, m.getColumn(2)); } private Fraction[] columnToArray(Fraction[][] column) { Fraction[] data = new Fraction[column.length]; for (int i = 0; i < data.length; ++i) { data[i] = column[i][0]; } return data; } private void checkArrays(Fraction[] expected, Fraction[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; ++i) { assertEquals(expected[i], actual[i]); } } public void testEqualsAndHashCode() { BlockFieldMatrix m = new BlockFieldMatrix(testData); BlockFieldMatrix m1 = (BlockFieldMatrix) m.copy(); BlockFieldMatrix mt = (BlockFieldMatrix) m.transpose(); assertTrue(m.hashCode() != mt.hashCode()); assertEquals(m.hashCode(), m1.hashCode()); assertEquals(m, m); assertEquals(m, m1); assertFalse(m.equals(null)); assertFalse(m.equals(mt)); assertFalse(m.equals(new BlockFieldMatrix(bigSingular))); } public void testToString() { BlockFieldMatrix m = new BlockFieldMatrix(testData); assertEquals("BlockFieldMatrix{{1,2,3},{2,5,3},{1,0,8}}", m.toString()); } public void testSetSubMatrix() throws Exception { BlockFieldMatrix m = new BlockFieldMatrix(testData); m.setSubMatrix(detData2,1,1); FieldMatrix expected = new BlockFieldMatrix (new Fraction[][] {{new Fraction(1),new Fraction(2),new Fraction(3)},{new Fraction(2),new Fraction(1),new Fraction(3)},{new Fraction(1),new Fraction(2),new Fraction(4)}}); assertEquals(expected, m); m.setSubMatrix(detData2,0,0); expected = new BlockFieldMatrix (new Fraction[][] {{new Fraction(1),new Fraction(3),new Fraction(3)},{new Fraction(2),new Fraction(4),new Fraction(3)},{new Fraction(1),new Fraction(2),new Fraction(4)}}); assertEquals(expected, m); m.setSubMatrix(testDataPlus2,0,0); expected = new BlockFieldMatrix (new Fraction[][] {{new Fraction(3),new Fraction(4),new Fraction(5)},{new Fraction(4),new Fraction(7),new Fraction(5)},{new Fraction(3),new Fraction(2),new Fraction(10)}}); assertEquals(expected, m); // javadoc example BlockFieldMatrix matrix = new BlockFieldMatrix(new Fraction[][] { {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4)}, {new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8)}, {new Fraction(9), new Fraction(0), new Fraction(1) , new Fraction(2)} }); matrix.setSubMatrix(new Fraction[][] { {new Fraction(3), new Fraction(4)}, {new Fraction(5), new Fraction(6)} }, 1, 1); expected = new BlockFieldMatrix(new Fraction[][] { {new Fraction(1), new Fraction(2), new Fraction(3),new Fraction(4)}, {new Fraction(5), new Fraction(3), new Fraction(4), new Fraction(8)}, {new Fraction(9), new Fraction(5) ,new Fraction(6), new Fraction(2)} }); assertEquals(expected, matrix); // dimension overflow try { m.setSubMatrix(testData,1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // dimension underflow try { m.setSubMatrix(testData,-1,1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } try { m.setSubMatrix(testData,1,-1); fail("expecting MatrixIndexException"); } catch (MatrixIndexException e) { // expected } // null try { m.setSubMatrix(null,1,1); fail("expecting NullPointerException"); } catch (NullPointerException e) { // expected } // ragged try { m.setSubMatrix(new Fraction[][] {{new Fraction(1)}, {new Fraction(2), new Fraction(3)}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } // empty try { m.setSubMatrix(new Fraction[][] {{}}, 0, 0); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected } } public void testWalk() throws MatrixVisitorException { int rows = 150; int columns = 75; FieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInRowOrder(new SetVisitor()); GetVisitor getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInColumnOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor()); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor); assertEquals(rows * columns, getVisitor.getCount()); m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2); getVisitor = new GetVisitor(); m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2); assertEquals((rows - 2) * (columns - 2), getVisitor.getCount()); for (int i = 0; i < rows; ++i) { assertEquals(new Fraction(0), m.getEntry(i, 0)); assertEquals(new Fraction(0), m.getEntry(i, columns - 1)); } for (int j = 0; j < columns; ++j) { assertEquals(new Fraction(0), m.getEntry(0, j)); assertEquals(new Fraction(0), m.getEntry(rows - 1, j)); } } public void testSerial() { BlockFieldMatrix m = new BlockFieldMatrix(testData); assertEquals(m,TestUtils.serializeAndRecover(m)); } private static class SetVisitor extends DefaultFieldMatrixChangingVisitor { public SetVisitor() { super(Fraction.ZERO); } @Override public Fraction visit(int i, int j, Fraction value) { return new Fraction(i * 11 + j, 11); } } private static class GetVisitor extends DefaultFieldMatrixPreservingVisitor { private int count; public GetVisitor() { super(Fraction.ZERO); count = 0; } @Override public void visit(int i, int j, Fraction value) { ++count; assertEquals(new Fraction(i * 11 + j, 11), value); } public int getCount() { return count; } } private BlockFieldMatrix createRandomMatrix(Random r, int rows, int columns) { BlockFieldMatrix m = new BlockFieldMatrix(FractionField.getInstance(), rows, columns); for (int i = 0; i < rows; ++i) { for (int j = 0; j < columns; ++j) { int p = r.nextInt(20) - 10; int q = r.nextInt(20) - 10; if (q == 0) { q = 1; } m.setEntry(i, j, new Fraction(p, q)); } } return m; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java100644 1750 1750 122372 11532241243 30645 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.util.Iterator; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link OpenMapRealVector} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class SparseRealVectorTest extends TestCase { // protected double[][] ma1 = {{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}; protected double[] vec1 = {1d, 2d, 3d}; protected double[] vec2 = {4d, 5d, 6d}; protected double[] vec3 = {7d, 8d, 9d}; protected double[] vec4 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; protected double[] vec5 = { -4d, 0d, 3d, 1d, -6d, 3d}; protected double[] vec_null = {0d, 0d, 0d}; protected Double[] dvec1 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; protected double[][] mat1 = {{1d, 2d, 3d}, {4d, 5d, 6d},{ 7d, 8d, 9d}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; // Testclass to test the RealVector interface // only with enough content to support the test public static class SparseRealVectorTestImpl extends AbstractRealVector implements Serializable { private static final long serialVersionUID = -6251371752518113791L; /** Entries of the vector. */ protected double data[]; public SparseRealVectorTestImpl(double[] d) { data = d.clone(); } private MatrixVisitorException unsupported() { return new MatrixVisitorException("Not supported, unneeded for test purposes", new Object[0]); } @Override public RealVector map(UnivariateRealFunction function) throws MatrixVisitorException { throw unsupported(); } @Override public RealVector mapToSelf(UnivariateRealFunction function) throws MatrixVisitorException { throw unsupported(); } @Override public Iterator iterator() { throw unsupported(); } @Override public AbstractRealVector copy() { return new SparseRealVectorTestImpl(data); } @Override public RealVector add(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector add(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector subtract(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector subtract(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector mapAdd(double d) { throw unsupported(); } @Override public RealVector mapAddToSelf(double d) { throw unsupported(); } @Override public RealVector mapSubtract(double d) { throw unsupported(); } @Override public RealVector mapSubtractToSelf(double d) { throw unsupported(); } @Override public RealVector mapMultiply(double d) { double[] out = new double[data.length]; for (int i = 0; i < data.length; i++) { out[i] = data[i] * d; } return new OpenMapRealVector(out); } @Override public RealVector mapMultiplyToSelf(double d) { throw unsupported(); } @Override public RealVector mapDivide(double d) { throw unsupported(); } @Override public RealVector mapDivideToSelf(double d) { throw unsupported(); } @Override public RealVector mapPow(double d) { throw unsupported(); } @Override public RealVector mapPowToSelf(double d) { throw unsupported(); } @Override public RealVector mapExp() { throw unsupported(); } @Override public RealVector mapExpToSelf() { throw unsupported(); } @Override public RealVector mapExpm1() { throw unsupported(); } @Override public RealVector mapExpm1ToSelf() { throw unsupported(); } @Override public RealVector mapLog() { throw unsupported(); } @Override public RealVector mapLogToSelf() { throw unsupported(); } @Override public RealVector mapLog10() { throw unsupported(); } @Override public RealVector mapLog10ToSelf() { throw unsupported(); } @Override public RealVector mapLog1p() { throw unsupported(); } @Override public RealVector mapLog1pToSelf() { throw unsupported(); } @Override public RealVector mapCosh() { throw unsupported(); } @Override public RealVector mapCoshToSelf() { throw unsupported(); } @Override public RealVector mapSinh() { throw unsupported(); } @Override public RealVector mapSinhToSelf() { throw unsupported(); } @Override public RealVector mapTanh() { throw unsupported(); } @Override public RealVector mapTanhToSelf() { throw unsupported(); } @Override public RealVector mapCos() { throw unsupported(); } @Override public RealVector mapCosToSelf() { throw unsupported(); } @Override public RealVector mapSin() { throw unsupported(); } @Override public RealVector mapSinToSelf() { throw unsupported(); } @Override public RealVector mapTan() { throw unsupported(); } @Override public RealVector mapTanToSelf() { throw unsupported(); } @Override public RealVector mapAcos() { throw unsupported(); } @Override public RealVector mapAcosToSelf() { throw unsupported(); } @Override public RealVector mapAsin() { throw unsupported(); } @Override public RealVector mapAsinToSelf() { throw unsupported(); } @Override public RealVector mapAtan() { throw unsupported(); } @Override public RealVector mapAtanToSelf() { throw unsupported(); } @Override public RealVector mapInv() { throw unsupported(); } @Override public RealVector mapInvToSelf() { throw unsupported(); } @Override public RealVector mapAbs() { throw unsupported(); } @Override public RealVector mapAbsToSelf() { throw unsupported(); } @Override public RealVector mapSqrt() { throw unsupported(); } @Override public RealVector mapSqrtToSelf() { throw unsupported(); } @Override public RealVector mapCbrt() { throw unsupported(); } @Override public RealVector mapCbrtToSelf() { throw unsupported(); } @Override public RealVector mapCeil() { throw unsupported(); } @Override public RealVector mapCeilToSelf() { throw unsupported(); } @Override public RealVector mapFloor() { throw unsupported(); } @Override public RealVector mapFloorToSelf() { throw unsupported(); } @Override public RealVector mapRint() { throw unsupported(); } @Override public RealVector mapRintToSelf() { throw unsupported(); } @Override public RealVector mapSignum() { throw unsupported(); } @Override public RealVector mapSignumToSelf() { throw unsupported(); } @Override public RealVector mapUlp() { throw unsupported(); } @Override public RealVector mapUlpToSelf() { throw unsupported(); } public RealVector ebeMultiply(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealVector ebeDivide(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector ebeDivide(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public double[] getData() { return data.clone(); } @Override public double dotProduct(RealVector v) throws IllegalArgumentException { double dot = 0; for (int i = 0; i < data.length; i++) { dot += data[i] * v.getEntry(i); } return dot; } @Override public double dotProduct(double[] v) throws IllegalArgumentException { double dot = 0; for (int i = 0; i < data.length; i++) { dot += data[i] * v[i]; } return dot; } @Override public double getNorm() { throw unsupported(); } @Override public double getL1Norm() { throw unsupported(); } @Override public double getLInfNorm() { throw unsupported(); } @Override public double getDistance(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public double getDistance(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public double getL1Distance(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public double getL1Distance(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public double getLInfDistance(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public double getLInfDistance(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector unitVector() { throw unsupported(); } @Override public void unitize() { throw unsupported(); } public RealVector projection(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealVector projection(double[] v) throws IllegalArgumentException { throw unsupported(); } @Override public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { throw unsupported(); } @Override public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { throw unsupported(); } public double getEntry(int index) throws MatrixIndexException { return data[index]; } public int getDimension() { return data.length; } public RealVector append(RealVector v) { throw unsupported(); } public RealVector append(double d) { throw unsupported(); } public RealVector append(double[] a) { throw unsupported(); } public RealVector getSubVector(int index, int n) throws MatrixIndexException { throw unsupported(); } public void setEntry(int index, double value) throws MatrixIndexException { data[index] = value; } @Override public void setSubVector(int index, RealVector v) throws MatrixIndexException { throw unsupported(); } @Override public void setSubVector(int index, double[] v) throws MatrixIndexException { throw unsupported(); } @Override public void set(double value) { throw unsupported(); } @Override public double[] toArray() { throw unsupported(); } public boolean isNaN() { throw unsupported(); } public boolean isInfinite() { throw unsupported(); } } public void testConstructors() { OpenMapRealVector v0 = new OpenMapRealVector(); assertEquals("testData len", 0, v0.getDimension()); OpenMapRealVector v1 = new OpenMapRealVector(7); assertEquals("testData len", 7, v1.getDimension()); assertEquals("testData is 0.0 ", 0.0, v1.getEntry(6)); OpenMapRealVector v3 = new OpenMapRealVector(vec1); assertEquals("testData len", 3, v3.getDimension()); assertEquals("testData is 2.0 ", 2.0, v3.getEntry(1)); //SparseRealVector v4 = new SparseRealVector(vec4, 3, 2); //assertEquals("testData len", 2, v4.getDimension()); //assertEquals("testData is 4.0 ", 4.0, v4.getEntry(0)); //try { // new SparseRealVector(vec4, 8, 3); // fail("IllegalArgumentException expected"); //} catch (IllegalArgumentException ex) { // expected behavior //} RealVector v5_i = new OpenMapRealVector(dvec1); assertEquals("testData len", 9, v5_i.getDimension()); assertEquals("testData is 9.0 ", 9.0, v5_i.getEntry(8)); OpenMapRealVector v5 = new OpenMapRealVector(dvec1); assertEquals("testData len", 9, v5.getDimension()); assertEquals("testData is 9.0 ", 9.0, v5.getEntry(8)); OpenMapRealVector v7 = new OpenMapRealVector(v1); assertEquals("testData len", 7, v7.getDimension()); assertEquals("testData is 0.0 ", 0.0, v7.getEntry(6)); SparseRealVectorTestImpl v7_i = new SparseRealVectorTestImpl(vec1); OpenMapRealVector v7_2 = new OpenMapRealVector(v7_i); assertEquals("testData len", 3, v7_2.getDimension()); assertEquals("testData is 0.0 ", 2.0d, v7_2.getEntry(1)); OpenMapRealVector v8 = new OpenMapRealVector(v1); assertEquals("testData len", 7, v8.getDimension()); assertEquals("testData is 0.0 ", 0.0, v8.getEntry(6)); } public void testDataInOut() { OpenMapRealVector v1 = new OpenMapRealVector(vec1); OpenMapRealVector v2 = new OpenMapRealVector(vec2); OpenMapRealVector v4 = new OpenMapRealVector(vec4); SparseRealVectorTestImpl v2_t = new SparseRealVectorTestImpl(vec2); RealVector v_append_1 = v1.append(v2); assertEquals("testData len", 6, v_append_1.getDimension()); assertEquals("testData is 4.0 ", 4.0, v_append_1.getEntry(3)); RealVector v_append_2 = v1.append(2.0); assertEquals("testData len", 4, v_append_2.getDimension()); assertEquals("testData is 2.0 ", 2.0, v_append_2.getEntry(3)); RealVector v_append_3 = v1.append(vec2); assertEquals("testData len", 6, v_append_3.getDimension()); assertEquals("testData is ", 4.0, v_append_3.getEntry(3)); RealVector v_append_4 = v1.append(v2_t); assertEquals("testData len", 6, v_append_4.getDimension()); assertEquals("testData is 4.0 ", 4.0, v_append_4.getEntry(3)); RealVector vout5 = v4.getSubVector(3, 3); assertEquals("testData len", 3, vout5.getDimension()); assertEquals("testData is 4.0 ", 5.0, vout5.getEntry(1)); try { v4.getSubVector(3, 7); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } OpenMapRealVector v_set1 = v1.copy(); v_set1.setEntry(1, 11.0); assertEquals("testData is 11.0 ", 11.0, v_set1.getEntry(1)); try { v_set1.setEntry(3, 11.0); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } OpenMapRealVector v_set2 = v4.copy(); v_set2.setSubVector(3, v1); assertEquals("testData is 1.0 ", 1.0, v_set2.getEntry(3)); assertEquals("testData is 7.0 ", 7.0, v_set2.getEntry(6)); try { v_set2.setSubVector(7, v1); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } OpenMapRealVector v_set3 = v1.copy(); v_set3.set(13.0); assertEquals("testData is 13.0 ", 13.0, v_set3.getEntry(2)); try { v_set3.getEntry(23); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } OpenMapRealVector v_set4 = v4.copy(); v_set4.setSubVector(3, v2_t); assertEquals("testData is 1.0 ", 4.0, v_set4.getEntry(3)); assertEquals("testData is 7.0 ", 7.0, v_set4.getEntry(6)); try { v_set4.setSubVector(7, v2_t); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } } public void testMapFunctions() { OpenMapRealVector v1 = new OpenMapRealVector(vec1); //octave = v1 .+ 2.0 RealVector v_mapAdd = v1.mapAdd(2.0d); double[] result_mapAdd = {3d, 4d, 5d}; assertClose("compare vectors" ,result_mapAdd,v_mapAdd.getData(),normTolerance); //octave = v1 .+ 2.0 RealVector v_mapAddToSelf = v1.copy(); v_mapAddToSelf.mapAddToSelf(2.0d); double[] result_mapAddToSelf = {3d, 4d, 5d}; assertClose("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData(),normTolerance); //octave = v1 .- 2.0 RealVector v_mapSubtract = v1.mapSubtract(2.0d); double[] result_mapSubtract = {-1d, 0d, 1d}; assertClose("compare vectors" ,result_mapSubtract,v_mapSubtract.getData(),normTolerance); //octave = v1 .- 2.0 RealVector v_mapSubtractToSelf = v1.copy(); v_mapSubtractToSelf.mapSubtractToSelf(2.0d); double[] result_mapSubtractToSelf = {-1d, 0d, 1d}; assertClose("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData(),normTolerance); //octave = v1 .* 2.0 RealVector v_mapMultiply = v1.mapMultiply(2.0d); double[] result_mapMultiply = {2d, 4d, 6d}; assertClose("compare vectors" ,result_mapMultiply,v_mapMultiply.getData(),normTolerance); //octave = v1 .* 2.0 RealVector v_mapMultiplyToSelf = v1.copy(); v_mapMultiplyToSelf.mapMultiplyToSelf(2.0d); double[] result_mapMultiplyToSelf = {2d, 4d, 6d}; assertClose("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData(),normTolerance); //octave = v1 ./ 2.0 RealVector v_mapDivide = v1.mapDivide(2.0d); double[] result_mapDivide = {.5d, 1d, 1.5d}; assertClose("compare vectors" ,result_mapDivide,v_mapDivide.getData(),normTolerance); //octave = v1 ./ 2.0 RealVector v_mapDivideToSelf = v1.copy(); v_mapDivideToSelf.mapDivideToSelf(2.0d); double[] result_mapDivideToSelf = {.5d, 1d, 1.5d}; assertClose("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData(),normTolerance); //octave = v1 .^ 2.0 RealVector v_mapPow = v1.mapPow(2.0d); double[] result_mapPow = {1d, 4d, 9d}; assertClose("compare vectors" ,result_mapPow,v_mapPow.getData(),normTolerance); //octave = v1 .^ 2.0 RealVector v_mapPowToSelf = v1.copy(); v_mapPowToSelf.mapPowToSelf(2.0d); double[] result_mapPowToSelf = {1d, 4d, 9d}; assertClose("compare vectors" ,result_mapPowToSelf,v_mapPowToSelf.getData(),normTolerance); //octave = exp(v1) RealVector v_mapExp = v1.mapExp(); double[] result_mapExp = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; assertClose("compare vectors" ,result_mapExp,v_mapExp.getData(),normTolerance); //octave = exp(v1) RealVector v_mapExpToSelf = v1.copy(); v_mapExpToSelf.mapExpToSelf(); double[] result_mapExpToSelf = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; assertClose("compare vectors" ,result_mapExpToSelf,v_mapExpToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapExpm1 = v1.mapExpm1(); double[] result_mapExpm1 = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; assertClose("compare vectors" ,result_mapExpm1,v_mapExpm1.getData(),normTolerance); //octave = ??? RealVector v_mapExpm1ToSelf = v1.copy(); v_mapExpm1ToSelf.mapExpm1ToSelf(); double[] result_mapExpm1ToSelf = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; assertClose("compare vectors" ,result_mapExpm1ToSelf,v_mapExpm1ToSelf.getData(),normTolerance); //octave = log(v1) RealVector v_mapLog = v1.mapLog(); double[] result_mapLog = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; assertClose("compare vectors" ,result_mapLog,v_mapLog.getData(),normTolerance); //octave = log(v1) RealVector v_mapLogToSelf = v1.copy(); v_mapLogToSelf.mapLogToSelf(); double[] result_mapLogToSelf = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; assertClose("compare vectors" ,result_mapLogToSelf,v_mapLogToSelf.getData(),normTolerance); //octave = log10(v1) RealVector v_mapLog10 = v1.mapLog10(); double[] result_mapLog10 = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; assertClose("compare vectors" ,result_mapLog10,v_mapLog10.getData(),normTolerance); //octave = log(v1) RealVector v_mapLog10ToSelf = v1.copy(); v_mapLog10ToSelf.mapLog10ToSelf(); double[] result_mapLog10ToSelf = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; assertClose("compare vectors" ,result_mapLog10ToSelf,v_mapLog10ToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapLog1p = v1.mapLog1p(); double[] result_mapLog1p = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; assertClose("compare vectors" ,result_mapLog1p,v_mapLog1p.getData(),normTolerance); //octave = ??? RealVector v_mapLog1pToSelf = v1.copy(); v_mapLog1pToSelf.mapLog1pToSelf(); double[] result_mapLog1pToSelf = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; assertClose("compare vectors" ,result_mapLog1pToSelf,v_mapLog1pToSelf.getData(),normTolerance); //octave = cosh(v1) RealVector v_mapCosh = v1.mapCosh(); double[] result_mapCosh = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; assertClose("compare vectors" ,result_mapCosh,v_mapCosh.getData(),normTolerance); //octave = cosh(v1) RealVector v_mapCoshToSelf = v1.copy(); v_mapCoshToSelf.mapCoshToSelf(); double[] result_mapCoshToSelf = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; assertClose("compare vectors" ,result_mapCoshToSelf,v_mapCoshToSelf.getData(),normTolerance); //octave = sinh(v1) RealVector v_mapSinh = v1.mapSinh(); double[] result_mapSinh = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; assertClose("compare vectors" ,result_mapSinh,v_mapSinh.getData(),normTolerance); //octave = sinh(v1) RealVector v_mapSinhToSelf = v1.copy(); v_mapSinhToSelf.mapSinhToSelf(); double[] result_mapSinhToSelf = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; assertClose("compare vectors" ,result_mapSinhToSelf,v_mapSinhToSelf.getData(),normTolerance); //octave = tanh(v1) RealVector v_mapTanh = v1.mapTanh(); double[] result_mapTanh = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; assertClose("compare vectors" ,result_mapTanh,v_mapTanh.getData(),normTolerance); //octave = tanh(v1) RealVector v_mapTanhToSelf = v1.copy(); v_mapTanhToSelf.mapTanhToSelf(); double[] result_mapTanhToSelf = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; assertClose("compare vectors" ,result_mapTanhToSelf,v_mapTanhToSelf.getData(),normTolerance); //octave = cos(v1) RealVector v_mapCos = v1.mapCos(); double[] result_mapCos = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; assertClose("compare vectors" ,result_mapCos,v_mapCos.getData(),normTolerance); //octave = cos(v1) RealVector v_mapCosToSelf = v1.copy(); v_mapCosToSelf.mapCosToSelf(); double[] result_mapCosToSelf = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; assertClose("compare vectors" ,result_mapCosToSelf,v_mapCosToSelf.getData(),normTolerance); //octave = sin(v1) RealVector v_mapSin = v1.mapSin(); double[] result_mapSin = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; assertClose("compare vectors" ,result_mapSin,v_mapSin.getData(),normTolerance); //octave = sin(v1) RealVector v_mapSinToSelf = v1.copy(); v_mapSinToSelf.mapSinToSelf(); double[] result_mapSinToSelf = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; assertClose("compare vectors" ,result_mapSinToSelf,v_mapSinToSelf.getData(),normTolerance); //octave = tan(v1) RealVector v_mapTan = v1.mapTan(); double[] result_mapTan = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; assertClose("compare vectors" ,result_mapTan,v_mapTan.getData(),normTolerance); //octave = tan(v1) RealVector v_mapTanToSelf = v1.copy(); v_mapTanToSelf.mapTanToSelf(); double[] result_mapTanToSelf = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; assertClose("compare vectors" ,result_mapTanToSelf,v_mapTanToSelf.getData(),normTolerance); double[] vat_a = {0d, 0.5d, 1.0d}; OpenMapRealVector vat = new OpenMapRealVector(vat_a); //octave = acos(vat) RealVector v_mapAcos = vat.mapAcos(); double[] result_mapAcos = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; assertClose("compare vectors" ,result_mapAcos,v_mapAcos.getData(),normTolerance); //octave = acos(vat) RealVector v_mapAcosToSelf = vat.copy(); v_mapAcosToSelf.mapAcosToSelf(); double[] result_mapAcosToSelf = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; assertClose("compare vectors" ,result_mapAcosToSelf,v_mapAcosToSelf.getData(),normTolerance); //octave = asin(vat) RealVector v_mapAsin = vat.mapAsin(); double[] result_mapAsin = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; assertClose("compare vectors" ,result_mapAsin,v_mapAsin.getData(),normTolerance); //octave = asin(vat) RealVector v_mapAsinToSelf = vat.copy(); v_mapAsinToSelf.mapAsinToSelf(); double[] result_mapAsinToSelf = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; assertClose("compare vectors" ,result_mapAsinToSelf,v_mapAsinToSelf.getData(),normTolerance); //octave = atan(vat) RealVector v_mapAtan = vat.mapAtan(); double[] result_mapAtan = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; assertClose("compare vectors" ,result_mapAtan,v_mapAtan.getData(),normTolerance); //octave = atan(vat) RealVector v_mapAtanToSelf = vat.copy(); v_mapAtanToSelf.mapAtanToSelf(); double[] result_mapAtanToSelf = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; assertClose("compare vectors" ,result_mapAtanToSelf,v_mapAtanToSelf.getData(),normTolerance); //octave = v1 .^-1 RealVector v_mapInv = v1.mapInv(); double[] result_mapInv = {1d,0.5d,3.333333333333333e-01d}; assertClose("compare vectors" ,result_mapInv,v_mapInv.getData(),normTolerance); //octave = v1 .^-1 RealVector v_mapInvToSelf = v1.copy(); v_mapInvToSelf.mapInvToSelf(); double[] result_mapInvToSelf = {1d,0.5d,3.333333333333333e-01d}; assertClose("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData(),normTolerance); double[] abs_a = {-1.0d, 0.0d, 1.0d}; OpenMapRealVector abs_v = new OpenMapRealVector(abs_a); //octave = abs(abs_v) RealVector v_mapAbs = abs_v.mapAbs(); double[] result_mapAbs = {1d,0d,1d}; assertClose("compare vectors" ,result_mapAbs,v_mapAbs.getData(),normTolerance); //octave = abs(abs_v) RealVector v_mapAbsToSelf = abs_v.copy(); v_mapAbsToSelf.mapAbsToSelf(); double[] result_mapAbsToSelf = {1d,0d,1d}; assertClose("compare vectors" ,result_mapAbsToSelf,v_mapAbsToSelf.getData(),normTolerance); //octave = sqrt(v1) RealVector v_mapSqrt = v1.mapSqrt(); double[] result_mapSqrt = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; assertClose("compare vectors" ,result_mapSqrt,v_mapSqrt.getData(),normTolerance); //octave = sqrt(v1) RealVector v_mapSqrtToSelf = v1.copy(); v_mapSqrtToSelf.mapSqrtToSelf(); double[] result_mapSqrtToSelf = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; assertClose("compare vectors" ,result_mapSqrtToSelf,v_mapSqrtToSelf.getData(),normTolerance); double[] cbrt_a = {-2.0d, 0.0d, 2.0d}; OpenMapRealVector cbrt_v = new OpenMapRealVector(cbrt_a); //octave = ??? RealVector v_mapCbrt = cbrt_v.mapCbrt(); double[] result_mapCbrt = {-1.2599210498948732d,0d,1.2599210498948732d}; assertClose("compare vectors" ,result_mapCbrt,v_mapCbrt.getData(),normTolerance); //octave = ??? RealVector v_mapCbrtToSelf = cbrt_v.copy(); v_mapCbrtToSelf.mapCbrtToSelf(); double[] result_mapCbrtToSelf = {-1.2599210498948732d,0d,1.2599210498948732d}; assertClose("compare vectors" ,result_mapCbrtToSelf,v_mapCbrtToSelf.getData(),normTolerance); double[] ceil_a = {-1.1d, 0.9d, 1.1d}; OpenMapRealVector ceil_v = new OpenMapRealVector(ceil_a); //octave = ceil(ceil_v) RealVector v_mapCeil = ceil_v.mapCeil(); double[] result_mapCeil = {-1d,1d,2d}; assertClose("compare vectors" ,result_mapCeil,v_mapCeil.getData(),normTolerance); //octave = ceil(ceil_v) RealVector v_mapCeilToSelf = ceil_v.copy(); v_mapCeilToSelf.mapCeilToSelf(); double[] result_mapCeilToSelf = {-1d,1d,2d}; assertClose("compare vectors" ,result_mapCeilToSelf,v_mapCeilToSelf.getData(),normTolerance); //octave = floor(ceil_v) RealVector v_mapFloor = ceil_v.mapFloor(); double[] result_mapFloor = {-2d,0d,1d}; assertClose("compare vectors" ,result_mapFloor,v_mapFloor.getData(),normTolerance); //octave = floor(ceil_v) RealVector v_mapFloorToSelf = ceil_v.copy(); v_mapFloorToSelf.mapFloorToSelf(); double[] result_mapFloorToSelf = {-2d,0d,1d}; assertClose("compare vectors" ,result_mapFloorToSelf,v_mapFloorToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapRint = ceil_v.mapRint(); double[] result_mapRint = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapRint,v_mapRint.getData(),normTolerance); //octave = ??? RealVector v_mapRintToSelf = ceil_v.copy(); v_mapRintToSelf.mapRintToSelf(); double[] result_mapRintToSelf = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapRintToSelf,v_mapRintToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapSignum = ceil_v.mapSignum(); double[] result_mapSignum = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapSignum,v_mapSignum.getData(),normTolerance); //octave = ??? RealVector v_mapSignumToSelf = ceil_v.copy(); v_mapSignumToSelf.mapSignumToSelf(); double[] result_mapSignumToSelf = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapSignumToSelf,v_mapSignumToSelf.getData(),normTolerance); // Is with the used resolutions of limited value as test //octave = ??? RealVector v_mapUlp = ceil_v.mapUlp(); double[] result_mapUlp = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; assertClose("compare vectors" ,result_mapUlp,v_mapUlp.getData(),normTolerance); //octave = ??? RealVector v_mapUlpToSelf = ceil_v.copy(); v_mapUlpToSelf.mapUlpToSelf(); double[] result_mapUlpToSelf = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; assertClose("compare vectors" ,result_mapUlpToSelf,v_mapUlpToSelf.getData(),normTolerance); } public void testBasicFunctions() { OpenMapRealVector v1 = new OpenMapRealVector(vec1); OpenMapRealVector v2 = new OpenMapRealVector(vec2); OpenMapRealVector v5 = new OpenMapRealVector(vec5); OpenMapRealVector v_null = new OpenMapRealVector(vec_null); SparseRealVectorTestImpl v2_t = new SparseRealVectorTestImpl(vec2); // emacs calc: [-4, 0, 3, 1, -6, 3] A --> 8.4261497731763586307 double d_getNorm = v5.getNorm(); assertEquals("compare values ", 8.4261497731763586307, d_getNorm); // emacs calc: [-4, 0, 3, 1, -6, 3] vN --> 17 double d_getL1Norm = v5.getL1Norm(); assertEquals("compare values ", 17.0, d_getL1Norm); // emacs calc: [-4, 0, 3, 1, -6, 3] vn --> 6 double d_getLInfNorm = v5.getLInfNorm(); assertEquals("compare values ", 6.0, d_getLInfNorm); //octave = sqrt(sumsq(v1-v2)) double dist = v1.getDistance(v2); assertEquals("compare values ",v1.subtract(v2).getNorm(), dist ); //octave = sqrt(sumsq(v1-v2)) double dist_2 = v1.getDistance(v2_t); assertEquals("compare values ", v1.subtract(v2).getNorm(),dist_2 ); //octave = ??? double d_getL1Distance = v1. getL1Distance(v2); assertEquals("compare values ",9d, d_getL1Distance ); double d_getL1Distance_2 = v1. getL1Distance(v2_t); assertEquals("compare values ",9d, d_getL1Distance_2 ); //octave = ??? double d_getLInfDistance = v1. getLInfDistance(v2); assertEquals("compare values ",3d, d_getLInfDistance ); double d_getLInfDistance_2 = v1. getLInfDistance(v2_t); assertEquals("compare values ",3d, d_getLInfDistance_2 ); //octave = v1 + v2 OpenMapRealVector v_add = v1.add(v2); double[] result_add = {5d, 7d, 9d}; assertClose("compare vect" ,v_add.getData(),result_add,normTolerance); SparseRealVectorTestImpl vt2 = new SparseRealVectorTestImpl(vec2); RealVector v_add_i = v1.add(vt2); double[] result_add_i = {5d, 7d, 9d}; assertClose("compare vect" ,v_add_i.getData(),result_add_i,normTolerance); //octave = v1 - v2 OpenMapRealVector v_subtract = v1.subtract(v2); double[] result_subtract = {-3d, -3d, -3d}; assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); RealVector v_subtract_i = v1.subtract(vt2); double[] result_subtract_i = {-3d, -3d, -3d}; assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); // octave v1 .* v2 RealVector v_ebeMultiply = v1.ebeMultiply(v2); double[] result_ebeMultiply = {4d, 10d, 18d}; assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); RealVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); double[] result_ebeMultiply_2 = {4d, 10d, 18d}; assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); // octave v1 ./ v2 RealVector v_ebeDivide = v1.ebeDivide(v2); double[] result_ebeDivide = {0.25d, 0.4d, 0.5d}; assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); RealVector v_ebeDivide_2 = v1.ebeDivide(v2_t); double[] result_ebeDivide_2 = {0.25d, 0.4d, 0.5d}; assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); // octave dot(v1,v2) double dot = v1.dotProduct(v2); assertEquals("compare val ",32d, dot); // octave dot(v1,v2_t) double dot_2 = v1.dotProduct(v2_t); assertEquals("compare val ",32d, dot_2); RealMatrix m_outerProduct = v1.outerProduct(v2); assertEquals("compare val ",4d, m_outerProduct.getEntry(0,0)); RealMatrix m_outerProduct_2 = v1.outerProduct(v2_t); assertEquals("compare val ",4d, m_outerProduct_2.getEntry(0,0)); RealVector v_unitVector = v1.unitVector(); RealVector v_unitVector_2 = v1.mapDivide(v1.getNorm()); assertClose("compare vect" ,v_unitVector.getData(),v_unitVector_2.getData(),normTolerance); try { v_null.unitVector(); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected behavior } OpenMapRealVector v_unitize = v1.copy(); v_unitize.unitize(); assertClose("compare vect" ,v_unitVector_2.getData(),v_unitize.getData(),normTolerance); try { v_null.unitize(); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected behavior } RealVector v_projection = v1.projection(v2); double[] result_projection = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; assertClose("compare vect", v_projection.getData(), result_projection, normTolerance); RealVector v_projection_2 = v1.projection(v2_t); double[] result_projection_2 = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; assertClose("compare vect", v_projection_2.getData(), result_projection_2, normTolerance); } public void testMisc() { OpenMapRealVector v1 = new OpenMapRealVector(vec1); String out1 = v1.toString(); assertTrue("some output ", out1.length()!=0); try { v1.checkVectorDimensions(2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } } public void testPredicates() { OpenMapRealVector v = new OpenMapRealVector(new double[] { 0, 1, 2 }); assertFalse(v.isNaN()); v.setEntry(1, Double.NaN); assertTrue(v.isNaN()); assertFalse(v.isInfinite()); v.setEntry(0, Double.POSITIVE_INFINITY); assertFalse(v.isInfinite()); // NaN has higher priority than infinity v.setEntry(1, 1); assertTrue(v.isInfinite()); v.setEntry(0, 0); assertEquals(v, new OpenMapRealVector(new double[] { 0, 1, 2 })); assertNotSame(v, new OpenMapRealVector(new double[] { 0, 1, 2 + FastMath.ulp(2)})); assertNotSame(v, new OpenMapRealVector(new double[] { 0, 1, 2, 3 })); } public void testSerial() { OpenMapRealVector v = new OpenMapRealVector(new double[] { 0, 1, 2 }); assertEquals(v,TestUtils.serializeAndRecover(v)); } /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, double[] m, double[] n, double tolerance) { if (m.length != n.length) { fail("vectors have different lengths"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i],n[i],tolerance); } } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/CholeskyDecompositionImplTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java100644 1750 1750 13617 11532241243 32542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.MathException; import org.apache.commons.math.linear.CholeskyDecomposition; import org.apache.commons.math.linear.CholeskyDecompositionImpl; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.NonSquareMatrixException; import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException; import org.apache.commons.math.linear.NotSymmetricMatrixException; import org.apache.commons.math.linear.RealMatrix; import org.junit.Test; public class CholeskyDecompositionImplTest { private double[][] testData = new double[][] { { 1, 2, 4, 7, 11 }, { 2, 13, 23, 38, 58 }, { 4, 23, 77, 122, 182 }, { 7, 38, 122, 294, 430 }, { 11, 58, 182, 430, 855 } }; /** test dimensions */ @Test public void testDimensions() throws MathException { CholeskyDecomposition llt = new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)); assertEquals(testData.length, llt.getL().getRowDimension()); assertEquals(testData.length, llt.getL().getColumnDimension()); assertEquals(testData.length, llt.getLT().getRowDimension()); assertEquals(testData.length, llt.getLT().getColumnDimension()); } /** test non-square matrix */ @Test(expected = NonSquareMatrixException.class) public void testNonSquare() throws MathException { new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[3][2])); } /** test non-symmetric matrix */ @Test(expected = NotSymmetricMatrixException.class) public void testNotSymmetricMatrixException() throws MathException { double[][] changed = testData.clone(); changed[0][changed[0].length - 1] += 1.0e-5; new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(changed)); } /** test non positive definite matrix */ @Test(expected = NotPositiveDefiniteMatrixException.class) public void testNotPositiveDefinite() throws MathException { new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[][] { { 14, 11, 13, 15, 24 }, { 11, 34, 13, 8, 25 }, { 13, 13, 14, 15, 21 }, { 15, 8, 15, 18, 23 }, { 24, 25, 21, 23, 45 } })); } @Test(expected = NotPositiveDefiniteMatrixException.class) public void testMath274() throws MathException { new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[][] { { 0.40434286, -0.09376327, 0.30328980, 0.04909388 }, {-0.09376327, 0.10400408, 0.07137959, 0.04762857 }, { 0.30328980, 0.07137959, 0.30458776, 0.04882449 }, { 0.04909388, 0.04762857, 0.04882449, 0.07543265 } })); } /** test A = LLT */ @Test public void testAEqualLLT() throws MathException { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); CholeskyDecomposition llt = new CholeskyDecompositionImpl(matrix); RealMatrix l = llt.getL(); RealMatrix lt = llt.getLT(); double norm = l.multiply(lt).subtract(matrix).getNorm(); assertEquals(0, norm, 1.0e-15); } /** test that L is lower triangular */ @Test public void testLLowerTriangular() throws MathException { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); RealMatrix l = new CholeskyDecompositionImpl(matrix).getL(); for (int i = 0; i < l.getRowDimension(); i++) { for (int j = i + 1; j < l.getColumnDimension(); j++) { assertEquals(0.0, l.getEntry(i, j), 0.0); } } } /** test that LT is transpose of L */ @Test public void testLTTransposed() throws MathException { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); CholeskyDecomposition llt = new CholeskyDecompositionImpl(matrix); RealMatrix l = llt.getL(); RealMatrix lt = llt.getLT(); double norm = l.subtract(lt.transpose()).getNorm(); assertEquals(0, norm, 1.0e-15); } /** test matrices values */ @Test public void testMatricesValues() throws MathException { RealMatrix lRef = MatrixUtils.createRealMatrix(new double[][] { { 1, 0, 0, 0, 0 }, { 2, 3, 0, 0, 0 }, { 4, 5, 6, 0, 0 }, { 7, 8, 9, 10, 0 }, { 11, 12, 13, 14, 15 } }); CholeskyDecomposition llt = new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)); // check values against known references RealMatrix l = llt.getL(); assertEquals(0, l.subtract(lRef).getNorm(), 1.0e-13); RealMatrix lt = llt.getLT(); assertEquals(0, lt.subtract(lRef.transpose()).getNorm(), 1.0e-13); // check the same cached instance is returned the second time assertTrue(l == llt.getL()); assertTrue(lt == llt.getLT()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java100644 1750 1750 140577 11532241243 30475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.util.Iterator; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link ArrayRealVector} class. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class ArrayRealVectorTest extends TestCase { // protected double[][] ma1 = {{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}; protected double[] vec1 = {1d, 2d, 3d}; protected double[] vec2 = {4d, 5d, 6d}; protected double[] vec3 = {7d, 8d, 9d}; protected double[] vec4 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; protected double[] vec5 = { -4d, 0d, 3d, 1d, -6d, 3d}; protected double[] vec_null = {0d, 0d, 0d}; protected Double[] dvec1 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; protected double[][] mat1 = {{1d, 2d, 3d}, {4d, 5d, 6d},{ 7d, 8d, 9d}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; // Testclass to test the RealVector interface // only with enough content to support the test public static class RealVectorTestImpl implements RealVector, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 4715341047369582908L; /** Entries of the vector. */ protected double data[]; public RealVectorTestImpl(double[] d) { data = d.clone(); } private MatrixVisitorException unsupported() { return new MatrixVisitorException("Not supported, unneeded for test purposes", new Object[0]); } public RealVector map(UnivariateRealFunction function) throws MatrixVisitorException { throw unsupported(); } public RealVector mapToSelf(UnivariateRealFunction function) throws MatrixVisitorException { throw unsupported(); } public Iterator iterator() { return new Iterator() { int i = 0; public boolean hasNext() { return i sparseIterator() { return iterator(); } public RealVector copy() { throw unsupported(); } public RealVector add(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealVector add(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealVector subtract(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealVector subtract(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealVector mapAdd(double d) { throw unsupported(); } public RealVector mapAddToSelf(double d) { throw unsupported(); } public RealVector mapSubtract(double d) { throw unsupported(); } public RealVector mapSubtractToSelf(double d) { throw unsupported(); } public RealVector mapMultiply(double d) { double[] out = new double[data.length]; for (int i = 0; i < data.length; i++) { out[i] = data[i] * d; } return new ArrayRealVector(out); } public RealVector mapMultiplyToSelf(double d) { throw unsupported(); } public RealVector mapDivide(double d) { throw unsupported(); } public RealVector mapDivideToSelf(double d) { throw unsupported(); } public RealVector mapPow(double d) { throw unsupported(); } public RealVector mapPowToSelf(double d) { throw unsupported(); } public RealVector mapExp() { throw unsupported(); } public RealVector mapExpToSelf() { throw unsupported(); } public RealVector mapExpm1() { throw unsupported(); } public RealVector mapExpm1ToSelf() { throw unsupported(); } public RealVector mapLog() { throw unsupported(); } public RealVector mapLogToSelf() { throw unsupported(); } public RealVector mapLog10() { throw unsupported(); } public RealVector mapLog10ToSelf() { throw unsupported(); } public RealVector mapLog1p() { throw unsupported(); } public RealVector mapLog1pToSelf() { throw unsupported(); } public RealVector mapCosh() { throw unsupported(); } public RealVector mapCoshToSelf() { throw unsupported(); } public RealVector mapSinh() { throw unsupported(); } public RealVector mapSinhToSelf() { throw unsupported(); } public RealVector mapTanh() { throw unsupported(); } public RealVector mapTanhToSelf() { throw unsupported(); } public RealVector mapCos() { throw unsupported(); } public RealVector mapCosToSelf() { throw unsupported(); } public RealVector mapSin() { throw unsupported(); } public RealVector mapSinToSelf() { throw unsupported(); } public RealVector mapTan() { throw unsupported(); } public RealVector mapTanToSelf() { throw unsupported(); } public RealVector mapAcos() { throw unsupported(); } public RealVector mapAcosToSelf() { throw unsupported(); } public RealVector mapAsin() { throw unsupported(); } public RealVector mapAsinToSelf() { throw unsupported(); } public RealVector mapAtan() { throw unsupported(); } public RealVector mapAtanToSelf() { throw unsupported(); } public RealVector mapInv() { throw unsupported(); } public RealVector mapInvToSelf() { throw unsupported(); } public RealVector mapAbs() { throw unsupported(); } public RealVector mapAbsToSelf() { throw unsupported(); } public RealVector mapSqrt() { throw unsupported(); } public RealVector mapSqrtToSelf() { throw unsupported(); } public RealVector mapCbrt() { throw unsupported(); } public RealVector mapCbrtToSelf() { throw unsupported(); } public RealVector mapCeil() { throw unsupported(); } public RealVector mapCeilToSelf() { throw unsupported(); } public RealVector mapFloor() { throw unsupported(); } public RealVector mapFloorToSelf() { throw unsupported(); } public RealVector mapRint() { throw unsupported(); } public RealVector mapRintToSelf() { throw unsupported(); } public RealVector mapSignum() { throw unsupported(); } public RealVector mapSignumToSelf() { throw unsupported(); } public RealVector mapUlp() { throw unsupported(); } public RealVector mapUlpToSelf() { throw unsupported(); } public RealVector ebeMultiply(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealVector ebeDivide(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealVector ebeDivide(double[] v) throws IllegalArgumentException { throw unsupported(); } public double[] getData() { return data.clone(); } public double dotProduct(RealVector v) throws IllegalArgumentException { double dot = 0; for (int i = 0; i < data.length; i++) { dot += data[i] * v.getEntry(i); } return dot; } public double dotProduct(double[] v) throws IllegalArgumentException { double dot = 0; for (int i = 0; i < data.length; i++) { dot += data[i] * v[i]; } return dot; } public double getNorm() { throw unsupported(); } public double getL1Norm() { throw unsupported(); } public double getLInfNorm() { throw unsupported(); } public double getDistance(RealVector v) throws IllegalArgumentException { throw unsupported(); } public double getDistance(double[] v) throws IllegalArgumentException { throw unsupported(); } public double getL1Distance(RealVector v) throws IllegalArgumentException { throw unsupported(); } public double getL1Distance(double[] v) throws IllegalArgumentException { throw unsupported(); } public double getLInfDistance(RealVector v) throws IllegalArgumentException { throw unsupported(); } public double getLInfDistance(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealVector unitVector() { throw unsupported(); } public void unitize() { throw unsupported(); } public RealVector projection(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealVector projection(double[] v) throws IllegalArgumentException { throw unsupported(); } public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { throw unsupported(); } public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { throw unsupported(); } public double getEntry(int index) throws MatrixIndexException { return data[index]; } public int getDimension() { return data.length; } public RealVector append(RealVector v) { throw unsupported(); } public RealVector append(double d) { throw unsupported(); } public RealVector append(double[] a) { throw unsupported(); } public RealVector getSubVector(int index, int n) throws MatrixIndexException { throw unsupported(); } public void setEntry(int index, double value) throws MatrixIndexException { throw unsupported(); } public void setSubVector(int index, RealVector v) throws MatrixIndexException { throw unsupported(); } public void setSubVector(int index, double[] v) throws MatrixIndexException { throw unsupported(); } public void set(double value) { throw unsupported(); } public double[] toArray() { throw unsupported(); } public boolean isNaN() { throw unsupported(); } public boolean isInfinite() { throw unsupported(); } } public void testConstructors() { ArrayRealVector v0 = new ArrayRealVector(); assertEquals("testData len", 0, v0.getDimension()); ArrayRealVector v1 = new ArrayRealVector(7); assertEquals("testData len", 7, v1.getDimension()); assertEquals("testData is 0.0 ", 0.0, v1.getEntry(6)); ArrayRealVector v2 = new ArrayRealVector(5, 1.23); assertEquals("testData len", 5, v2.getDimension()); assertEquals("testData is 1.23 ", 1.23, v2.getEntry(4)); ArrayRealVector v3 = new ArrayRealVector(vec1); assertEquals("testData len", 3, v3.getDimension()); assertEquals("testData is 2.0 ", 2.0, v3.getEntry(1)); ArrayRealVector v3_bis = new ArrayRealVector(vec1, true); assertEquals("testData len", 3, v3_bis.getDimension()); assertEquals("testData is 2.0 ", 2.0, v3_bis.getEntry(1)); assertNotSame(v3_bis.getDataRef(), vec1); assertNotSame(v3_bis.getData(), vec1); ArrayRealVector v3_ter = new ArrayRealVector(vec1, false); assertEquals("testData len", 3, v3_ter.getDimension()); assertEquals("testData is 2.0 ", 2.0, v3_ter.getEntry(1)); assertSame(v3_ter.getDataRef(), vec1); assertNotSame(v3_ter.getData(), vec1); ArrayRealVector v4 = new ArrayRealVector(vec4, 3, 2); assertEquals("testData len", 2, v4.getDimension()); assertEquals("testData is 4.0 ", 4.0, v4.getEntry(0)); try { new ArrayRealVector(vec4, 8, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } RealVector v5_i = new ArrayRealVector(dvec1); assertEquals("testData len", 9, v5_i.getDimension()); assertEquals("testData is 9.0 ", 9.0, v5_i.getEntry(8)); ArrayRealVector v5 = new ArrayRealVector(dvec1); assertEquals("testData len", 9, v5.getDimension()); assertEquals("testData is 9.0 ", 9.0, v5.getEntry(8)); ArrayRealVector v6 = new ArrayRealVector(dvec1, 3, 2); assertEquals("testData len", 2, v6.getDimension()); assertEquals("testData is 4.0 ", 4.0, v6.getEntry(0)); try { new ArrayRealVector(dvec1, 8, 3); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } ArrayRealVector v7 = new ArrayRealVector(v1); assertEquals("testData len", 7, v7.getDimension()); assertEquals("testData is 0.0 ", 0.0, v7.getEntry(6)); RealVectorTestImpl v7_i = new RealVectorTestImpl(vec1); ArrayRealVector v7_2 = new ArrayRealVector(v7_i); assertEquals("testData len", 3, v7_2.getDimension()); assertEquals("testData is 0.0 ", 2.0d, v7_2.getEntry(1)); ArrayRealVector v8 = new ArrayRealVector(v1, true); assertEquals("testData len", 7, v8.getDimension()); assertEquals("testData is 0.0 ", 0.0, v8.getEntry(6)); assertNotSame("testData not same object ", v1.data, v8.data); ArrayRealVector v8_2 = new ArrayRealVector(v1, false); assertEquals("testData len", 7, v8_2.getDimension()); assertEquals("testData is 0.0 ", 0.0, v8_2.getEntry(6)); assertEquals("testData same object ", v1.data, v8_2.data); ArrayRealVector v9 = new ArrayRealVector(v1, v3); assertEquals("testData len", 10, v9.getDimension()); assertEquals("testData is 1.0 ", 1.0, v9.getEntry(7)); ArrayRealVector v10 = new ArrayRealVector(v2, new RealVectorTestImpl(vec3)); assertEquals("testData len", 8, v10.getDimension()); assertEquals("testData is 1.23 ", 1.23, v10.getEntry(4)); assertEquals("testData is 7.0 ", 7.0, v10.getEntry(5)); ArrayRealVector v11 = new ArrayRealVector(new RealVectorTestImpl(vec3), v2); assertEquals("testData len", 8, v11.getDimension()); assertEquals("testData is 9.0 ", 9.0, v11.getEntry(2)); assertEquals("testData is 1.23 ", 1.23, v11.getEntry(3)); ArrayRealVector v12 = new ArrayRealVector(v2, vec3); assertEquals("testData len", 8, v12.getDimension()); assertEquals("testData is 1.23 ", 1.23, v12.getEntry(4)); assertEquals("testData is 7.0 ", 7.0, v12.getEntry(5)); ArrayRealVector v13 = new ArrayRealVector(vec3, v2); assertEquals("testData len", 8, v13.getDimension()); assertEquals("testData is 9.0 ", 9.0, v13.getEntry(2)); assertEquals("testData is 1.23 ", 1.23, v13.getEntry(3)); ArrayRealVector v14 = new ArrayRealVector(vec3, vec4); assertEquals("testData len", 12, v14.getDimension()); assertEquals("testData is 9.0 ", 9.0, v14.getEntry(2)); assertEquals("testData is 1.0 ", 1.0, v14.getEntry(3)); } public void testDataInOut() { ArrayRealVector v1 = new ArrayRealVector(vec1); ArrayRealVector v2 = new ArrayRealVector(vec2); ArrayRealVector v4 = new ArrayRealVector(vec4); RealVectorTestImpl v2_t = new RealVectorTestImpl(vec2); RealVector v_append_1 = v1.append(v2); assertEquals("testData len", 6, v_append_1.getDimension()); assertEquals("testData is 4.0 ", 4.0, v_append_1.getEntry(3)); RealVector v_append_2 = v1.append(2.0); assertEquals("testData len", 4, v_append_2.getDimension()); assertEquals("testData is 2.0 ", 2.0, v_append_2.getEntry(3)); RealVector v_append_3 = v1.append(vec2); assertEquals("testData len", 6, v_append_3.getDimension()); assertEquals("testData is ", 4.0, v_append_3.getEntry(3)); RealVector v_append_4 = v1.append(v2_t); assertEquals("testData len", 6, v_append_4.getDimension()); assertEquals("testData is 4.0 ", 4.0, v_append_4.getEntry(3)); RealVector v_append_5 = v1.append((RealVector) v2); assertEquals("testData len", 6, v_append_5.getDimension()); assertEquals("testData is 4.0 ", 4.0, v_append_5.getEntry(3)); RealVector v_copy = v1.copy(); assertEquals("testData len", 3, v_copy.getDimension()); assertNotSame("testData not same object ", v1.data, v_copy.getData()); double[] a_double = v1.toArray(); assertEquals("testData len", 3, a_double.length); assertNotSame("testData not same object ", v1.data, a_double); // ArrayRealVector vout4 = (ArrayRealVector) v1.clone(); // assertEquals("testData len", 3, vout4.getDimension()); // assertEquals("testData not same object ", v1.data, vout4.data); RealVector vout5 = v4.getSubVector(3, 3); assertEquals("testData len", 3, vout5.getDimension()); assertEquals("testData is 4.0 ", 5.0, vout5.getEntry(1)); try { v4.getSubVector(3, 7); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayRealVector v_set1 = (ArrayRealVector) v1.copy(); v_set1.setEntry(1, 11.0); assertEquals("testData is 11.0 ", 11.0, v_set1.getEntry(1)); try { v_set1.setEntry(3, 11.0); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayRealVector v_set2 = (ArrayRealVector) v4.copy(); v_set2.set(3, v1); assertEquals("testData is 1.0 ", 1.0, v_set2.getEntry(3)); assertEquals("testData is 7.0 ", 7.0, v_set2.getEntry(6)); try { v_set2.set(7, v1); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayRealVector v_set3 = (ArrayRealVector) v1.copy(); v_set3.set(13.0); assertEquals("testData is 13.0 ", 13.0, v_set3.getEntry(2)); try { v_set3.getEntry(23); fail("ArrayIndexOutOfBoundsException expected"); } catch (ArrayIndexOutOfBoundsException ex) { // expected behavior } ArrayRealVector v_set4 = (ArrayRealVector) v4.copy(); v_set4.setSubVector(3, v2_t); assertEquals("testData is 1.0 ", 4.0, v_set4.getEntry(3)); assertEquals("testData is 7.0 ", 7.0, v_set4.getEntry(6)); try { v_set4.setSubVector(7, v2_t); fail("MatrixIndexException expected"); } catch (MatrixIndexException ex) { // expected behavior } ArrayRealVector vout10 = (ArrayRealVector) v1.copy(); ArrayRealVector vout10_2 = (ArrayRealVector) v1.copy(); assertEquals(vout10, vout10_2); vout10_2.setEntry(0, 1.1); assertNotSame(vout10, vout10_2); } public void testMapFunctions() { ArrayRealVector v1 = new ArrayRealVector(vec1); //octave = v1 .+ 2.0 RealVector v_mapAdd = v1.mapAdd(2.0d); double[] result_mapAdd = {3d, 4d, 5d}; assertClose("compare vectors" ,result_mapAdd,v_mapAdd.getData(),normTolerance); //octave = v1 .+ 2.0 RealVector v_mapAddToSelf = v1.copy(); v_mapAddToSelf.mapAddToSelf(2.0d); double[] result_mapAddToSelf = {3d, 4d, 5d}; assertClose("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData(),normTolerance); //octave = v1 .- 2.0 RealVector v_mapSubtract = v1.mapSubtract(2.0d); double[] result_mapSubtract = {-1d, 0d, 1d}; assertClose("compare vectors" ,result_mapSubtract,v_mapSubtract.getData(),normTolerance); //octave = v1 .- 2.0 RealVector v_mapSubtractToSelf = v1.copy(); v_mapSubtractToSelf.mapSubtractToSelf(2.0d); double[] result_mapSubtractToSelf = {-1d, 0d, 1d}; assertClose("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData(),normTolerance); //octave = v1 .* 2.0 RealVector v_mapMultiply = v1.mapMultiply(2.0d); double[] result_mapMultiply = {2d, 4d, 6d}; assertClose("compare vectors" ,result_mapMultiply,v_mapMultiply.getData(),normTolerance); //octave = v1 .* 2.0 RealVector v_mapMultiplyToSelf = v1.copy(); v_mapMultiplyToSelf.mapMultiplyToSelf(2.0d); double[] result_mapMultiplyToSelf = {2d, 4d, 6d}; assertClose("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData(),normTolerance); //octave = v1 ./ 2.0 RealVector v_mapDivide = v1.mapDivide(2.0d); double[] result_mapDivide = {.5d, 1d, 1.5d}; assertClose("compare vectors" ,result_mapDivide,v_mapDivide.getData(),normTolerance); //octave = v1 ./ 2.0 RealVector v_mapDivideToSelf = v1.copy(); v_mapDivideToSelf.mapDivideToSelf(2.0d); double[] result_mapDivideToSelf = {.5d, 1d, 1.5d}; assertClose("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData(),normTolerance); //octave = v1 .^ 2.0 RealVector v_mapPow = v1.mapPow(2.0d); double[] result_mapPow = {1d, 4d, 9d}; assertClose("compare vectors" ,result_mapPow,v_mapPow.getData(),normTolerance); //octave = v1 .^ 2.0 RealVector v_mapPowToSelf = v1.copy(); v_mapPowToSelf.mapPowToSelf(2.0d); double[] result_mapPowToSelf = {1d, 4d, 9d}; assertClose("compare vectors" ,result_mapPowToSelf,v_mapPowToSelf.getData(),normTolerance); //octave = exp(v1) RealVector v_mapExp = v1.mapExp(); double[] result_mapExp = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; assertClose("compare vectors" ,result_mapExp,v_mapExp.getData(),normTolerance); //octave = exp(v1) RealVector v_mapExpToSelf = v1.copy(); v_mapExpToSelf.mapExpToSelf(); double[] result_mapExpToSelf = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; assertClose("compare vectors" ,result_mapExpToSelf,v_mapExpToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapExpm1 = v1.mapExpm1(); double[] result_mapExpm1 = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; assertClose("compare vectors" ,result_mapExpm1,v_mapExpm1.getData(),normTolerance); //octave = ??? RealVector v_mapExpm1ToSelf = v1.copy(); v_mapExpm1ToSelf.mapExpm1ToSelf(); double[] result_mapExpm1ToSelf = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; assertClose("compare vectors" ,result_mapExpm1ToSelf,v_mapExpm1ToSelf.getData(),normTolerance); //octave = log(v1) RealVector v_mapLog = v1.mapLog(); double[] result_mapLog = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; assertClose("compare vectors" ,result_mapLog,v_mapLog.getData(),normTolerance); //octave = log(v1) RealVector v_mapLogToSelf = v1.copy(); v_mapLogToSelf.mapLogToSelf(); double[] result_mapLogToSelf = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; assertClose("compare vectors" ,result_mapLogToSelf,v_mapLogToSelf.getData(),normTolerance); //octave = log10(v1) RealVector v_mapLog10 = v1.mapLog10(); double[] result_mapLog10 = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; assertClose("compare vectors" ,result_mapLog10,v_mapLog10.getData(),normTolerance); //octave = log(v1) RealVector v_mapLog10ToSelf = v1.copy(); v_mapLog10ToSelf.mapLog10ToSelf(); double[] result_mapLog10ToSelf = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; assertClose("compare vectors" ,result_mapLog10ToSelf,v_mapLog10ToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapLog1p = v1.mapLog1p(); double[] result_mapLog1p = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; assertClose("compare vectors" ,result_mapLog1p,v_mapLog1p.getData(),normTolerance); //octave = ??? RealVector v_mapLog1pToSelf = v1.copy(); v_mapLog1pToSelf.mapLog1pToSelf(); double[] result_mapLog1pToSelf = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; assertClose("compare vectors" ,result_mapLog1pToSelf,v_mapLog1pToSelf.getData(),normTolerance); //octave = cosh(v1) RealVector v_mapCosh = v1.mapCosh(); double[] result_mapCosh = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; assertClose("compare vectors" ,result_mapCosh,v_mapCosh.getData(),normTolerance); //octave = cosh(v1) RealVector v_mapCoshToSelf = v1.copy(); v_mapCoshToSelf.mapCoshToSelf(); double[] result_mapCoshToSelf = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; assertClose("compare vectors" ,result_mapCoshToSelf,v_mapCoshToSelf.getData(),normTolerance); //octave = sinh(v1) RealVector v_mapSinh = v1.mapSinh(); double[] result_mapSinh = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; assertClose("compare vectors" ,result_mapSinh,v_mapSinh.getData(),normTolerance); //octave = sinh(v1) RealVector v_mapSinhToSelf = v1.copy(); v_mapSinhToSelf.mapSinhToSelf(); double[] result_mapSinhToSelf = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; assertClose("compare vectors" ,result_mapSinhToSelf,v_mapSinhToSelf.getData(),normTolerance); //octave = tanh(v1) RealVector v_mapTanh = v1.mapTanh(); double[] result_mapTanh = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; assertClose("compare vectors" ,result_mapTanh,v_mapTanh.getData(),normTolerance); //octave = tanh(v1) RealVector v_mapTanhToSelf = v1.copy(); v_mapTanhToSelf.mapTanhToSelf(); double[] result_mapTanhToSelf = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; assertClose("compare vectors" ,result_mapTanhToSelf,v_mapTanhToSelf.getData(),normTolerance); //octave = cos(v1) RealVector v_mapCos = v1.mapCos(); double[] result_mapCos = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; assertClose("compare vectors" ,result_mapCos,v_mapCos.getData(),normTolerance); //octave = cos(v1) RealVector v_mapCosToSelf = v1.copy(); v_mapCosToSelf.mapCosToSelf(); double[] result_mapCosToSelf = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; assertClose("compare vectors" ,result_mapCosToSelf,v_mapCosToSelf.getData(),normTolerance); //octave = sin(v1) RealVector v_mapSin = v1.mapSin(); double[] result_mapSin = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; assertClose("compare vectors" ,result_mapSin,v_mapSin.getData(),normTolerance); //octave = sin(v1) RealVector v_mapSinToSelf = v1.copy(); v_mapSinToSelf.mapSinToSelf(); double[] result_mapSinToSelf = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; assertClose("compare vectors" ,result_mapSinToSelf,v_mapSinToSelf.getData(),normTolerance); //octave = tan(v1) RealVector v_mapTan = v1.mapTan(); double[] result_mapTan = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; assertClose("compare vectors" ,result_mapTan,v_mapTan.getData(),normTolerance); //octave = tan(v1) RealVector v_mapTanToSelf = v1.copy(); v_mapTanToSelf.mapTanToSelf(); double[] result_mapTanToSelf = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; assertClose("compare vectors" ,result_mapTanToSelf,v_mapTanToSelf.getData(),normTolerance); double[] vat_a = {0d, 0.5d, 1.0d}; ArrayRealVector vat = new ArrayRealVector(vat_a); //octave = acos(vat) RealVector v_mapAcos = vat.mapAcos(); double[] result_mapAcos = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; assertClose("compare vectors" ,result_mapAcos,v_mapAcos.getData(),normTolerance); //octave = acos(vat) RealVector v_mapAcosToSelf = vat.copy(); v_mapAcosToSelf.mapAcosToSelf(); double[] result_mapAcosToSelf = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; assertClose("compare vectors" ,result_mapAcosToSelf,v_mapAcosToSelf.getData(),normTolerance); //octave = asin(vat) RealVector v_mapAsin = vat.mapAsin(); double[] result_mapAsin = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; assertClose("compare vectors" ,result_mapAsin,v_mapAsin.getData(),normTolerance); //octave = asin(vat) RealVector v_mapAsinToSelf = vat.copy(); v_mapAsinToSelf.mapAsinToSelf(); double[] result_mapAsinToSelf = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; assertClose("compare vectors" ,result_mapAsinToSelf,v_mapAsinToSelf.getData(),normTolerance); //octave = atan(vat) RealVector v_mapAtan = vat.mapAtan(); double[] result_mapAtan = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; assertClose("compare vectors" ,result_mapAtan,v_mapAtan.getData(),normTolerance); //octave = atan(vat) RealVector v_mapAtanToSelf = vat.copy(); v_mapAtanToSelf.mapAtanToSelf(); double[] result_mapAtanToSelf = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; assertClose("compare vectors" ,result_mapAtanToSelf,v_mapAtanToSelf.getData(),normTolerance); //octave = v1 .^-1 RealVector v_mapInv = v1.mapInv(); double[] result_mapInv = {1d,0.5d,3.333333333333333e-01d}; assertClose("compare vectors" ,result_mapInv,v_mapInv.getData(),normTolerance); //octave = v1 .^-1 RealVector v_mapInvToSelf = v1.copy(); v_mapInvToSelf.mapInvToSelf(); double[] result_mapInvToSelf = {1d,0.5d,3.333333333333333e-01d}; assertClose("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData(),normTolerance); double[] abs_a = {-1.0d, 0.0d, 1.0d}; ArrayRealVector abs_v = new ArrayRealVector(abs_a); //octave = abs(abs_v) RealVector v_mapAbs = abs_v.mapAbs(); double[] result_mapAbs = {1d,0d,1d}; assertClose("compare vectors" ,result_mapAbs,v_mapAbs.getData(),normTolerance); //octave = abs(abs_v) RealVector v_mapAbsToSelf = abs_v.copy(); v_mapAbsToSelf.mapAbsToSelf(); double[] result_mapAbsToSelf = {1d,0d,1d}; assertClose("compare vectors" ,result_mapAbsToSelf,v_mapAbsToSelf.getData(),normTolerance); //octave = sqrt(v1) RealVector v_mapSqrt = v1.mapSqrt(); double[] result_mapSqrt = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; assertClose("compare vectors" ,result_mapSqrt,v_mapSqrt.getData(),normTolerance); //octave = sqrt(v1) RealVector v_mapSqrtToSelf = v1.copy(); v_mapSqrtToSelf.mapSqrtToSelf(); double[] result_mapSqrtToSelf = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; assertClose("compare vectors" ,result_mapSqrtToSelf,v_mapSqrtToSelf.getData(),normTolerance); double[] cbrt_a = {-2.0d, 0.0d, 2.0d}; ArrayRealVector cbrt_v = new ArrayRealVector(cbrt_a); //octave = ??? RealVector v_mapCbrt = cbrt_v.mapCbrt(); double[] result_mapCbrt = {-1.2599210498948732d,0d,1.2599210498948732d}; assertClose("compare vectors" ,result_mapCbrt,v_mapCbrt.getData(),normTolerance); //octave = ??? RealVector v_mapCbrtToSelf = cbrt_v.copy(); v_mapCbrtToSelf.mapCbrtToSelf(); double[] result_mapCbrtToSelf = {-1.2599210498948732d,0d,1.2599210498948732d}; assertClose("compare vectors" ,result_mapCbrtToSelf,v_mapCbrtToSelf.getData(),normTolerance); double[] ceil_a = {-1.1d, 0.9d, 1.1d}; ArrayRealVector ceil_v = new ArrayRealVector(ceil_a); //octave = ceil(ceil_v) RealVector v_mapCeil = ceil_v.mapCeil(); double[] result_mapCeil = {-1d,1d,2d}; assertClose("compare vectors" ,result_mapCeil,v_mapCeil.getData(),normTolerance); //octave = ceil(ceil_v) RealVector v_mapCeilToSelf = ceil_v.copy(); v_mapCeilToSelf.mapCeilToSelf(); double[] result_mapCeilToSelf = {-1d,1d,2d}; assertClose("compare vectors" ,result_mapCeilToSelf,v_mapCeilToSelf.getData(),normTolerance); //octave = floor(ceil_v) RealVector v_mapFloor = ceil_v.mapFloor(); double[] result_mapFloor = {-2d,0d,1d}; assertClose("compare vectors" ,result_mapFloor,v_mapFloor.getData(),normTolerance); //octave = floor(ceil_v) RealVector v_mapFloorToSelf = ceil_v.copy(); v_mapFloorToSelf.mapFloorToSelf(); double[] result_mapFloorToSelf = {-2d,0d,1d}; assertClose("compare vectors" ,result_mapFloorToSelf,v_mapFloorToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapRint = ceil_v.mapRint(); double[] result_mapRint = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapRint,v_mapRint.getData(),normTolerance); //octave = ??? RealVector v_mapRintToSelf = ceil_v.copy(); v_mapRintToSelf.mapRintToSelf(); double[] result_mapRintToSelf = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapRintToSelf,v_mapRintToSelf.getData(),normTolerance); //octave = ??? RealVector v_mapSignum = ceil_v.mapSignum(); double[] result_mapSignum = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapSignum,v_mapSignum.getData(),normTolerance); //octave = ??? RealVector v_mapSignumToSelf = ceil_v.copy(); v_mapSignumToSelf.mapSignumToSelf(); double[] result_mapSignumToSelf = {-1d,1d,1d}; assertClose("compare vectors" ,result_mapSignumToSelf,v_mapSignumToSelf.getData(),normTolerance); // Is with the used resolutions of limited value as test //octave = ??? RealVector v_mapUlp = ceil_v.mapUlp(); double[] result_mapUlp = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; assertClose("compare vectors" ,result_mapUlp,v_mapUlp.getData(),normTolerance); //octave = ??? RealVector v_mapUlpToSelf = ceil_v.copy(); v_mapUlpToSelf.mapUlpToSelf(); double[] result_mapUlpToSelf = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; assertClose("compare vectors" ,result_mapUlpToSelf,v_mapUlpToSelf.getData(),normTolerance); } public void testBasicFunctions() { ArrayRealVector v1 = new ArrayRealVector(vec1); ArrayRealVector v2 = new ArrayRealVector(vec2); ArrayRealVector v5 = new ArrayRealVector(vec5); ArrayRealVector v_null = new ArrayRealVector(vec_null); RealVectorTestImpl v2_t = new RealVectorTestImpl(vec2); // emacs calc: [-4, 0, 3, 1, -6, 3] A --> 8.4261497731763586307 double d_getNorm = v5.getNorm(); assertEquals("compare values ", 8.4261497731763586307, d_getNorm); // emacs calc: [-4, 0, 3, 1, -6, 3] vN --> 17 double d_getL1Norm = v5.getL1Norm(); assertEquals("compare values ", 17.0, d_getL1Norm); // emacs calc: [-4, 0, 3, 1, -6, 3] vn --> 6 double d_getLInfNorm = v5.getLInfNorm(); assertEquals("compare values ", 6.0, d_getLInfNorm); //octave = sqrt(sumsq(v1-v2)) double dist = v1.getDistance(v2); assertEquals("compare values ",v1.subtract(v2).getNorm(), dist ); //octave = sqrt(sumsq(v1-v2)) double dist_2 = v1.getDistance(v2_t); assertEquals("compare values ", v1.subtract(v2).getNorm(),dist_2 ); //octave = sqrt(sumsq(v1-v2)) double dist_3 = v1.getDistance((RealVector) v2); assertEquals("compare values ", v1.subtract(v2).getNorm(),dist_3 ); //octave = ??? double d_getL1Distance = v1. getL1Distance(v2); assertEquals("compare values ",9d, d_getL1Distance ); double d_getL1Distance_2 = v1. getL1Distance(v2_t); assertEquals("compare values ",9d, d_getL1Distance_2 ); double d_getL1Distance_3 = v1. getL1Distance((RealVector) v2); assertEquals("compare values ",9d, d_getL1Distance_3 ); //octave = ??? double d_getLInfDistance = v1. getLInfDistance(v2); assertEquals("compare values ",3d, d_getLInfDistance ); double d_getLInfDistance_2 = v1. getLInfDistance(v2_t); assertEquals("compare values ",3d, d_getLInfDistance_2 ); double d_getLInfDistance_3 = v1. getLInfDistance((RealVector) v2); assertEquals("compare values ",3d, d_getLInfDistance_3 ); //octave = v1 + v2 ArrayRealVector v_add = v1.add(v2); double[] result_add = {5d, 7d, 9d}; assertClose("compare vect" ,v_add.getData(),result_add,normTolerance); RealVectorTestImpl vt2 = new RealVectorTestImpl(vec2); RealVector v_add_i = v1.add(vt2); double[] result_add_i = {5d, 7d, 9d}; assertClose("compare vect" ,v_add_i.getData(),result_add_i,normTolerance); //octave = v1 - v2 ArrayRealVector v_subtract = v1.subtract(v2); double[] result_subtract = {-3d, -3d, -3d}; assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); RealVector v_subtract_i = v1.subtract(vt2); double[] result_subtract_i = {-3d, -3d, -3d}; assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); // octave v1 .* v2 ArrayRealVector v_ebeMultiply = v1.ebeMultiply(v2); double[] result_ebeMultiply = {4d, 10d, 18d}; assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); RealVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); double[] result_ebeMultiply_2 = {4d, 10d, 18d}; assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); RealVector v_ebeMultiply_3 = v1.ebeMultiply((RealVector) v2); double[] result_ebeMultiply_3 = {4d, 10d, 18d}; assertClose("compare vect" ,v_ebeMultiply_3.getData(),result_ebeMultiply_3,normTolerance); // octave v1 ./ v2 ArrayRealVector v_ebeDivide = v1.ebeDivide(v2); double[] result_ebeDivide = {0.25d, 0.4d, 0.5d}; assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); RealVector v_ebeDivide_2 = v1.ebeDivide(v2_t); double[] result_ebeDivide_2 = {0.25d, 0.4d, 0.5d}; assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); RealVector v_ebeDivide_3 = v1.ebeDivide((RealVector) v2); double[] result_ebeDivide_3 = {0.25d, 0.4d, 0.5d}; assertClose("compare vect" ,v_ebeDivide_3.getData(),result_ebeDivide_3,normTolerance); // octave dot(v1,v2) double dot = v1.dotProduct(v2); assertEquals("compare val ",32d, dot); // octave dot(v1,v2_t) double dot_2 = v1.dotProduct(v2_t); assertEquals("compare val ",32d, dot_2); RealMatrix m_outerProduct = v1.outerProduct(v2); assertEquals("compare val ",4d, m_outerProduct.getEntry(0,0)); RealMatrix m_outerProduct_2 = v1.outerProduct(v2_t); assertEquals("compare val ",4d, m_outerProduct_2.getEntry(0,0)); RealMatrix m_outerProduct_3 = v1.outerProduct((RealVector) v2); assertEquals("compare val ",4d, m_outerProduct_3.getEntry(0,0)); RealVector v_unitVector = v1.unitVector(); RealVector v_unitVector_2 = v1.mapDivide(v1.getNorm()); assertClose("compare vect" ,v_unitVector.getData(),v_unitVector_2.getData(),normTolerance); try { v_null.unitVector(); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected behavior } ArrayRealVector v_unitize = (ArrayRealVector)v1.copy(); v_unitize.unitize(); assertClose("compare vect" ,v_unitVector_2.getData(),v_unitize.getData(),normTolerance); try { v_null.unitize(); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected behavior } ArrayRealVector v_projection = v1.projection(v2); double[] result_projection = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; assertClose("compare vect", v_projection.getData(), result_projection, normTolerance); RealVector v_projection_2 = v1.projection(v2_t); double[] result_projection_2 = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; assertClose("compare vect", v_projection_2.getData(), result_projection_2, normTolerance); RealVector v_projection_3 = v1.projection(v2.getData()); double[] result_projection_3 = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; assertClose("compare vect", v_projection_3.getData(), result_projection_3, normTolerance); } public void testMisc() { ArrayRealVector v1 = new ArrayRealVector(vec1); ArrayRealVector v4 = new ArrayRealVector(vec4); RealVector v4_2 = new ArrayRealVector(vec4); String out1 = v1.toString(); assertTrue("some output ", out1.length()!=0); /* double[] dout1 = v1.copyOut(); assertEquals("testData len", 3, dout1.length); assertNotSame("testData not same object ", v1.data, dout1); */ try { v1.checkVectorDimensions(2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { v1.checkVectorDimensions(v4); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } try { v1.checkVectorDimensions(v4_2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected behavior } } public void testPredicates() { ArrayRealVector v = new ArrayRealVector(new double[] { 0, 1, 2 }); assertFalse(v.isNaN()); v.setEntry(1, Double.NaN); assertTrue(v.isNaN()); assertFalse(v.isInfinite()); v.setEntry(0, Double.POSITIVE_INFINITY); assertFalse(v.isInfinite()); v.setEntry(1, 1); assertTrue(v.isInfinite()); v.setEntry(0, 1); assertFalse(v.isInfinite()); v.setEntry(0, 0); assertEquals(v, new ArrayRealVector(new double[] { 0, 1, 2 })); assertNotSame(v, new ArrayRealVector(new double[] { 0, 1, 2 + FastMath.ulp(2)})); assertNotSame(v, new ArrayRealVector(new double[] { 0, 1, 2, 3 })); assertEquals(new ArrayRealVector(new double[] { Double.NaN, 1, 2 }).hashCode(), new ArrayRealVector(new double[] { 0, Double.NaN, 2 }).hashCode()); assertTrue(new ArrayRealVector(new double[] { Double.NaN, 1, 2 }).hashCode() != new ArrayRealVector(new double[] { 0, 1, 2 }).hashCode()); assertTrue(v.equals(v)); assertTrue(v.equals(v.copy())); assertFalse(v.equals(null)); assertFalse(v.equals(v.getDataRef())); assertFalse(v.equals(v.getSubVector(0, v.getDimension() - 1))); assertTrue(v.equals(v.getSubVector(0, v.getDimension()))); } public void testSerial() { ArrayRealVector v = new ArrayRealVector(new double[] { 0, 1, 2 }); assertEquals(v,TestUtils.serializeAndRecover(v)); } public void testZeroVectors() { assertEquals(0, new ArrayRealVector(new double[0]).getDimension()); assertEquals(0, new ArrayRealVector(new double[0], true).getDimension()); assertEquals(0, new ArrayRealVector(new double[0], false).getDimension()); } public void testMinMax() { ArrayRealVector v1 = new ArrayRealVector(new double[] { 0, -6, 4, 12, 7 }); assertEquals(1, v1.getMinIndex()); assertEquals(-6, v1.getMinValue(), 1.0e-12); assertEquals(3, v1.getMaxIndex()); assertEquals(12, v1.getMaxValue(), 1.0e-12); ArrayRealVector v2 = new ArrayRealVector(new double[] { Double.NaN, 3, Double.NaN, -2 }); assertEquals(3, v2.getMinIndex()); assertEquals(-2, v2.getMinValue(), 1.0e-12); assertEquals(1, v2.getMaxIndex()); assertEquals(3, v2.getMaxValue(), 1.0e-12); ArrayRealVector v3 = new ArrayRealVector(new double[] { Double.NaN, Double.NaN }); assertEquals(-1, v3.getMinIndex()); assertTrue(Double.isNaN(v3.getMinValue())); assertEquals(-1, v3.getMaxIndex()); assertTrue(Double.isNaN(v3.getMaxValue())); ArrayRealVector v4 = new ArrayRealVector(new double[0]); assertEquals(-1, v4.getMinIndex()); assertTrue(Double.isNaN(v4.getMinValue())); assertEquals(-1, v4.getMaxIndex()); assertTrue(Double.isNaN(v4.getMaxValue())); } /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, double[] m, double[] n, double tolerance) { if (m.length != n.length) { fail("vectors have different lengths"); } for (int i = 0; i < m.length; i++) { assertEquals(msg + " " + i + " elements differ", m[i],n[i],tolerance); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java100644 1750 1750 13430 11532241243 31347 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.junit.Assert; import org.junit.Test; public class SingularValueSolverTest { private double[][] testSquare = { { 24.0 / 25.0, 43.0 / 25.0 }, { 57.0 / 25.0, 24.0 / 25.0 } }; private static final double normTolerance = 10e-14; /** test solve dimension errors */ @Test public void testSolveDimensionErrors() { DecompositionSolver solver = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[3][2]); try { solver.solve(b); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(b.getColumn(0)); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } } /** test least square solve */ @Test public void testLeastSquareSolve() { RealMatrix m = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 0.0 }, { 0.0, 0.0 } }); DecompositionSolver solver = new SingularValueDecompositionImpl(m).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { 11, 12 }, { 21, 22 } }); RealMatrix xMatrix = solver.solve(b); Assert.assertEquals(11, xMatrix.getEntry(0, 0), 1.0e-15); Assert.assertEquals(12, xMatrix.getEntry(0, 1), 1.0e-15); Assert.assertEquals(0, xMatrix.getEntry(1, 0), 1.0e-15); Assert.assertEquals(0, xMatrix.getEntry(1, 1), 1.0e-15); double[] xCol = solver.solve(b.getColumn(0)); Assert.assertEquals(11, xCol[0], 1.0e-15); Assert.assertEquals(0, xCol[1], 1.0e-15); RealVector xColVec = solver.solve(b.getColumnVector(0)); Assert.assertEquals(11, xColVec.getEntry(0), 1.0e-15); Assert.assertEquals(0, xColVec.getEntry(1), 1.0e-15); RealVector xColOtherVec = solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); Assert.assertEquals(11, xColOtherVec.getEntry(0), 1.0e-15); Assert.assertEquals(0, xColOtherVec.getEntry(1), 1.0e-15); } /** test solve */ @Test public void testSolve() { DecompositionSolver solver = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { 1, 2, 3 }, { 0, -5, 1 } }); RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] { { -8.0 / 25.0, -263.0 / 75.0, -29.0 / 75.0 }, { 19.0 / 25.0, 78.0 / 25.0, 49.0 / 25.0 } }); // using RealMatrix Assert.assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), normTolerance); // using double[] for (int i = 0; i < b.getColumnDimension(); ++i) { Assert.assertEquals(0, new ArrayRealVector(solver.solve(b.getColumn(i))).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using Array2DRowRealMatrix for (int i = 0; i < b.getColumnDimension(); ++i) { Assert.assertEquals(0, solver.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } // using RealMatrix with an alternate implementation for (int i = 0; i < b.getColumnDimension(); ++i) { ArrayRealVectorTest.RealVectorTestImpl v = new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i)); Assert.assertEquals(0, solver.solve(v).subtract(xRef.getColumnVector(i)).getNorm(), 1.0e-13); } } /** test condition number */ @Test public void testConditionNumber() { SingularValueDecompositionImpl svd = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)); // replace 1.0e-15 with 1.5e-15 Assert.assertEquals(3.0, svd.getConditionNumber(), 1.5e-15); } @Test public void testMath320B() { RealMatrix rm = new Array2DRowRealMatrix(new double[][] { { 1.0, 2.0 }, { 1.0, 2.0 } }); SingularValueDecomposition svd = new SingularValueDecompositionImpl(rm); RealMatrix recomposed = svd.getU().multiply(svd.getS()).multiply(svd.getVT()); Assert.assertEquals(0.0, recomposed.subtract(rm).getNorm(), 2.0e-15); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/LUDecompositionImplTest.java100644 1750 1750 24253 11532241243 31277 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import junit.framework.TestCase; public class LUDecompositionImplTest extends TestCase { private double[][] testData = { { 1.0, 2.0, 3.0}, { 2.0, 5.0, 3.0}, { 1.0, 0.0, 8.0} }; private double[][] testDataMinus = { { -1.0, -2.0, -3.0}, { -2.0, -5.0, -3.0}, { -1.0, 0.0, -8.0} }; private double[][] luData = { { 2.0, 3.0, 3.0 }, { 0.0, 5.0, 7.0 }, { 6.0, 9.0, 8.0 } }; // singular matrices private double[][] singular = { { 2.0, 3.0 }, { 2.0, 3.0 } }; private double[][] bigSingular = { { 1.0, 2.0, 3.0, 4.0 }, { 2.0, 5.0, 3.0, 4.0 }, { 7.0, 3.0, 256.0, 1930.0 }, { 3.0, 7.0, 6.0, 8.0 } }; // 4th row = 1st + 2nd private static final double entryTolerance = 10e-16; private static final double normTolerance = 10e-14; public LUDecompositionImplTest(String name) { super(name); } /** test dimensions */ public void testDimensions() { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); LUDecomposition LU = new LUDecompositionImpl(matrix); assertEquals(testData.length, LU.getL().getRowDimension()); assertEquals(testData.length, LU.getL().getColumnDimension()); assertEquals(testData.length, LU.getU().getRowDimension()); assertEquals(testData.length, LU.getU().getColumnDimension()); assertEquals(testData.length, LU.getP().getRowDimension()); assertEquals(testData.length, LU.getP().getColumnDimension()); } /** test non-square matrix */ public void testNonSquare() { try { new LUDecompositionImpl(MatrixUtils.createRealMatrix(new double[3][2])); fail("Expecting InvalidMatrixException"); } catch (InvalidMatrixException ime) { // expected behavior } } /** test PA = LU */ public void testPAEqualLU() { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); LUDecomposition lu = new LUDecompositionImpl(matrix); RealMatrix l = lu.getL(); RealMatrix u = lu.getU(); RealMatrix p = lu.getP(); double norm = l.multiply(u).subtract(p.multiply(matrix)).getNorm(); assertEquals(0, norm, normTolerance); matrix = MatrixUtils.createRealMatrix(testDataMinus); lu = new LUDecompositionImpl(matrix); l = lu.getL(); u = lu.getU(); p = lu.getP(); norm = l.multiply(u).subtract(p.multiply(matrix)).getNorm(); assertEquals(0, norm, normTolerance); matrix = MatrixUtils.createRealIdentityMatrix(17); lu = new LUDecompositionImpl(matrix); l = lu.getL(); u = lu.getU(); p = lu.getP(); norm = l.multiply(u).subtract(p.multiply(matrix)).getNorm(); assertEquals(0, norm, normTolerance); matrix = MatrixUtils.createRealMatrix(singular); lu = new LUDecompositionImpl(matrix); assertFalse(lu.getSolver().isNonSingular()); assertNull(lu.getL()); assertNull(lu.getU()); assertNull(lu.getP()); matrix = MatrixUtils.createRealMatrix(bigSingular); lu = new LUDecompositionImpl(matrix); assertFalse(lu.getSolver().isNonSingular()); assertNull(lu.getL()); assertNull(lu.getU()); assertNull(lu.getP()); } /** test that L is lower triangular with unit diagonal */ public void testLLowerTriangular() { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); RealMatrix l = new LUDecompositionImpl(matrix).getL(); for (int i = 0; i < l.getRowDimension(); i++) { assertEquals(l.getEntry(i, i), 1, entryTolerance); for (int j = i + 1; j < l.getColumnDimension(); j++) { assertEquals(l.getEntry(i, j), 0, entryTolerance); } } } /** test that U is upper triangular */ public void testUUpperTriangular() { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); RealMatrix u = new LUDecompositionImpl(matrix).getU(); for (int i = 0; i < u.getRowDimension(); i++) { for (int j = 0; j < i; j++) { assertEquals(u.getEntry(i, j), 0, entryTolerance); } } } /** test that P is a permutation matrix */ public void testPPermutation() { RealMatrix matrix = MatrixUtils.createRealMatrix(testData); RealMatrix p = new LUDecompositionImpl(matrix).getP(); RealMatrix ppT = p.multiply(p.transpose()); RealMatrix id = MatrixUtils.createRealIdentityMatrix(p.getRowDimension()); assertEquals(0, ppT.subtract(id).getNorm(), normTolerance); for (int i = 0; i < p.getRowDimension(); i++) { int zeroCount = 0; int oneCount = 0; int otherCount = 0; for (int j = 0; j < p.getColumnDimension(); j++) { final double e = p.getEntry(i, j); if (e == 0) { ++zeroCount; } else if (e == 1) { ++oneCount; } else { ++otherCount; } } assertEquals(p.getColumnDimension() - 1, zeroCount); assertEquals(1, oneCount); assertEquals(0, otherCount); } for (int j = 0; j < p.getColumnDimension(); j++) { int zeroCount = 0; int oneCount = 0; int otherCount = 0; for (int i = 0; i < p.getRowDimension(); i++) { final double e = p.getEntry(i, j); if (e == 0) { ++zeroCount; } else if (e == 1) { ++oneCount; } else { ++otherCount; } } assertEquals(p.getRowDimension() - 1, zeroCount); assertEquals(1, oneCount); assertEquals(0, otherCount); } } /** test singular */ public void testSingular() { LUDecomposition lu = new LUDecompositionImpl(MatrixUtils.createRealMatrix(testData)); assertTrue(lu.getSolver().isNonSingular()); lu = new LUDecompositionImpl(MatrixUtils.createRealMatrix(singular)); assertFalse(lu.getSolver().isNonSingular()); lu = new LUDecompositionImpl(MatrixUtils.createRealMatrix(bigSingular)); assertFalse(lu.getSolver().isNonSingular()); } /** test matrices values */ public void testMatricesValues1() { LUDecomposition lu = new LUDecompositionImpl(MatrixUtils.createRealMatrix(testData)); RealMatrix lRef = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 0.0, 0.0 }, { 0.5, 1.0, 0.0 }, { 0.5, 0.2, 1.0 } }); RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { 2.0, 5.0, 3.0 }, { 0.0, -2.5, 6.5 }, { 0.0, 0.0, 0.2 } }); RealMatrix pRef = MatrixUtils.createRealMatrix(new double[][] { { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 1.0, 0.0, 0.0 } }); int[] pivotRef = { 1, 2, 0 }; // check values against known references RealMatrix l = lu.getL(); assertEquals(0, l.subtract(lRef).getNorm(), 1.0e-13); RealMatrix u = lu.getU(); assertEquals(0, u.subtract(uRef).getNorm(), 1.0e-13); RealMatrix p = lu.getP(); assertEquals(0, p.subtract(pRef).getNorm(), 1.0e-13); int[] pivot = lu.getPivot(); for (int i = 0; i < pivotRef.length; ++i) { assertEquals(pivotRef[i], pivot[i]); } // check the same cached instance is returned the second time assertTrue(l == lu.getL()); assertTrue(u == lu.getU()); assertTrue(p == lu.getP()); } /** test matrices values */ public void testMatricesValues2() { LUDecomposition lu = new LUDecompositionImpl(MatrixUtils.createRealMatrix(luData)); RealMatrix lRef = MatrixUtils.createRealMatrix(new double[][] { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 1.0 / 3.0, 0.0, 1.0 } }); RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { 6.0, 9.0, 8.0 }, { 0.0, 5.0, 7.0 }, { 0.0, 0.0, 1.0 / 3.0 } }); RealMatrix pRef = MatrixUtils.createRealMatrix(new double[][] { { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 } }); int[] pivotRef = { 2, 1, 0 }; // check values against known references RealMatrix l = lu.getL(); assertEquals(0, l.subtract(lRef).getNorm(), 1.0e-13); RealMatrix u = lu.getU(); assertEquals(0, u.subtract(uRef).getNorm(), 1.0e-13); RealMatrix p = lu.getP(); assertEquals(0, p.subtract(pRef).getNorm(), 1.0e-13); int[] pivot = lu.getPivot(); for (int i = 0; i < pivotRef.length; ++i) { assertEquals(pivotRef[i], pivot[i]); } // check the same cached instance is returned the second time assertTrue(l == lu.getL()); assertTrue(u == lu.getU()); assertTrue(p == lu.getP()); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SingularValueDecompositionImplTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/linear/SingularValueDecompositionImplTest100644 1750 1750 25277 11532241243 32627 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Random; import junit.framework.TestCase; public class SingularValueDecompositionImplTest extends TestCase { private double[][] testSquare = { { 24.0 / 25.0, 43.0 / 25.0 }, { 57.0 / 25.0, 24.0 / 25.0 } }; private double[][] testNonSquare = { { -540.0 / 625.0, 963.0 / 625.0, -216.0 / 625.0 }, { -1730.0 / 625.0, -744.0 / 625.0, 1008.0 / 625.0 }, { -720.0 / 625.0, 1284.0 / 625.0, -288.0 / 625.0 }, { -360.0 / 625.0, 192.0 / 625.0, 1756.0 / 625.0 }, }; private static final double normTolerance = 10e-14; public SingularValueDecompositionImplTest(String name) { super(name); } public void testMoreRows() { final double[] singularValues = { 123.456, 2.3, 1.001, 0.999 }; final int rows = singularValues.length + 2; final int columns = singularValues.length; Random r = new Random(15338437322523l); SingularValueDecomposition svd = new SingularValueDecompositionImpl(createTestMatrix(r, rows, columns, singularValues)); double[] computedSV = svd.getSingularValues(); assertEquals(singularValues.length, computedSV.length); for (int i = 0; i < singularValues.length; ++i) { assertEquals(singularValues[i], computedSV[i], 1.0e-10); } } public void testMoreColumns() { final double[] singularValues = { 123.456, 2.3, 1.001, 0.999 }; final int rows = singularValues.length; final int columns = singularValues.length + 2; Random r = new Random(732763225836210l); SingularValueDecomposition svd = new SingularValueDecompositionImpl(createTestMatrix(r, rows, columns, singularValues)); double[] computedSV = svd.getSingularValues(); assertEquals(singularValues.length, computedSV.length); for (int i = 0; i < singularValues.length; ++i) { assertEquals(singularValues[i], computedSV[i], 1.0e-10); } } /** test dimensions */ public void testDimensions() { RealMatrix matrix = MatrixUtils.createRealMatrix(testSquare); final int m = matrix.getRowDimension(); final int n = matrix.getColumnDimension(); SingularValueDecomposition svd = new SingularValueDecompositionImpl(matrix); assertEquals(m, svd.getU().getRowDimension()); assertEquals(m, svd.getU().getColumnDimension()); assertEquals(m, svd.getS().getColumnDimension()); assertEquals(n, svd.getS().getColumnDimension()); assertEquals(n, svd.getV().getRowDimension()); assertEquals(n, svd.getV().getColumnDimension()); } /** Test based on a dimension 4 Hadamard matrix. */ public void testHadamard() { RealMatrix matrix = new Array2DRowRealMatrix(new double[][] { {15.0 / 2.0, 5.0 / 2.0, 9.0 / 2.0, 3.0 / 2.0 }, { 5.0 / 2.0, 15.0 / 2.0, 3.0 / 2.0, 9.0 / 2.0 }, { 9.0 / 2.0, 3.0 / 2.0, 15.0 / 2.0, 5.0 / 2.0 }, { 3.0 / 2.0, 9.0 / 2.0, 5.0 / 2.0, 15.0 / 2.0 } }, false); SingularValueDecomposition svd = new SingularValueDecompositionImpl(matrix); assertEquals(16.0, svd.getSingularValues()[0], 1.0e-14); assertEquals( 8.0, svd.getSingularValues()[1], 1.0e-14); assertEquals( 4.0, svd.getSingularValues()[2], 1.0e-14); assertEquals( 2.0, svd.getSingularValues()[3], 1.0e-14); RealMatrix fullCovariance = new Array2DRowRealMatrix(new double[][] { { 85.0 / 1024, -51.0 / 1024, -75.0 / 1024, 45.0 / 1024 }, { -51.0 / 1024, 85.0 / 1024, 45.0 / 1024, -75.0 / 1024 }, { -75.0 / 1024, 45.0 / 1024, 85.0 / 1024, -51.0 / 1024 }, { 45.0 / 1024, -75.0 / 1024, -51.0 / 1024, 85.0 / 1024 } }, false); assertEquals(0.0, fullCovariance.subtract(svd.getCovariance(0.0)).getNorm(), 1.0e-14); RealMatrix halfCovariance = new Array2DRowRealMatrix(new double[][] { { 5.0 / 1024, -3.0 / 1024, 5.0 / 1024, -3.0 / 1024 }, { -3.0 / 1024, 5.0 / 1024, -3.0 / 1024, 5.0 / 1024 }, { 5.0 / 1024, -3.0 / 1024, 5.0 / 1024, -3.0 / 1024 }, { -3.0 / 1024, 5.0 / 1024, -3.0 / 1024, 5.0 / 1024 } }, false); assertEquals(0.0, halfCovariance.subtract(svd.getCovariance(6.0)).getNorm(), 1.0e-14); } /** test A = USVt */ public void testAEqualUSVt() { checkAEqualUSVt(MatrixUtils.createRealMatrix(testSquare)); checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare)); checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare).transpose()); } public void checkAEqualUSVt(final RealMatrix matrix) { SingularValueDecomposition svd = new SingularValueDecompositionImpl(matrix); RealMatrix u = svd.getU(); RealMatrix s = svd.getS(); RealMatrix v = svd.getV(); double norm = u.multiply(s).multiply(v.transpose()).subtract(matrix).getNorm(); assertEquals(0, norm, normTolerance); } /** test that U is orthogonal */ public void testUOrthogonal() { checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)).getU()); checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testNonSquare)).getU()); checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getU()); } /** test that V is orthogonal */ public void testVOrthogonal() { checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)).getV()); checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testNonSquare)).getV()); checkOrthogonal(new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getV()); } public void checkOrthogonal(final RealMatrix m) { RealMatrix mTm = m.transpose().multiply(m); RealMatrix id = MatrixUtils.createRealIdentityMatrix(mTm.getRowDimension()); assertEquals(0, mTm.subtract(id).getNorm(), normTolerance); } /** test matrices values */ public void testMatricesValues1() { SingularValueDecomposition svd = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)); RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { 3.0 / 5.0, -4.0 / 5.0 }, { 4.0 / 5.0, 3.0 / 5.0 } }); RealMatrix sRef = MatrixUtils.createRealMatrix(new double[][] { { 3.0, 0.0 }, { 0.0, 1.0 } }); RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] { { 4.0 / 5.0, 3.0 / 5.0 }, { 3.0 / 5.0, -4.0 / 5.0 } }); // check values against known references RealMatrix u = svd.getU(); assertEquals(0, u.subtract(uRef).getNorm(), normTolerance); RealMatrix s = svd.getS(); assertEquals(0, s.subtract(sRef).getNorm(), normTolerance); RealMatrix v = svd.getV(); assertEquals(0, v.subtract(vRef).getNorm(), normTolerance); // check the same cached instance is returned the second time assertTrue(u == svd.getU()); assertTrue(s == svd.getS()); assertTrue(v == svd.getV()); } /** test matrices values */ // This test is useless since whereas the columns of U and V are linked // together, the actual triplet (U,S,V) is not uniquely defined. public void useless_testMatricesValues2() { RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] { { 0.0 / 5.0, 3.0 / 5.0, 0.0 / 5.0 }, { -4.0 / 5.0, 0.0 / 5.0, -3.0 / 5.0 }, { 0.0 / 5.0, 4.0 / 5.0, 0.0 / 5.0 }, { -3.0 / 5.0, 0.0 / 5.0, 4.0 / 5.0 } }); RealMatrix sRef = MatrixUtils.createRealMatrix(new double[][] { { 4.0, 0.0, 0.0 }, { 0.0, 3.0, 0.0 }, { 0.0, 0.0, 2.0 } }); RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] { { 80.0 / 125.0, -60.0 / 125.0, 75.0 / 125.0 }, { 24.0 / 125.0, 107.0 / 125.0, 60.0 / 125.0 }, { -93.0 / 125.0, -24.0 / 125.0, 80.0 / 125.0 } }); // check values against known references SingularValueDecomposition svd = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testNonSquare)); RealMatrix u = svd.getU(); assertEquals(0, u.subtract(uRef).getNorm(), normTolerance); RealMatrix s = svd.getS(); assertEquals(0, s.subtract(sRef).getNorm(), normTolerance); RealMatrix v = svd.getV(); assertEquals(0, v.subtract(vRef).getNorm(), normTolerance); // check the same cached instance is returned the second time assertTrue(u == svd.getU()); assertTrue(s == svd.getS()); assertTrue(v == svd.getV()); } /** test condition number */ public void testConditionNumber() { SingularValueDecompositionImpl svd = new SingularValueDecompositionImpl(MatrixUtils.createRealMatrix(testSquare)); // replace 1.0e-15 with 1.5e-15 assertEquals(3.0, svd.getConditionNumber(), 1.5e-15); } private RealMatrix createTestMatrix(final Random r, final int rows, final int columns, final double[] singularValues) { final RealMatrix u = EigenDecompositionImplTest.createOrthogonalMatrix(r, rows); final RealMatrix d = EigenDecompositionImplTest.createDiagonalMatrix(singularValues, rows, columns); final RealMatrix v = EigenDecompositionImplTest.createOrthogonalMatrix(r, columns); return u.multiply(d).multiply(v); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/TriDiagonalTransformerTest.java100644 1750 1750 16130 11532241243 32013 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public class TriDiagonalTransformerTest extends TestCase { private double[][] testSquare5 = { { 1, 2, 3, 1, 1 }, { 2, 1, 1, 3, 1 }, { 3, 1, 1, 1, 2 }, { 1, 3, 1, 2, 1 }, { 1, 1, 2, 1, 3 } }; private double[][] testSquare3 = { { 1, 3, 4 }, { 3, 2, 2 }, { 4, 2, 0 } }; public TriDiagonalTransformerTest(String name) { super(name); } public void testNonSquare() { try { new TriDiagonalTransformer(MatrixUtils.createRealMatrix(new double[3][2])); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } } public void testAEqualQTQt() { checkAEqualQTQt(MatrixUtils.createRealMatrix(testSquare5)); checkAEqualQTQt(MatrixUtils.createRealMatrix(testSquare3)); } private void checkAEqualQTQt(RealMatrix matrix) { TriDiagonalTransformer transformer = new TriDiagonalTransformer(matrix); RealMatrix q = transformer.getQ(); RealMatrix qT = transformer.getQT(); RealMatrix t = transformer.getT(); double norm = q.multiply(t).multiply(qT).subtract(matrix).getNorm(); assertEquals(0, norm, 4.0e-15); } public void testNoAccessBelowDiagonal() { checkNoAccessBelowDiagonal(testSquare5); checkNoAccessBelowDiagonal(testSquare3); } private void checkNoAccessBelowDiagonal(double[][] data) { double[][] modifiedData = new double[data.length][]; for (int i = 0; i < data.length; ++i) { modifiedData[i] = data[i].clone(); Arrays.fill(modifiedData[i], 0, i, Double.NaN); } RealMatrix matrix = MatrixUtils.createRealMatrix(modifiedData); TriDiagonalTransformer transformer = new TriDiagonalTransformer(matrix); RealMatrix q = transformer.getQ(); RealMatrix qT = transformer.getQT(); RealMatrix t = transformer.getT(); double norm = q.multiply(t).multiply(qT).subtract(MatrixUtils.createRealMatrix(data)).getNorm(); assertEquals(0, norm, 4.0e-15); } public void testQOrthogonal() { checkOrthogonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare5)).getQ()); checkOrthogonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare3)).getQ()); } public void testQTOrthogonal() { checkOrthogonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare5)).getQT()); checkOrthogonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare3)).getQT()); } private void checkOrthogonal(RealMatrix m) { RealMatrix mTm = m.transpose().multiply(m); RealMatrix id = MatrixUtils.createRealIdentityMatrix(mTm.getRowDimension()); assertEquals(0, mTm.subtract(id).getNorm(), 1.0e-15); } public void testTTriDiagonal() { checkTriDiagonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare5)).getT()); checkTriDiagonal(new TriDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare3)).getT()); } private void checkTriDiagonal(RealMatrix m) { final int rows = m.getRowDimension(); final int cols = m.getColumnDimension(); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { if ((i < j - 1) || (i > j + 1)) { assertEquals(0, m.getEntry(i, j), 1.0e-16); } } } } public void testMatricesValues5() { checkMatricesValues(testSquare5, new double[][] { { 1.0, 0.0, 0.0, 0.0, 0.0 }, { 0.0, -0.5163977794943222, 0.016748280772542083, 0.839800693771262, 0.16669620021405473 }, { 0.0, -0.7745966692414833, -0.4354553000860955, -0.44989322880603355, -0.08930153582895772 }, { 0.0, -0.2581988897471611, 0.6364346693566014, -0.30263204032131164, 0.6608313651342882 }, { 0.0, -0.2581988897471611, 0.6364346693566009, -0.027289660803112598, -0.7263191580755246 } }, new double[] { 1, 4.4, 1.433099579242636, -0.89537362758743, 2.062274048344794 }, new double[] { -FastMath.sqrt(15), -3.0832882879592476, 0.6082710842351517, 1.1786086405912128 }); } public void testMatricesValues3() { checkMatricesValues(testSquare3, new double[][] { { 1.0, 0.0, 0.0 }, { 0.0, -0.6, 0.8 }, { 0.0, -0.8, -0.6 }, }, new double[] { 1, 2.64, -0.64 }, new double[] { -5, -1.52 }); } private void checkMatricesValues(double[][] matrix, double[][] qRef, double[] mainDiagnonal, double[] secondaryDiagonal) { TriDiagonalTransformer transformer = new TriDiagonalTransformer(MatrixUtils.createRealMatrix(matrix)); // check values against known references RealMatrix q = transformer.getQ(); assertEquals(0, q.subtract(MatrixUtils.createRealMatrix(qRef)).getNorm(), 1.0e-14); RealMatrix t = transformer.getT(); double[][] tData = new double[mainDiagnonal.length][mainDiagnonal.length]; for (int i = 0; i < mainDiagnonal.length; ++i) { tData[i][i] = mainDiagnonal[i]; if (i > 0) { tData[i][i - 1] = secondaryDiagonal[i - 1]; } if (i < secondaryDiagonal.length) { tData[i][i + 1] = secondaryDiagonal[i]; } } assertEquals(0, t.subtract(MatrixUtils.createRealMatrix(tData)).getNorm(), 1.0e-14); // check the same cached instance is returned the second time assertTrue(q == transformer.getQ()); assertTrue(t == transformer.getT()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/BigMatrixImplTest.java100644 1750 1750 76777 11532241243 30132 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.math.BigDecimal; import junit.framework.TestCase; /** * Test cases for the {@link BigMatrixImpl} class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ @Deprecated public final class BigMatrixImplTest extends TestCase { // Test data for String constructors protected String[][] testDataString = { {"1","2","3"}, {"2","5","3"}, {"1","0","8"} }; // 3 x 3 identity matrix protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} }; // Test data for group operations protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} }; protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}}; protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} }; protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d}, {-1d,0d,-8d} }; protected double[] testDataRow1 = {1d,2d,3d}; protected double[] testDataCol3 = {3d,3d,8d}; protected double[][] testDataInv = { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} }; protected double[] preMultTest = {8,12,33}; protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}}; protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}}; protected double[][] testDataPlusInv = { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} }; // lu decomposition tests protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} }; protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d}, {0.33333333333333,0d,0.33333333333333} }; // singular matrices protected double[][] singular = { {2d,3d}, {2d,3d} }; protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d}, {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} }; protected double[][] detData2 = { {1d, 3d}, {2d, 4d}}; // vectors protected double[] testVector = {1,2,3}; protected double[] testVector2 = {1,2,3,4}; // submatrix accessor tests protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5}, {2, 4, 6, 8}, {4, 5, 6, 7}}; // array selections protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}}; protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}}; protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}}; // effective permutations protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}}; protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}}; // contiguous ranges protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}}; protected double[][] subRows23Cols00 = {{2} , {4}}; protected double[][] subRows00Cols33 = {{4}}; // row matrices protected double[][] subRow0 = {{1,2,3,4}}; protected double[][] subRow3 = {{4,5,6,7}}; // column matrices protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}}; protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}}; // tolerances protected double entryTolerance = 10E-16; protected double normTolerance = 10E-14; public BigMatrixImplTest(String name) { super(name); } public static final double[] asDouble(BigDecimal[] data) { double d[] = new double[data.length]; for (int i=0;i",new RealVectorFormat().parse(source, pos)); assertEquals(0, pos.getErrorIndex()); } public void testForgottenSeparator() { ParsePosition pos = new ParsePosition(0); final String source = "{1; 1 1}"; assertNull("Should not parse <"+source+">",new RealVectorFormat().parse(source, pos)); assertEquals(6, pos.getErrorIndex()); } public void testForgottenSuffix() { ParsePosition pos = new ParsePosition(0); final String source = "{1; 1; 1 "; assertNull("Should not parse <"+source+">",new RealVectorFormat().parse(source, pos)); assertEquals(8, pos.getErrorIndex()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/FrenchRealVectorFormatTest.java100644 1750 1750 2143 11532241243 31717 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Locale; public class FrenchRealVectorFormatTest extends RealVectorFormatAbstractTest { @Override protected char getDecimalCharacter() { return ','; } @Override protected Locale getLocale() { return Locale.FRENCH; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/MatrixUtilsTest.java100644 1750 1750 37001 11532241243 27660 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.math.BigDecimal; import junit.framework.TestCase; import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionConversionException; import org.apache.commons.math.fraction.FractionField; /** * Test cases for the {@link MatrixUtils} class. * * @version $Revision: 1003899 $ $Date: 2010-10-03 00:06:55 +0200 (dim. 03 oct. 2010) $ */ public final class MatrixUtilsTest extends TestCase { protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} }; protected double[][] nullMatrix = null; protected double[] row = {1,2,3}; protected BigDecimal[] bigRow = {new BigDecimal(1),new BigDecimal(2),new BigDecimal(3)}; protected String[] stringRow = {"1", "2", "3"}; protected Fraction[] fractionRow = {new Fraction(1),new Fraction(2),new Fraction(3)}; protected double[][] rowMatrix = {{1,2,3}}; protected BigDecimal[][] bigRowMatrix = {{new BigDecimal(1), new BigDecimal(2), new BigDecimal(3)}}; protected String[][] stringRowMatrix = {{"1", "2", "3"}}; protected Fraction[][] fractionRowMatrix = {{new Fraction(1), new Fraction(2), new Fraction(3)}}; protected double[] col = {0,4,6}; protected BigDecimal[] bigCol = {new BigDecimal(0),new BigDecimal(4),new BigDecimal(6)}; protected String[] stringCol = {"0","4","6"}; protected Fraction[] fractionCol = {new Fraction(0),new Fraction(4),new Fraction(6)}; protected double[] nullDoubleArray = null; protected double[][] colMatrix = {{0},{4},{6}}; protected BigDecimal[][] bigColMatrix = {{new BigDecimal(0)},{new BigDecimal(4)},{new BigDecimal(6)}}; protected String[][] stringColMatrix = {{"0"}, {"4"}, {"6"}}; protected Fraction[][] fractionColMatrix = {{new Fraction(0)},{new Fraction(4)},{new Fraction(6)}}; public MatrixUtilsTest(String name) { super(name); } public void testCreateRealMatrix() { assertEquals(new BlockRealMatrix(testData), MatrixUtils.createRealMatrix(testData)); try { MatrixUtils.createRealMatrix(new double[][] {{1}, {1,2}}); // ragged fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createRealMatrix(new double[][] {{}, {}}); // no columns fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createRealMatrix(null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testcreateFieldMatrix() { assertEquals(new Array2DRowFieldMatrix(asFraction(testData)), MatrixUtils.createFieldMatrix(asFraction(testData))); assertEquals(new Array2DRowFieldMatrix(fractionColMatrix), MatrixUtils.createFieldMatrix(fractionColMatrix)); try { MatrixUtils.createFieldMatrix(asFraction(new double[][] {{1}, {1,2}})); // ragged fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createFieldMatrix(asFraction(new double[][] {{}, {}})); // no columns fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createFieldMatrix((Fraction[][])null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } @Deprecated public void testCreateBigMatrix() { assertEquals(new BigMatrixImpl(testData), MatrixUtils.createBigMatrix(testData)); assertEquals(new BigMatrixImpl(BigMatrixImplTest.asBigDecimal(testData), true), MatrixUtils.createBigMatrix(BigMatrixImplTest.asBigDecimal(testData), false)); assertEquals(new BigMatrixImpl(BigMatrixImplTest.asBigDecimal(testData), false), MatrixUtils.createBigMatrix(BigMatrixImplTest.asBigDecimal(testData), true)); assertEquals(new BigMatrixImpl(bigColMatrix), MatrixUtils.createBigMatrix(bigColMatrix)); assertEquals(new BigMatrixImpl(stringColMatrix), MatrixUtils.createBigMatrix(stringColMatrix)); try { MatrixUtils.createBigMatrix(new double[][] {{1}, {1,2}}); // ragged fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createBigMatrix(new double[][] {{}, {}}); // no columns fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createBigMatrix(nullMatrix); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testCreateRowRealMatrix() { assertEquals(MatrixUtils.createRowRealMatrix(row), new BlockRealMatrix(rowMatrix)); try { MatrixUtils.createRowRealMatrix(new double[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createRowRealMatrix(null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testCreateRowFieldMatrix() { assertEquals(MatrixUtils.createRowFieldMatrix(asFraction(row)), new Array2DRowFieldMatrix(asFraction(rowMatrix))); assertEquals(MatrixUtils.createRowFieldMatrix(fractionRow), new Array2DRowFieldMatrix(fractionRowMatrix)); try { MatrixUtils.createRowFieldMatrix(new Fraction[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createRowFieldMatrix((Fraction[]) null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } @Deprecated public void testCreateRowBigMatrix() { assertEquals(MatrixUtils.createRowBigMatrix(row), new BigMatrixImpl(rowMatrix)); assertEquals(MatrixUtils.createRowBigMatrix(bigRow), new BigMatrixImpl(bigRowMatrix)); assertEquals(MatrixUtils.createRowBigMatrix(stringRow), new BigMatrixImpl(stringRowMatrix)); try { MatrixUtils.createRowBigMatrix(new double[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createRowBigMatrix(nullDoubleArray); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testCreateColumnRealMatrix() { assertEquals(MatrixUtils.createColumnRealMatrix(col), new BlockRealMatrix(colMatrix)); try { MatrixUtils.createColumnRealMatrix(new double[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createColumnRealMatrix(null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testCreateColumnFieldMatrix() { assertEquals(MatrixUtils.createColumnFieldMatrix(asFraction(col)), new Array2DRowFieldMatrix(asFraction(colMatrix))); assertEquals(MatrixUtils.createColumnFieldMatrix(fractionCol), new Array2DRowFieldMatrix(fractionColMatrix)); try { MatrixUtils.createColumnFieldMatrix(new Fraction[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createColumnFieldMatrix((Fraction[]) null); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } @Deprecated public void testCreateColumnBigMatrix() { assertEquals(MatrixUtils.createColumnBigMatrix(col), new BigMatrixImpl(colMatrix)); assertEquals(MatrixUtils.createColumnBigMatrix(bigCol), new BigMatrixImpl(bigColMatrix)); assertEquals(MatrixUtils.createColumnBigMatrix(stringCol), new BigMatrixImpl(stringColMatrix)); try { MatrixUtils.createColumnBigMatrix(new double[] {}); // empty fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { MatrixUtils.createColumnBigMatrix(nullDoubleArray); // null fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } /** * Verifies that the matrix is an identity matrix */ protected void checkIdentityMatrix(RealMatrix m) { for (int i = 0; i < m.getRowDimension(); i++) { for (int j =0; j < m.getColumnDimension(); j++) { if (i == j) { assertEquals(m.getEntry(i, j), 1d, 0); } else { assertEquals(m.getEntry(i, j), 0d, 0); } } } } public void testCreateIdentityMatrix() { checkIdentityMatrix(MatrixUtils.createRealIdentityMatrix(3)); checkIdentityMatrix(MatrixUtils.createRealIdentityMatrix(2)); checkIdentityMatrix(MatrixUtils.createRealIdentityMatrix(1)); try { MatrixUtils.createRealIdentityMatrix(0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } /** * Verifies that the matrix is an identity matrix */ protected void checkIdentityFieldMatrix(FieldMatrix m) { for (int i = 0; i < m.getRowDimension(); i++) { for (int j =0; j < m.getColumnDimension(); j++) { if (i == j) { assertEquals(m.getEntry(i, j), Fraction.ONE); } else { assertEquals(m.getEntry(i, j), Fraction.ZERO); } } } } public void testcreateFieldIdentityMatrix() { checkIdentityFieldMatrix(MatrixUtils.createFieldIdentityMatrix(FractionField.getInstance(), 3)); checkIdentityFieldMatrix(MatrixUtils.createFieldIdentityMatrix(FractionField.getInstance(), 2)); checkIdentityFieldMatrix(MatrixUtils.createFieldIdentityMatrix(FractionField.getInstance(), 1)); try { MatrixUtils.createRealIdentityMatrix(0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testBigFractionConverter() { BigFraction[][] bfData = { { new BigFraction(1), new BigFraction(2), new BigFraction(3) }, { new BigFraction(2), new BigFraction(5), new BigFraction(3) }, { new BigFraction(1), new BigFraction(0), new BigFraction(8) } }; FieldMatrix m = new Array2DRowFieldMatrix(bfData, false); RealMatrix converted = MatrixUtils.bigFractionMatrixToRealMatrix(m); RealMatrix reference = new Array2DRowRealMatrix(testData, false); assertEquals(0.0, converted.subtract(reference).getNorm(), 0.0); } public void testFractionConverter() { Fraction[][] fData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) }, { new Fraction(1), new Fraction(0), new Fraction(8) } }; FieldMatrix m = new Array2DRowFieldMatrix(fData, false); RealMatrix converted = MatrixUtils.fractionMatrixToRealMatrix(m); RealMatrix reference = new Array2DRowRealMatrix(testData, false); assertEquals(0.0, converted.subtract(reference).getNorm(), 0.0); } public static final Fraction[][] asFraction(double[][] data) { Fraction d[][] = new Fraction[data.length][]; try { for (int i = 0; i < data.length; ++i) { double[] dataI = data[i]; Fraction[] dI = new Fraction[dataI.length]; for (int j = 0; j < dataI.length; ++j) { dI[j] = new Fraction(dataI[j]); } d[i] = dI; } } catch (FractionConversionException fce) { fail(fce.getMessage()); } return d; } public static final Fraction[] asFraction(double[] data) { Fraction d[] = new Fraction[data.length]; try { for (int i = 0; i < data.length; ++i) { d[i] = new Fraction(data[i]); } } catch (FractionConversionException fce) { fail(fce.getMessage()); } return d; } /** * Verifies that the matrix is an identity matrix */ @Deprecated protected void checkIdentityBigMatrix(BigMatrix m) { for (int i = 0; i < m.getRowDimension(); i++) { for (int j =0; j < m.getColumnDimension(); j++) { if (i == j) { assertEquals(m.getEntry(i, j), BigMatrixImpl.ONE); } else { assertEquals(m.getEntry(i, j), BigMatrixImpl.ZERO); } } } } @Deprecated public void testCreateBigIdentityMatrix() { checkIdentityBigMatrix(MatrixUtils.createBigIdentityMatrix(3)); checkIdentityBigMatrix(MatrixUtils.createBigIdentityMatrix(2)); checkIdentityBigMatrix(MatrixUtils.createBigIdentityMatrix(1)); try { MatrixUtils.createRealIdentityMatrix(0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java100644 1750 1750 13164 11532241243 27621 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Random; import junit.framework.TestCase; import org.apache.commons.math.util.MathUtils; public class EigenSolverTest extends TestCase { private double[] refValues; private RealMatrix matrix; public EigenSolverTest(String name) { super(name); } /** test non invertible matrix */ public void testNonInvertible() { Random r = new Random(9994100315209l); RealMatrix m = EigenDecompositionImplTest.createTestMatrix(r, new double[] { 1.0, 0.0, -1.0, -2.0, -3.0 }); DecompositionSolver es = new EigenDecompositionImpl(m, MathUtils.SAFE_MIN).getSolver(); assertFalse(es.isNonSingular()); try { es.getInverse(); fail("an exception should have been thrown"); } catch (InvalidMatrixException ime) { // expected behavior } } /** test invertible matrix */ public void testInvertible() { Random r = new Random(9994100315209l); RealMatrix m = EigenDecompositionImplTest.createTestMatrix(r, new double[] { 1.0, 0.5, -1.0, -2.0, -3.0 }); DecompositionSolver es = new EigenDecompositionImpl(m, MathUtils.SAFE_MIN).getSolver(); assertTrue(es.isNonSingular()); RealMatrix inverse = es.getInverse(); RealMatrix error = m.multiply(inverse).subtract(MatrixUtils.createRealIdentityMatrix(m.getRowDimension())); assertEquals(0, error.getNorm(), 4.0e-15); } /** test solve dimension errors */ public void testSolveDimensionErrors() { DecompositionSolver es = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]); try { es.solve(b); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { es.solve(b.getColumn(0)); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } try { es.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0))); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected behavior } } /** test solve */ public void testSolve() { RealMatrix m = MatrixUtils.createRealMatrix(new double[][] { { 91, 5, 29, 32, 40, 14 }, { 5, 34, -1, 0, 2, -1 }, { 29, -1, 12, 9, 21, 8 }, { 32, 0, 9, 14, 9, 0 }, { 40, 2, 21, 9, 51, 19 }, { 14, -1, 8, 0, 19, 14 } }); DecompositionSolver es = new EigenDecompositionImpl(m, MathUtils.SAFE_MIN).getSolver(); RealMatrix b = MatrixUtils.createRealMatrix(new double[][] { { 1561, 269, 188 }, { 69, -21, 70 }, { 739, 108, 63 }, { 324, 86, 59 }, { 1624, 194, 107 }, { 796, 69, 36 } }); RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] { { 1, 2, 1 }, { 2, -1, 2 }, { 4, 2, 3 }, { 8, -1, 0 }, { 16, 2, 0 }, { 32, -1, 0 } }); // using RealMatrix RealMatrix solution=es.solve(b); assertEquals(0, solution.subtract(xRef).getNorm(), 2.5e-12); // using double[] for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, new ArrayRealVector(es.solve(b.getColumn(i))).subtract(xRef.getColumnVector(i)).getNorm(), 2.0e-11); } // using Array2DRowRealMatrix for (int i = 0; i < b.getColumnDimension(); ++i) { assertEquals(0, es.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(), 2.0e-11); } // using RealMatrix with an alternate implementation for (int i = 0; i < b.getColumnDimension(); ++i) { ArrayRealVectorTest.RealVectorTestImpl v = new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i)); assertEquals(0, es.solve(v).subtract(xRef.getColumnVector(i)).getNorm(), 2.0e-11); } } @Override public void setUp() { refValues = new double[] { 2.003, 2.002, 2.001, 1.001, 1.000, 0.001 }; matrix = EigenDecompositionImplTest.createTestMatrix(new Random(35992629946426l), refValues); } @Override public void tearDown() { refValues = null; matrix = null; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java100644 1750 1750 56673 11532241243 32021 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import java.util.Random; import junit.framework.TestCase; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; public class EigenDecompositionImplTest extends TestCase { private double[] refValues; private RealMatrix matrix; public EigenDecompositionImplTest(String name) { super(name); } public void testDimension1() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 1.5 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(1.5, ed.getRealEigenvalue(0), 1.0e-15); } public void testDimension2() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 59.0, 12.0 }, { 12.0, 66.0 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(75.0, ed.getRealEigenvalue(0), 1.0e-15); assertEquals(50.0, ed.getRealEigenvalue(1), 1.0e-15); } public void testDimension3() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 39632.0, -4824.0, -16560.0 }, { -4824.0, 8693.0, 7920.0 }, { -16560.0, 7920.0, 17300.0 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(50000.0, ed.getRealEigenvalue(0), 3.0e-11); assertEquals(12500.0, ed.getRealEigenvalue(1), 3.0e-11); assertEquals( 3125.0, ed.getRealEigenvalue(2), 3.0e-11); } public void testDimension3MultipleRoot() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 5, 10, 15 }, { 10, 20, 30 }, { 15, 30, 45 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(70.0, ed.getRealEigenvalue(0), 3.0e-11); assertEquals(0.0, ed.getRealEigenvalue(1), 3.0e-11); assertEquals(0.0, ed.getRealEigenvalue(2), 3.0e-11); } public void testDimension4WithSplit() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 0.784, -0.288, 0.000, 0.000 }, { -0.288, 0.616, 0.000, 0.000 }, { 0.000, 0.000, 0.164, -0.048 }, { 0.000, 0.000, -0.048, 0.136 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(1.0, ed.getRealEigenvalue(0), 1.0e-15); assertEquals(0.4, ed.getRealEigenvalue(1), 1.0e-15); assertEquals(0.2, ed.getRealEigenvalue(2), 1.0e-15); assertEquals(0.1, ed.getRealEigenvalue(3), 1.0e-15); } public void testDimension4WithoutSplit() { RealMatrix matrix = MatrixUtils.createRealMatrix(new double[][] { { 0.5608, -0.2016, 0.1152, -0.2976 }, { -0.2016, 0.4432, -0.2304, 0.1152 }, { 0.1152, -0.2304, 0.3088, -0.1344 }, { -0.2976, 0.1152, -0.1344, 0.3872 } }); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(1.0, ed.getRealEigenvalue(0), 1.0e-15); assertEquals(0.4, ed.getRealEigenvalue(1), 1.0e-15); assertEquals(0.2, ed.getRealEigenvalue(2), 1.0e-15); assertEquals(0.1, ed.getRealEigenvalue(3), 1.0e-15); } // the following test triggered an ArrayIndexOutOfBoundsException in commons-math 2.0 public void testMath308() { double[] mainTridiagonal = { 22.330154644539597, 46.65485522478641, 17.393672330044705, 54.46687435351116, 80.17800767709437 }; double[] secondaryTridiagonal = { 13.04450406501361, -5.977590941539671, 2.9040909856707517, 7.1570352792841225 }; // the reference values have been computed using routine DSTEMR // from the fortran library LAPACK version 3.2.1 double[] refEigenValues = { 82.044413207204002, 53.456697699894512, 52.536278520113882, 18.847969733754262, 14.138204224043099 }; RealVector[] refEigenVectors = { new ArrayRealVector(new double[] { -0.000462690386766, -0.002118073109055, 0.011530080757413, 0.252322434584915, 0.967572088232592 }), new ArrayRealVector(new double[] { 0.314647769490148, 0.750806415553905, -0.167700312025760, -0.537092972407375, 0.143854968127780 }), new ArrayRealVector(new double[] { 0.222368839324646, 0.514921891363332, -0.021377019336614, 0.801196801016305, -0.207446991247740 }), new ArrayRealVector(new double[] { -0.713933751051495, 0.190582113553930, -0.671410443368332, 0.056056055955050, -0.006541576993581 }), new ArrayRealVector(new double[] { -0.584677060845929, 0.367177264979103, 0.721453187784497, -0.052971054621812, 0.005740715188257 }) }; EigenDecomposition decomposition = new EigenDecompositionImpl(mainTridiagonal, secondaryTridiagonal, MathUtils.SAFE_MIN); double[] eigenValues = decomposition.getRealEigenvalues(); for (int i = 0; i < refEigenValues.length; ++i) { assertEquals(refEigenValues[i], eigenValues[i], 1.0e-5); assertEquals(0, refEigenVectors[i].subtract(decomposition.getEigenvector(i)).getNorm(), 2.0e-7); } } public void testMathpbx02() { double[] mainTridiagonal = { 7484.860960227216, 18405.28129035345, 13855.225609560746, 10016.708722343366, 559.8117399576674, 6750.190788301587, 71.21428769782159 }; double[] secondaryTridiagonal = { -4175.088570476366,1975.7955858241994,5193.178422374075, 1995.286659169179,75.34535882933804,-234.0808002076056 }; // the reference values have been computed using routine DSTEMR // from the fortran library LAPACK version 3.2.1 double[] refEigenValues = { 20654.744890306974412,16828.208208485466457, 6893.155912634994820,6757.083016675340332, 5887.799885688558788,64.309089923240379, 57.992628792736340 }; RealVector[] refEigenVectors = { new ArrayRealVector(new double[] {-0.270356342026904, 0.852811091326997, 0.399639490702077, 0.198794657813990, 0.019739323307666, 0.000106983022327, -0.000001216636321}), new ArrayRealVector(new double[] {0.179995273578326,-0.402807848153042,0.701870993525734,0.555058211014888,0.068079148898236,0.000509139115227,-0.000007112235617}), new ArrayRealVector(new double[] {-0.399582721284727,-0.056629954519333,-0.514406488522827,0.711168164518580,0.225548081276367,0.125943999652923,-0.004321507456014}), new ArrayRealVector(new double[] {0.058515721572821,0.010200130057739,0.063516274916536,-0.090696087449378,-0.017148420432597,0.991318870265707,-0.034707338554096}), new ArrayRealVector(new double[] {0.855205995537564,0.327134656629775,-0.265382397060548,0.282690729026706,0.105736068025572,-0.009138126622039,0.000367751821196}), new ArrayRealVector(new double[] {-0.002913069901144,-0.005177515777101,0.041906334478672,-0.109315918416258,0.436192305456741,0.026307315639535,0.891797507436344}), new ArrayRealVector(new double[] {-0.005738311176435,-0.010207611670378,0.082662420517928,-0.215733886094368,0.861606487840411,-0.025478530652759,-0.451080697503958}) }; // the following line triggers the exception EigenDecomposition decomposition = new EigenDecompositionImpl(mainTridiagonal, secondaryTridiagonal, MathUtils.SAFE_MIN); double[] eigenValues = decomposition.getRealEigenvalues(); for (int i = 0; i < refEigenValues.length; ++i) { assertEquals(refEigenValues[i], eigenValues[i], 1.0e-3); if (refEigenVectors[i].dotProduct(decomposition.getEigenvector(i)) < 0) { assertEquals(0, refEigenVectors[i].add(decomposition.getEigenvector(i)).getNorm(), 1.0e-5); } else { assertEquals(0, refEigenVectors[i].subtract(decomposition.getEigenvector(i)).getNorm(), 1.0e-5); } } } public void testMathpbx03() { double[] mainTridiagonal = { 1809.0978259647177,3395.4763425956166,1832.1894584712693,3804.364873592377, 806.0482458637571,2403.656427234185,28.48691431556015 }; double[] secondaryTridiagonal = { -656.8932064545833,-469.30804108920734,-1021.7714889369421, -1152.540497328983,-939.9765163817368,-12.885877015422391 }; // the reference values have been computed using routine DSTEMR // from the fortran library LAPACK version 3.2.1 double[] refEigenValues = { 4603.121913685183245,3691.195818048970978,2743.442955402465032,1657.596442107321764, 1336.797819095331306,30.129865209677519,17.035352085224986 }; RealVector[] refEigenVectors = { new ArrayRealVector(new double[] {-0.036249830202337,0.154184732411519,-0.346016328392363,0.867540105133093,-0.294483395433451,0.125854235969548,-0.000354507444044}), new ArrayRealVector(new double[] {-0.318654191697157,0.912992309960507,-0.129270874079777,-0.184150038178035,0.096521712579439,-0.070468788536461,0.000247918177736}), new ArrayRealVector(new double[] {-0.051394668681147,0.073102235876933,0.173502042943743,-0.188311980310942,-0.327158794289386,0.905206581432676,-0.004296342252659}), new ArrayRealVector(new double[] {0.838150199198361,0.193305209055716,-0.457341242126146,-0.166933875895419,0.094512811358535,0.119062381338757,-0.000941755685226}), new ArrayRealVector(new double[] {0.438071395458547,0.314969169786246,0.768480630802146,0.227919171600705,-0.193317045298647,-0.170305467485594,0.001677380536009}), new ArrayRealVector(new double[] {-0.003726503878741,-0.010091946369146,-0.067152015137611,-0.113798146542187,-0.313123000097908,-0.118940107954918,0.932862311396062}), new ArrayRealVector(new double[] {0.009373003194332,0.025570377559400,0.170955836081348,0.291954519805750,0.807824267665706,0.320108347088646,0.360202112392266}), }; // the following line triggers the exception EigenDecomposition decomposition = new EigenDecompositionImpl(mainTridiagonal, secondaryTridiagonal, MathUtils.SAFE_MIN); double[] eigenValues = decomposition.getRealEigenvalues(); for (int i = 0; i < refEigenValues.length; ++i) { assertEquals(refEigenValues[i], eigenValues[i], 1.0e-4); if (refEigenVectors[i].dotProduct(decomposition.getEigenvector(i)) < 0) { assertEquals(0, refEigenVectors[i].add(decomposition.getEigenvector(i)).getNorm(), 1.0e-5); } else { assertEquals(0, refEigenVectors[i].subtract(decomposition.getEigenvector(i)).getNorm(), 1.0e-5); } } } /** test a matrix already in tridiagonal form. */ public void testTridiagonal() { Random r = new Random(4366663527842l); double[] ref = new double[30]; for (int i = 0; i < ref.length; ++i) { if (i < 5) { ref[i] = 2 * r.nextDouble() - 1; } else { ref[i] = 0.0001 * r.nextDouble() + 6; } } Arrays.sort(ref); TriDiagonalTransformer t = new TriDiagonalTransformer(createTestMatrix(r, ref)); EigenDecomposition ed = new EigenDecompositionImpl(t.getMainDiagonalRef(), t.getSecondaryDiagonalRef(), MathUtils.SAFE_MIN); double[] eigenValues = ed.getRealEigenvalues(); assertEquals(ref.length, eigenValues.length); for (int i = 0; i < ref.length; ++i) { assertEquals(ref[ref.length - i - 1], eigenValues[i], 2.0e-14); } } /** test dimensions */ public void testDimensions() { final int m = matrix.getRowDimension(); EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); assertEquals(m, ed.getV().getRowDimension()); assertEquals(m, ed.getV().getColumnDimension()); assertEquals(m, ed.getD().getColumnDimension()); assertEquals(m, ed.getD().getColumnDimension()); assertEquals(m, ed.getVT().getRowDimension()); assertEquals(m, ed.getVT().getColumnDimension()); } /** test eigenvalues */ public void testEigenvalues() { EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); double[] eigenValues = ed.getRealEigenvalues(); assertEquals(refValues.length, eigenValues.length); for (int i = 0; i < refValues.length; ++i) { assertEquals(refValues[i], eigenValues[i], 3.0e-15); } } /** test eigenvalues for a big matrix. */ public void testBigMatrix() { Random r = new Random(17748333525117l); double[] bigValues = new double[200]; for (int i = 0; i < bigValues.length; ++i) { bigValues[i] = 2 * r.nextDouble() - 1; } Arrays.sort(bigValues); EigenDecomposition ed = new EigenDecompositionImpl(createTestMatrix(r, bigValues), MathUtils.SAFE_MIN); double[] eigenValues = ed.getRealEigenvalues(); assertEquals(bigValues.length, eigenValues.length); for (int i = 0; i < bigValues.length; ++i) { assertEquals(bigValues[bigValues.length - i - 1], eigenValues[i], 2.0e-14); } } /** test eigenvectors */ public void testEigenvectors() { EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); for (int i = 0; i < matrix.getRowDimension(); ++i) { double lambda = ed.getRealEigenvalue(i); RealVector v = ed.getEigenvector(i); RealVector mV = matrix.operate(v); assertEquals(0, mV.subtract(v.mapMultiplyToSelf(lambda)).getNorm(), 1.0e-13); } } /** test A = VDVt */ public void testAEqualVDVt() { EigenDecomposition ed = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN); RealMatrix v = ed.getV(); RealMatrix d = ed.getD(); RealMatrix vT = ed.getVT(); double norm = v.multiply(d).multiply(vT).subtract(matrix).getNorm(); assertEquals(0, norm, 6.0e-13); } /** test that V is orthogonal */ public void testVOrthogonal() { RealMatrix v = new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN).getV(); RealMatrix vTv = v.transpose().multiply(v); RealMatrix id = MatrixUtils.createRealIdentityMatrix(vTv.getRowDimension()); assertEquals(0, vTv.subtract(id).getNorm(), 2.0e-13); } /** test diagonal matrix */ public void testDiagonal() { double[] diagonal = new double[] { -3.0, -2.0, 2.0, 5.0 }; RealMatrix m = createDiagonalMatrix(diagonal, diagonal.length, diagonal.length); EigenDecomposition ed = new EigenDecompositionImpl(m, MathUtils.SAFE_MIN); assertEquals(diagonal[0], ed.getRealEigenvalue(3), 2.0e-15); assertEquals(diagonal[1], ed.getRealEigenvalue(2), 2.0e-15); assertEquals(diagonal[2], ed.getRealEigenvalue(1), 2.0e-15); assertEquals(diagonal[3], ed.getRealEigenvalue(0), 2.0e-15); } /** * Matrix with eigenvalues {8, -1, -1} */ public void testRepeatedEigenvalue() { RealMatrix repeated = MatrixUtils.createRealMatrix(new double[][] { {3, 2, 4}, {2, 0, 2}, {4, 2, 3} }); EigenDecomposition ed = new EigenDecompositionImpl(repeated, MathUtils.SAFE_MIN); checkEigenValues((new double[] {8, -1, -1}), ed, 1E-12); checkEigenVector((new double[] {2, 1, 2}), ed, 1E-12); } /** * Matrix with eigenvalues {2, 0, 12} */ public void testDistinctEigenvalues() { RealMatrix distinct = MatrixUtils.createRealMatrix(new double[][] { {3, 1, -4}, {1, 3, -4}, {-4, -4, 8} }); EigenDecomposition ed = new EigenDecompositionImpl(distinct, MathUtils.SAFE_MIN); checkEigenValues((new double[] {2, 0, 12}), ed, 1E-12); checkEigenVector((new double[] {1, -1, 0}), ed, 1E-12); checkEigenVector((new double[] {1, 1, 1}), ed, 1E-12); checkEigenVector((new double[] {-1, -1, 2}), ed, 1E-12); } /** * Verifies operation on indefinite matrix */ public void testZeroDivide() { RealMatrix indefinite = MatrixUtils.createRealMatrix(new double [][] { { 0.0, 1.0, -1.0 }, { 1.0, 1.0, 0.0 }, { -1.0,0.0, 1.0 } }); EigenDecomposition ed = new EigenDecompositionImpl(indefinite, MathUtils.SAFE_MIN); checkEigenValues((new double[] {2, 1, -1}), ed, 1E-12); double isqrt3 = 1/FastMath.sqrt(3.0); checkEigenVector((new double[] {isqrt3,isqrt3,-isqrt3}), ed, 1E-12); double isqrt2 = 1/FastMath.sqrt(2.0); checkEigenVector((new double[] {0.0,-isqrt2,-isqrt2}), ed, 1E-12); double isqrt6 = 1/FastMath.sqrt(6.0); checkEigenVector((new double[] {2*isqrt6,-isqrt6,isqrt6}), ed, 1E-12); } /** * Verifies that the given EigenDecomposition has eigenvalues equivalent to * the targetValues, ignoring the order of the values and allowing * values to differ by tolerance. */ protected void checkEigenValues(double[] targetValues, EigenDecomposition ed, double tolerance) { double[] observed = ed.getRealEigenvalues(); for (int i = 0; i < observed.length; i++) { assertTrue(isIncludedValue(observed[i], targetValues, tolerance)); assertTrue(isIncludedValue(targetValues[i], observed, tolerance)); } } /** * Returns true iff there is an entry within tolerance of value in * searchArray. */ private boolean isIncludedValue(double value, double[] searchArray, double tolerance) { boolean found = false; int i = 0; while (!found && i < searchArray.length) { if (FastMath.abs(value - searchArray[i]) < tolerance) { found = true; } i++; } return found; } /** * Returns true iff eigenVector is a scalar multiple of one of the columns * of ed.getV(). Does not try linear combinations - i.e., should only be * used to find vectors in one-dimensional eigenspaces. */ protected void checkEigenVector(double[] eigenVector, EigenDecomposition ed, double tolerance) { assertTrue(isIncludedColumn(eigenVector, ed.getV(), tolerance)); } /** * Returns true iff there is a column that is a scalar multiple of column * in searchMatrix (modulo tolerance) */ private boolean isIncludedColumn(double[] column, RealMatrix searchMatrix, double tolerance) { boolean found = false; int i = 0; while (!found && i < searchMatrix.getColumnDimension()) { double multiplier = 1.0; boolean matching = true; int j = 0; while (matching && j < searchMatrix.getRowDimension()) { double colEntry = searchMatrix.getEntry(j, i); // Use the first entry where both are non-zero as scalar if (FastMath.abs(multiplier - 1.0) <= FastMath.ulp(1.0) && FastMath.abs(colEntry) > 1E-14 && FastMath.abs(column[j]) > 1e-14) { multiplier = colEntry / column[j]; } if (FastMath.abs(column[j] * multiplier - colEntry) > tolerance) { matching = false; } j++; } found = matching; i++; } return found; } @Override public void setUp() { refValues = new double[] { 2.003, 2.002, 2.001, 1.001, 1.000, 0.001 }; matrix = createTestMatrix(new Random(35992629946426l), refValues); } @Override public void tearDown() { refValues = null; matrix = null; } static RealMatrix createTestMatrix(final Random r, final double[] eigenValues) { final int n = eigenValues.length; final RealMatrix v = createOrthogonalMatrix(r, n); final RealMatrix d = createDiagonalMatrix(eigenValues, n, n); return v.multiply(d).multiply(v.transpose()); } public static RealMatrix createOrthogonalMatrix(final Random r, final int size) { final double[][] data = new double[size][size]; for (int i = 0; i < size; ++i) { final double[] dataI = data[i]; double norm2 = 0; do { // generate randomly row I for (int j = 0; j < size; ++j) { dataI[j] = 2 * r.nextDouble() - 1; } // project the row in the subspace orthogonal to previous rows for (int k = 0; k < i; ++k) { final double[] dataK = data[k]; double dotProduct = 0; for (int j = 0; j < size; ++j) { dotProduct += dataI[j] * dataK[j]; } for (int j = 0; j < size; ++j) { dataI[j] -= dotProduct * dataK[j]; } } // normalize the row norm2 = 0; for (final double dataIJ : dataI) { norm2 += dataIJ * dataIJ; } final double inv = 1.0 / FastMath.sqrt(norm2); for (int j = 0; j < size; ++j) { dataI[j] *= inv; } } while (norm2 * size < 0.01); } return MatrixUtils.createRealMatrix(data); } public static RealMatrix createDiagonalMatrix(final double[] diagonal, final int rows, final int columns) { final double[][] dData = new double[rows][columns]; for (int i = 0; i < FastMath.min(rows, columns); ++i) { dData[i][i] = diagonal[i]; } return MatrixUtils.createRealMatrix(dData); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/TournamentSelectionTest.java100644 1750 1750 3563 11532241242 31711 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import org.junit.Test; public class TournamentSelectionTest { private static int counter = 0; @Test public void testSelect() { TournamentSelection ts = new TournamentSelection(2); ElitisticListPopulation pop = new ElitisticListPopulation(100, 0.203); for (int i=0; i 0); assertTrue(pair.getSecond().getFitness() > 0); } } private static class DummyChromosome extends Chromosome { private final int fitness; public DummyChromosome() { this.fitness = counter; counter++; } public double fitness() { return this.fitness; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/GeneticAlgorithmTestBinary.java100644 1750 1750 10041 11532241242 32306 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import java.util.LinkedList; import java.util.List; import org.junit.Test; /** * This is also an example of usage. */ public class GeneticAlgorithmTestBinary { // parameters for the GA private static final int DIMENSION = 50; private static final int POPULATION_SIZE = 50; private static final int NUM_GENERATIONS = 50; private static final double ELITISM_RATE = 0.2; private static final double CROSSOVER_RATE = 1; private static final double MUTATION_RATE = 0.1; private static final int TOURNAMENT_ARITY = 2; @Test public void test() { // to test a stochastic algorithm is hard, so this will rather be an usage example // initialize a new genetic algorithm GeneticAlgorithm ga = new GeneticAlgorithm( new OnePointCrossover(), CROSSOVER_RATE, // all selected chromosomes will be recombined (=crosssover) new BinaryMutation(), MUTATION_RATE, new TournamentSelection(TOURNAMENT_ARITY) ); assertEquals(0, ga.getGenerationsEvolved()); // initial population Population initial = randomPopulation(); // stopping conditions StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS); // best initial chromosome Chromosome bestInitial = initial.getFittestChromosome(); // run the algorithm Population finalPopulation = ga.evolve(initial, stopCond); // best chromosome from the final population Chromosome bestFinal = finalPopulation.getFittestChromosome(); // the only thing we can test is whether the final solution is not worse than the initial one // however, for some implementations of GA, this need not be true :) assertTrue(bestFinal.compareTo(bestInitial) > 0); assertEquals(NUM_GENERATIONS, ga.getGenerationsEvolved()); } /** * Initializes a random population. */ private static ElitisticListPopulation randomPopulation() { List popList = new LinkedList(); for (int i=0; i representation) { super(representation); } /** * Returns number of elements != 0 */ public double fitness() { int num = 0; for (int val : this.getRepresentation()) { if (val != 0) num++; } // number of elements >= 0 return num; } @Override public AbstractListChromosome newFixedLengthChromosome(List chromosomeRepresentation) { return new FindOnes(chromosomeRepresentation); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/ChromosomeTest.java100644 1750 1750 6225 11532241242 30020 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.List; import org.junit.Test; public class ChromosomeTest { @Test public void testCompareTo() { Chromosome c1 = new Chromosome() { public double fitness() { return 0; } }; Chromosome c2 = new Chromosome() { public double fitness() { return 10; } }; Chromosome c3 = new Chromosome() { public double fitness() { return 10; } }; assertTrue(c1.compareTo(c2) < 0); assertTrue(c2.compareTo(c1) > 0); assertEquals(0,c3.compareTo(c2)); assertEquals(0,c2.compareTo(c3)); } private abstract static class DummyChromosome extends Chromosome { private final int repr; public DummyChromosome(final int repr) { this.repr = repr; } @Override protected boolean isSame(Chromosome another) { return ((DummyChromosome) another).repr == repr; } } @Test public void testFindSameChromosome() { Chromosome c1 = new DummyChromosome(1) { public double fitness() { return 1; } }; Chromosome c2 = new DummyChromosome(2) { public double fitness() { return 2; } }; Chromosome c3 = new DummyChromosome(3) { public double fitness() { return 3; } }; Chromosome c4 = new DummyChromosome(1) { public double fitness() { return 5; } }; Chromosome c5 = new DummyChromosome(15) { public double fitness() { return 15; } }; List popChr = new ArrayList(); popChr.add(c1); popChr.add(c2); popChr.add(c3); Population pop = new ListPopulation(popChr,3) { public Population nextGeneration() { // not important return null; } }; assertNull(c5.findSameChromosome(pop)); assertEquals(c1, c4.findSameChromosome(pop)); c4.searchForFitnessUpdate(pop); assertEquals(1, c4.getFitness(),0); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/FitnessCachingTest.java100644 1750 1750 6435 11532241242 30600 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import java.util.LinkedList; import java.util.List; import org.junit.Test; public class FitnessCachingTest { // parameters for the GA private static final int DIMENSION = 50; private static final double CROSSOVER_RATE = 1; private static final double MUTATION_RATE = 0.1; private static final int TOURNAMENT_ARITY = 5; private static final int POPULATION_SIZE = 10; private static final int NUM_GENERATIONS = 50; private static final double ELITISM_RATE = 0.2; // how many times was the fitness computed private static int fitnessCalls = 0; @Test public void testFitnessCaching() { // initialize a new genetic algorithm GeneticAlgorithm ga = new GeneticAlgorithm( new OnePointCrossover(), CROSSOVER_RATE, // all selected chromosomes will be recombined (=crosssover) new BinaryMutation(), MUTATION_RATE, // no mutation new TournamentSelection(TOURNAMENT_ARITY) ); // initial population Population initial = randomPopulation(); // stopping conditions StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS); // run the algorithm ga.evolve(initial, stopCond); int neededCalls = POPULATION_SIZE /*initial population*/ + (NUM_GENERATIONS - 1) /*for each population*/ * (int)(POPULATION_SIZE * (1.0 - ELITISM_RATE)) /*some chromosomes are copied*/ ; assertTrue(fitnessCalls <= neededCalls); // some chromosomes after crossover may be the same os old ones } /** * Initializes a random population. */ private static ElitisticListPopulation randomPopulation() { List popList = new LinkedList(); for (int i=0; i representation) { super(representation); } @Override public double fitness() { fitnessCalls++; return 0; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/DummyBinaryChromosome.java100644 1750 1750 2713 11532241242 31337 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.List; /** * Implementation of BinaryChromosome for testing purposes */ public class DummyBinaryChromosome extends BinaryChromosome { public DummyBinaryChromosome(List representation) { super(representation); } public DummyBinaryChromosome(Integer[] representation) { super(representation); } @Override public AbstractListChromosome newFixedLengthChromosome(List chromosomeRepresentation) { return new DummyBinaryChromosome(chromosomeRepresentation); } public double fitness() { // uninteresting return 0; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/DummyRandomKey.java100644 1750 1750 2643 11532241242 27752 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.List; /** * Implementation of RandomKey for testing purposes */ public class DummyRandomKey extends RandomKey { public DummyRandomKey(List representation) { super(representation); } public DummyRandomKey(Double[] representation) { super(representation); } @Override public AbstractListChromosome newFixedLengthChromosome(List chromosomeRepresentation) { return new DummyRandomKey(chromosomeRepresentation); } public double fitness() { // unimportant return 0; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/ElitisticListPopulationTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/ElitisticListPopulationTest.java100644 1750 1750 3166 11532241242 32546 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import org.junit.Test; public class ElitisticListPopulationTest { private static int counter = 0; @Test public void testNextGeneration() { ElitisticListPopulation pop = new ElitisticListPopulation(100, 0.203); for (int i=0; i chromosomes = new ArrayList (); chromosomes.add(c1); chromosomes.add(c2); chromosomes.add(c3); ListPopulation population = new ListPopulation(chromosomes,10) { public Population nextGeneration() { // not important return null; } }; assertEquals(c3, population.getFittestChromosome()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/BinaryMutationTest.java100644 1750 1750 3220 11532241242 30642 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import org.junit.Test; public class BinaryMutationTest { @Test public void testMutate() { BinaryMutation mutation = new BinaryMutation(); // stochastic testing :) for (int i=0; i<20; i++) { DummyBinaryChromosome original = new DummyBinaryChromosome(BinaryChromosome.randomBinaryRepresentation(10)); DummyBinaryChromosome mutated = (DummyBinaryChromosome) mutation.mutate(original); // one gene should be different int numDifferent = 0; for (int j=0; j decoded = drk.decode(Arrays.asList(new String[] {"a", "b", "c", "d", "e"})); assertEquals("b", decoded.get(0)); assertEquals("e", decoded.get(1)); assertEquals("a", decoded.get(2)); assertEquals("c", decoded.get(3)); assertEquals("d", decoded.get(4)); } @Test public void testRandomPermutation() { // never generate an invalid one for (int i=0; i<10; i++) { DummyRandomKey drk = new DummyRandomKey(RandomKey.randomPermutation(20)); assertNotNull(drk); } } @Test public void testIdentityPermutation() { DummyRandomKey drk = new DummyRandomKey(RandomKey.identityPermutation(5)); List decoded = drk.decode(Arrays.asList(new String[] {"a", "b", "c", "d", "e"})); assertEquals("a", decoded.get(0)); assertEquals("b", decoded.get(1)); assertEquals("c", decoded.get(2)); assertEquals("d", decoded.get(3)); assertEquals("e", decoded.get(4)); } @Test public void testComparatorPermutation() { List data = Arrays.asList(new String[] {"x", "b", "c", "z", "b"}); List permutation = RandomKey.comparatorPermutation(data, new Comparator() { public int compare(String o1, String o2) { return o1.compareTo(o2); } }); Double[] permArr = new Double[data.size()]; permArr = permutation.toArray(permArr); assertArrayEquals(new Double[] {0.6,0.0,0.4,0.8,0.2}, permArr); List decodedData = new DummyRandomKey(permutation).decode(data); assertEquals("b", decodedData.get(0)); assertEquals("b", decodedData.get(1)); assertEquals("c", decodedData.get(2)); assertEquals("x", decodedData.get(3)); assertEquals("z", decodedData.get(4)); permutation = RandomKey.comparatorPermutation(data, new Comparator() { public int compare(String o1, String o2) { return o2.compareTo(o1); } }); permArr = new Double[data.size()]; permArr = permutation.toArray(permArr); assertArrayEquals(new Double[] {0.2,0.6,0.4,0.0,0.8}, permArr); decodedData = new DummyRandomKey(permutation).decode(data); assertEquals("z", decodedData.get(0)); assertEquals("x", decodedData.get(1)); assertEquals("c", decodedData.get(2)); assertEquals("b", decodedData.get(3)); assertEquals("b", decodedData.get(4)); } @Test public void testInducedPermutation() { List origData = Arrays.asList(new String[] {"a", "b", "c", "d", "d"}); List permutedData = Arrays.asList(new String[] {"d", "b", "c", "a", "d"}); DummyRandomKey drk = new DummyRandomKey(RandomKey.inducedPermutation(origData, permutedData)); List decoded = drk.decode(origData); assertEquals("d", decoded.get(0)); assertEquals("b", decoded.get(1)); assertEquals("c", decoded.get(2)); assertEquals("a", decoded.get(3)); assertEquals("d", decoded.get(4)); try { RandomKey.inducedPermutation( Arrays.asList(new String[] {"a", "b", "c", "d", "d"}), Arrays.asList(new String[] {"a", "b", "c", "d"}) ); fail("Uncaught exception"); } catch (IllegalArgumentException e) { // no-op } try { RandomKey.inducedPermutation( Arrays.asList(new String[] {"a", "b", "c", "d", "d"}), Arrays.asList(new String[] {"a", "b", "c", "d", "f"}) ); fail("Uncaught exception"); } catch (IllegalArgumentException e) { // no-op } } @Test public void testEqualRepr() { DummyRandomKey drk = new DummyRandomKey(new Double[] {0.2, 0.2, 0.5}); List decodedData = drk.decode(Arrays.asList(new String[] {"a", "b", "c"})); assertEquals("a", decodedData.get(0)); assertEquals("b", decodedData.get(1)); assertEquals("c", decodedData.get(2)); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/GeneticAlgorithmTestPermutations.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/GeneticAlgorithmTestPermutations100644 1750 1750 10757 11532241242 32652 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.util.FastMath; import org.junit.Test; /** * This is also an example of usage. * * This algorithm does "stochastic sorting" of a sequence 0,...,N. * */ public class GeneticAlgorithmTestPermutations { // parameters for the GA private static final int DIMENSION = 20; private static final int POPULATION_SIZE = 80; private static final int NUM_GENERATIONS = 200; private static final double ELITISM_RATE = 0.2; private static final double CROSSOVER_RATE = 1; private static final double MUTATION_RATE = 0.08; private static final int TOURNAMENT_ARITY = 2; // numbers from 0 to N-1 private static final List sequence = new ArrayList(); static { for (int i=0; i(), CROSSOVER_RATE, new RandomKeyMutation(), MUTATION_RATE, new TournamentSelection(TOURNAMENT_ARITY) ); // initial population Population initial = randomPopulation(); // stopping conditions StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS); // best initial chromosome Chromosome bestInitial = initial.getFittestChromosome(); // run the algorithm Population finalPopulation = ga.evolve(initial, stopCond); // best chromosome from the final population Chromosome bestFinal = finalPopulation.getFittestChromosome(); // the only thing we can test is whether the final solution is not worse than the initial one // however, for some implementations of GA, this need not be true :) assertTrue(bestFinal.compareTo(bestInitial) > 0); //System.out.println(bestInitial); //System.out.println(bestFinal); } /** * Initializes a random population */ private static ElitisticListPopulation randomPopulation() { List popList = new ArrayList(); for (int i=0; i { public MinPermutations(List representation) { super(representation); } public double fitness() { int res = 0; List decoded = decode(sequence); for (int i=0; i newFixedLengthChromosome(List chromosomeRepresentation) { return new MinPermutations(chromosomeRepresentation); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/FixedGenerationCountTest.java100644 1750 1750 3674 11532241242 31776 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import java.util.Iterator; import org.junit.Test; public class FixedGenerationCountTest { @Test public void testIsSatisfied() { FixedGenerationCount fgc = new FixedGenerationCount(20); int cnt = 0; Population pop = new Population() { public void addChromosome(Chromosome chromosome) { // unimportant } public Chromosome getFittestChromosome() { // unimportant return null; } public int getPopulationLimit() { // unimportant return 0; } public int getPopulationSize() { // unimportant return 0; } public Population nextGeneration() { // unimportant return null; } public Iterator iterator() { // unimportant return null; } }; while (!fgc.isSatisfied(pop)) cnt++; assertEquals(20, cnt); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/genetics/OnePointCrossoverTest.java100644 1750 1750 4616 11532241242 31350 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import static org.junit.Assert.*; import org.junit.Test; public class OnePointCrossoverTest { @Test public void testCrossover() { Integer[] p1 = new Integer[] {1,0,1,0,0,1,0,1,1}; Integer[] p2 = new Integer[] {0,1,1,0,1,0,1,1,1}; BinaryChromosome p1c = new DummyBinaryChromosome(p1); BinaryChromosome p2c = new DummyBinaryChromosome(p2); OnePointCrossover opc = new OnePointCrossover(); // how to test a stochastic method? for (int i=0; i<20; i++) { ChromosomePair pair = opc.crossover(p1c,p2c); Integer[] c1 = new Integer[p1.length]; Integer[] c2 = new Integer[p2.length]; c1 = ((BinaryChromosome) pair.getFirst()).getRepresentation().toArray(c1); c2 = ((BinaryChromosome) pair.getSecond()).getRepresentation().toArray(c2); // first and last values will be the same assertEquals((int) p1[0], (int) c1[0]); assertEquals((int) p2[0], (int) c2[0]); assertEquals((int) p1[p1.length-1], (int) c1[c1.length-1]); assertEquals((int) p2[p2.length-1], (int) c2[c2.length-1]); // moreover, in the above setting, the 2nd, 3rd and 7th values will be the same assertEquals((int) p1[2], (int) c1[2]); assertEquals((int) p2[2], (int) c2[2]); assertEquals((int) p1[3], (int) c1[3]); assertEquals((int) p2[3], (int) c2[3]); assertEquals((int) p1[7], (int) c1[7]); assertEquals((int) p2[7], (int) c2[7]); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/data/CertifiedDataAbstractTest.java100644 1750 1750 12743 11532241243 32167 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.data; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class CertifiedDataAbstractTest extends TestCase { private DescriptiveStatistics descriptives; private SummaryStatistics summaries; private Map certifiedValues; @Override protected void setUp() throws Exception { descriptives = new DescriptiveStatistics(); summaries = new SummaryStatistics(); certifiedValues = new HashMap(); loadData(); } private void loadData() throws IOException { BufferedReader in = null; try { URL resourceURL = getClass().getClassLoader().getResource(getResourceName()); in = new BufferedReader(new InputStreamReader(resourceURL.openStream())); String line = in.readLine(); while (line != null) { /* this call to StringUtils did little for the * following conditional structure */ line = line.trim(); // not empty line or comment if (!("".equals(line) || line.startsWith("#"))) { int n = line.indexOf('='); if (n == -1) { // data value double value = Double.parseDouble(line); descriptives.addValue(value); summaries.addValue(value); } else { // certified value String name = line.substring(0, n).trim(); String valueString = line.substring(n + 1).trim(); Double value = Double.valueOf(valueString); certifiedValues.put(name, value); } } line = in.readLine(); } } finally { if (in != null) { in.close(); } } } protected abstract String getResourceName(); protected double getMaximumAbsoluteError() { return 1.0e-5; } @Override protected void tearDown() throws Exception { descriptives.clear(); descriptives = null; summaries.clear(); summaries = null; certifiedValues.clear(); certifiedValues = null; } public void testCertifiedValues() { for (String name : certifiedValues.keySet()) { Double expectedValue = certifiedValues.get(name); Double summariesValue = getProperty(summaries, name); if (summariesValue != null) { TestUtils.assertEquals("summary value for " + name + " is incorrect.", summariesValue.doubleValue(), expectedValue.doubleValue(), getMaximumAbsoluteError()); } Double descriptivesValue = getProperty(descriptives, name); if (descriptivesValue != null) { TestUtils.assertEquals("descriptive value for " + name + " is incorrect.", descriptivesValue.doubleValue(), expectedValue.doubleValue(), getMaximumAbsoluteError()); } } } protected Double getProperty(Object bean, String name) { try { // Get the value of prop String prop = "get" + name.substring(0,1).toUpperCase() + name.substring(1); Method meth = bean.getClass().getMethod(prop, new Class[0]); Object property = meth.invoke(bean, new Object[0]); if (meth.getReturnType().equals(Double.TYPE)) { return (Double) property; } else if (meth.getReturnType().equals(Long.TYPE)) { return Double.valueOf(((Long) property).doubleValue()); } else { fail("wrong type: " + meth.getReturnType().getName()); } } catch (NoSuchMethodException nsme) { // ignored } catch (InvocationTargetException ite) { fail(ite.getMessage()); } catch (IllegalAccessException iae) { fail(iae.getMessage()); } return null; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/data/LewTest.java100644 1750 1750 2145 11532241243 26515 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.data; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class LewTest extends CertifiedDataAbstractTest { @Override protected String getResourceName() { return "org/apache/commons/math/stat/data/Lew.txt"; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/data/LotteryTest.java100644 1750 1750 2155 11532241243 27431 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.data; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class LotteryTest extends CertifiedDataAbstractTest { @Override protected String getResourceName() { return "org/apache/commons/math/stat/data/Lottery.txt"; } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClustererTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClustererTe100644 1750 1750 16600 11532241243 32545 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import java.util.Random; import org.junit.Assert; import org.junit.Test; public class KMeansPlusPlusClustererTest { @Test public void dimension2() { KMeansPlusPlusClusterer transformer = new KMeansPlusPlusClusterer(new Random(1746432956321l)); EuclideanIntegerPoint[] points = new EuclideanIntegerPoint[] { // first expected cluster new EuclideanIntegerPoint(new int[] { -15, 3 }), new EuclideanIntegerPoint(new int[] { -15, 4 }), new EuclideanIntegerPoint(new int[] { -15, 5 }), new EuclideanIntegerPoint(new int[] { -14, 3 }), new EuclideanIntegerPoint(new int[] { -14, 5 }), new EuclideanIntegerPoint(new int[] { -13, 3 }), new EuclideanIntegerPoint(new int[] { -13, 4 }), new EuclideanIntegerPoint(new int[] { -13, 5 }), // second expected cluster new EuclideanIntegerPoint(new int[] { -1, 0 }), new EuclideanIntegerPoint(new int[] { -1, -1 }), new EuclideanIntegerPoint(new int[] { 0, -1 }), new EuclideanIntegerPoint(new int[] { 1, -1 }), new EuclideanIntegerPoint(new int[] { 1, -2 }), // third expected cluster new EuclideanIntegerPoint(new int[] { 13, 3 }), new EuclideanIntegerPoint(new int[] { 13, 4 }), new EuclideanIntegerPoint(new int[] { 14, 4 }), new EuclideanIntegerPoint(new int[] { 14, 7 }), new EuclideanIntegerPoint(new int[] { 16, 5 }), new EuclideanIntegerPoint(new int[] { 16, 6 }), new EuclideanIntegerPoint(new int[] { 17, 4 }), new EuclideanIntegerPoint(new int[] { 17, 7 }) }; List> clusters = transformer.cluster(Arrays.asList(points), 3, 10); assertEquals(3, clusters.size()); boolean cluster1Found = false; boolean cluster2Found = false; boolean cluster3Found = false; for (Cluster cluster : clusters) { int[] center = cluster.getCenter().getPoint(); if (center[0] < 0) { cluster1Found = true; assertEquals(8, cluster.getPoints().size()); assertEquals(-14, center[0]); assertEquals( 4, center[1]); } else if (center[1] < 0) { cluster2Found = true; assertEquals(5, cluster.getPoints().size()); assertEquals( 0, center[0]); assertEquals(-1, center[1]); } else { cluster3Found = true; assertEquals(8, cluster.getPoints().size()); assertEquals(15, center[0]); assertEquals(5, center[1]); } } assertTrue(cluster1Found); assertTrue(cluster2Found); assertTrue(cluster3Found); } /** * JIRA: MATH-305 * * Two points, one cluster, one iteration */ @Test public void testPerformClusterAnalysisDegenerate() { KMeansPlusPlusClusterer transformer = new KMeansPlusPlusClusterer( new Random(1746432956321l)); EuclideanIntegerPoint[] points = new EuclideanIntegerPoint[] { new EuclideanIntegerPoint(new int[] { 1959, 325100 }), new EuclideanIntegerPoint(new int[] { 1960, 373200 }), }; List> clusters = transformer.cluster(Arrays.asList(points), 1, 1); assertEquals(1, clusters.size()); assertEquals(2, (clusters.get(0).getPoints().size())); EuclideanIntegerPoint pt1 = new EuclideanIntegerPoint(new int[] { 1959, 325100 }); EuclideanIntegerPoint pt2 = new EuclideanIntegerPoint(new int[] { 1960, 373200 }); assertTrue(clusters.get(0).getPoints().contains(pt1)); assertTrue(clusters.get(0).getPoints().contains(pt2)); } @Test public void testCertainSpace() { KMeansPlusPlusClusterer.EmptyClusterStrategy[] strategies = { KMeansPlusPlusClusterer.EmptyClusterStrategy.LARGEST_VARIANCE, KMeansPlusPlusClusterer.EmptyClusterStrategy.LARGEST_POINTS_NUMBER, KMeansPlusPlusClusterer.EmptyClusterStrategy.FARTHEST_POINT }; for (KMeansPlusPlusClusterer.EmptyClusterStrategy strategy : strategies) { KMeansPlusPlusClusterer transformer = new KMeansPlusPlusClusterer(new Random(1746432956321l), strategy); int numberOfVariables = 27; // initialise testvalues int position1 = 1; int position2 = position1 + numberOfVariables; int position3 = position2 + numberOfVariables; int position4 = position3 + numberOfVariables; // testvalues will be multiplied int multiplier = 1000000; EuclideanIntegerPoint[] breakingPoints = new EuclideanIntegerPoint[numberOfVariables]; // define the space which will break the cluster algorithm for (int i = 0; i < numberOfVariables; i++) { int points[] = { position1, position2, position3, position4 }; // multiply the values for (int j = 0; j < points.length; j++) { points[j] = points[j] * multiplier; } EuclideanIntegerPoint euclideanIntegerPoint = new EuclideanIntegerPoint(points); breakingPoints[i] = euclideanIntegerPoint; position1 = position1 + numberOfVariables; position2 = position2 + numberOfVariables; position3 = position3 + numberOfVariables; position4 = position4 + numberOfVariables; } for (int n = 2; n < 27; ++n) { List> clusters = transformer.cluster(Arrays.asList(breakingPoints), n, 100); Assert.assertEquals(n, clusters.size()); int sum = 0; for (Cluster cluster : clusters) { sum += cluster.getPoints().size(); } Assert.assertEquals(numberOfVariables, sum); } } } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPointTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPointTest100644 1750 1750 4705 11532241243 32541 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class EuclideanIntegerPointTest { @Test public void testArrayIsReference() { int[] array = { -3, -2, -1, 0, 1 }; assertTrue(array == new EuclideanIntegerPoint(array).getPoint()); } @Test public void testDistance() { EuclideanIntegerPoint e1 = new EuclideanIntegerPoint(new int[] { -3, -2, -1, 0, 1 }); EuclideanIntegerPoint e2 = new EuclideanIntegerPoint(new int[] { 1, 0, -1, 1, 1 }); assertEquals(FastMath.sqrt(21.0), e1.distanceFrom(e2), 1.0e-15); assertEquals(0.0, e1.distanceFrom(e1), 1.0e-15); assertEquals(0.0, e2.distanceFrom(e2), 1.0e-15); } @Test public void testCentroid() { List list = new ArrayList(); list.add(new EuclideanIntegerPoint(new int[] { 1, 3 })); list.add(new EuclideanIntegerPoint(new int[] { 2, 2 })); list.add(new EuclideanIntegerPoint(new int[] { 3, 3 })); list.add(new EuclideanIntegerPoint(new int[] { 2, 4 })); EuclideanIntegerPoint c = list.get(0).centroidOf(list); assertEquals(2, c.getPoint()[0]); assertEquals(3, c.getPoint()[1]); } @Test public void testSerial() { EuclideanIntegerPoint p = new EuclideanIntegerPoint(new int[] { -3, -2, -1, 0, 1 }); assertEquals(p, TestUtils.serializeAndRecover(p)); } } ././@LongLink100644 0 0 177 11532242443 10260 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariate100644 1750 1750 2705 11532241243 32666 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Test cases for the {@link SynchronizedMultivariateSummaryStatisticsTest} class. * @version $Revision: 902201 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug * 2007) $ */ public final class SynchronizedMultivariateSummaryStatisticsTest extends MultivariateSummaryStatisticsTest { public SynchronizedMultivariateSummaryStatisticsTest(String name) { super(name); } @Override protected MultivariateSummaryStatistics createMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { return new SynchronizedMultivariateSummaryStatistics(k, isCovarianceBiasCorrected); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValuesTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues100644 1750 1750 6710 11532241243 32642 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.Locale; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; /** * Test cases for the {@link StatisticalSummaryValues} class. * * @version $Revision: 1038873 $ $Date: 2010-11-25 00:35:13 +0100 (jeu. 25 nov. 2010) $ */ public final class StatisticalSummaryValuesTest extends TestCase { public StatisticalSummaryValuesTest(String name) { super(name); } public void testSerialization() { StatisticalSummaryValues u = new StatisticalSummaryValues(1, 2, 3, 4, 5, 6); TestUtils.checkSerializedEquality(u); StatisticalSummaryValues t = (StatisticalSummaryValues) TestUtils.serializeAndRecover(u); verifyEquality(u, t); } public void testEqualsAndHashCode() { StatisticalSummaryValues u = new StatisticalSummaryValues(1, 2, 3, 4, 5, 6); StatisticalSummaryValues t = null; assertTrue("reflexive", u.equals(u)); assertFalse("non-null compared to null", u.equals(t)); assertFalse("wrong type", u.equals(Double.valueOf(0))); t = new StatisticalSummaryValues(1, 2, 3, 4, 5, 6); assertTrue("instances with same data should be equal", t.equals(u)); assertEquals("hash code", u.hashCode(), t.hashCode()); u = new StatisticalSummaryValues(Double.NaN, 2, 3, 4, 5, 6); t = new StatisticalSummaryValues(1, Double.NaN, 3, 4, 5, 6); assertFalse("instances based on different data should be different", (u.equals(t) ||t.equals(u))); } private void verifyEquality(StatisticalSummaryValues s, StatisticalSummaryValues u) { assertEquals("N",s.getN(),u.getN()); TestUtils.assertEquals("sum",s.getSum(),u.getSum(), 0); TestUtils.assertEquals("var",s.getVariance(),u.getVariance(), 0); TestUtils.assertEquals("std",s.getStandardDeviation(),u.getStandardDeviation(), 0); TestUtils.assertEquals("mean",s.getMean(),u.getMean(), 0); TestUtils.assertEquals("min",s.getMin(),u.getMin(), 0); TestUtils.assertEquals("max",s.getMax(),u.getMax(), 0); } public void testToString() { StatisticalSummaryValues u = new StatisticalSummaryValues(4.5, 16, 10, 5, 4, 45); Locale d = Locale.getDefault(); Locale.setDefault(Locale.US); assertEquals("StatisticalSummaryValues:\n" + "n: 10\n" + "min: 4.0\n" + "max: 5.0\n" + "mean: 4.5\n" + "std dev: 4.0\n" + "variance: 16.0\n" + "sum: 45.0\n", u.toString()); Locale.setDefault(d); } } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatisticTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatis100644 1750 1750 7462 11532241243 32610 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import junit.framework.TestCase; import org.apache.commons.math.stat.descriptive.moment.Mean; /** * Tests for AbstractUnivariateStatistic * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class AbstractUnivariateStatisticTest extends TestCase { public AbstractUnivariateStatisticTest(String name) { super(name); } protected double[] testArray = {0, 1, 2, 3, 4, 5}; protected double[] testWeightsArray = {0.3, 0.2, 1.3, 1.1, 1.0, 1.8}; protected double[] testNegativeWeightsArray = {-0.3, 0.2, -1.3, 1.1, 1.0, 1.8}; protected double[] nullArray = null; protected double[] singletonArray = {0}; protected Mean testStatistic = new Mean(); public void testTestPositive() { for (int j = 0; j < 6; j++) { for (int i = 1; i < (7 - j); i++) { assertTrue(testStatistic.test(testArray, 0, i)); } } assertTrue(testStatistic.test(singletonArray, 0, 1)); } public void testTestNegative() { assertFalse(testStatistic.test(singletonArray, 0, 0)); assertFalse(testStatistic.test(testArray, 0, 0)); try { testStatistic.test(singletonArray, 2, 1); // start past end fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(testArray, 0, 7); // end past end fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(testArray, -1, 1); // start negative fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(testArray, 0, -1); // length negative fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(nullArray, 0, 1); // null array fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(testArray, nullArray, 0, 1); // null weights array fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(singletonArray, testWeightsArray, 0, 1); // weights.length != value.length fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.test(testArray, testNegativeWeightsArray, 0, 6); // can't have negative weights fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 167 11532242443 10257 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveS100644 1750 1750 2510 11532241243 32616 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Test cases for the {@link SynchronizedDescriptiveStatisticsTest} class. * @version $Revision: 902201 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug * 2007) $ */ public final class SynchronizedDescriptiveStatisticsTest extends DescriptiveStatisticsTest { public SynchronizedDescriptiveStatisticsTest(String name) { super(name); } @Override protected DescriptiveStatistics createDescriptiveStatistics() { return new SynchronizedDescriptiveStatistics(); } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/MixedListUnivariateImplTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/MixedListUnivariateImplT100644 1750 1750 15115 11532241243 32537 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.NumberTransformer; import org.apache.commons.math.util.TransformerMap; /** * Test cases for the {@link ListUnivariateImpl} class. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class MixedListUnivariateImplTest extends TestCase { private double one = 1; private float two = 2; private int three = 3; private double mean = 2; private double sumSq = 18; private double sum = 8; private double var = 0.666666666666666666667; private double std = FastMath.sqrt(var); private double n = 4; private double min = 1; private double max = 3; private double tolerance = 10E-15; private TransformerMap transformers = new TransformerMap(); public MixedListUnivariateImplTest(String name) { super(name); transformers = new TransformerMap(); transformers.putTransformer(Foo.class, new FooTransformer()); transformers.putTransformer(Bar.class, new BarTransformer()); } /** test stats */ public void testStats() { List externalList = new ArrayList(); DescriptiveStatistics u = new ListUnivariateImpl(externalList,transformers); assertEquals("total count", 0, u.getN(), tolerance); u.addValue(one); u.addValue(two); u.addValue(two); u.addValue(three); assertEquals("N", n, u.getN(), tolerance); assertEquals("sum", sum, u.getSum(), tolerance); assertEquals("sumsq", sumSq, u.getSumsq(), tolerance); assertEquals("var", var, u.getVariance(), tolerance); assertEquals("std", std, u.getStandardDeviation(), tolerance); assertEquals("mean", mean, u.getMean(), tolerance); assertEquals("min", min, u.getMin(), tolerance); assertEquals("max", max, u.getMax(), tolerance); u.clear(); assertEquals("total count", 0, u.getN(), tolerance); } public void testN0andN1Conditions() throws Exception { DescriptiveStatistics u = new ListUnivariateImpl(new ArrayList(),transformers); assertTrue( "Mean of n = 0 set should be NaN", Double.isNaN(u.getMean())); assertTrue( "Standard Deviation of n = 0 set should be NaN", Double.isNaN(u.getStandardDeviation())); assertTrue( "Variance of n = 0 set should be NaN", Double.isNaN(u.getVariance())); u.addValue(one); assertTrue( "Mean of n = 1 set should be value of single item n1, instead it is " + u.getMean() , u.getMean() == one); assertTrue( "StdDev of n = 1 set should be zero, instead it is: " + u.getStandardDeviation(), u.getStandardDeviation() == 0); assertTrue( "Variance of n = 1 set should be zero", u.getVariance() == 0); } public void testSkewAndKurtosis() { ListUnivariateImpl u = new ListUnivariateImpl(new ArrayList(), transformers); u.addObject("12.5"); u.addObject(Integer.valueOf(12)); u.addObject("11.8"); u.addObject("14.2"); u.addObject(new Foo()); u.addObject("14.5"); u.addObject(Long.valueOf(21)); u.addObject("8.2"); u.addObject("10.3"); u.addObject("11.3"); u.addObject(Float.valueOf(14.1f)); u.addObject("9.9"); u.addObject("12.2"); u.addObject(new Bar()); u.addObject("12.1"); u.addObject("11"); u.addObject(Double.valueOf(19.8)); u.addObject("11"); u.addObject("10"); u.addObject("8.8"); u.addObject("9"); u.addObject("12.3"); assertEquals("mean", 12.40455, u.getMean(), 0.0001); assertEquals("variance", 10.00236, u.getVariance(), 0.0001); assertEquals("skewness", 1.437424, u.getSkewness(), 0.0001); assertEquals("kurtosis", 2.37719, u.getKurtosis(), 0.0001); } public void testProductAndGeometricMean() throws Exception { ListUnivariateImpl u = new ListUnivariateImpl(new ArrayList(),transformers); u.setWindowSize(10); u.addValue(1.0); u.addValue(2.0); u.addValue(3.0); u.addValue(4.0); assertEquals( "Geometric mean not expected", 2.213364, u.getGeometricMean(), 0.00001); // Now test rolling - StorelessDescriptiveStatistics should discount the contribution // of a discarded element for (int i = 0; i < 10; i++) { u.addValue(i + 2); } // Values should be (2,3,4,5,6,7,8,9,10,11) assertEquals( "Geometric mean not expected", 5.755931, u.getGeometricMean(), 0.00001); } public static final class Foo { public String heresFoo() { return "14.9"; } } public static final class FooTransformer implements NumberTransformer, Serializable { private static final long serialVersionUID = -4252248129291326127L; public double transform(Object o) { return Double.parseDouble(((Foo) o).heresFoo()); } } public static final class Bar { public String heresBar() { return "12.0"; } } public static final class BarTransformer implements NumberTransformer, Serializable { private static final long serialVersionUID = -1768345377764262043L; public double transform(Object o) { return Double.parseDouble(((Bar) o).heresBar()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumTest.java100644 1750 1750 5043 11532241243 31637 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link Sum} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class SumTest extends StorelessUnivariateStatisticAbstractTest{ protected Sum stat; /** * @param name */ public SumTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Sum(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.sum; } /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */ public double expectedWeightedValue() { return this.weightedSum; } public void testSpecialValues() { Sum sum = new Sum(); assertTrue(Double.isNaN(sum.getResult())); sum.increment(1); assertEquals(1, sum.getResult(), 0); sum.increment(Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, sum.getResult(), 0); sum.increment(Double.NEGATIVE_INFINITY); assertTrue(Double.isNaN(sum.getResult())); sum.increment(1); assertTrue(Double.isNaN(sum.getResult())); } public void testWeightedSum() { Sum sum = new Sum(); assertEquals(expectedWeightedValue(), sum.evaluate(testArray, testWeightsArray, 0, testArray.length), getTolerance()); assertEquals(expectedValue(), sum.evaluate(testArray, unitWeightsArray, 0, testArray.length), getTolerance()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumSqTest.java100644 1750 1750 4361 11532241243 32145 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link SumOfSquares} class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class SumSqTest extends StorelessUnivariateStatisticAbstractTest{ protected SumOfSquares stat; /** * @param name */ public SumSqTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new SumOfSquares(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.sumSq; } public void testSpecialValues() { SumOfSquares sumSq = new SumOfSquares(); assertTrue(Double.isNaN(sumSq.getResult())); sumSq.increment(2d); assertEquals(4d, sumSq.getResult(), 0); sumSq.increment(Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, sumSq.getResult(), 0); sumSq.increment(Double.NEGATIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, sumSq.getResult(), 0); sumSq.increment(Double.NaN); assertTrue(Double.isNaN(sumSq.getResult())); sumSq.increment(1); assertTrue(Double.isNaN(sumSq.getResult())); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumLogTest.java100644 1750 1750 5004 11532241243 32276 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class SumLogTest extends StorelessUnivariateStatisticAbstractTest{ protected SumOfLogs stat; /** * @param name */ public SumLogTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new SumOfLogs(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.sumLog; } public void testSpecialValues() { SumOfLogs sum = new SumOfLogs(); // empty assertTrue(Double.isNaN(sum.getResult())); // finite data sum.increment(1d); assertFalse(Double.isNaN(sum.getResult())); // add negative infinity sum.increment(0d); assertEquals(Double.NEGATIVE_INFINITY, sum.getResult(), 0); // add positive infinity -- should make NaN sum.increment(Double.POSITIVE_INFINITY); assertTrue(Double.isNaN(sum.getResult())); // clear sum.clear(); assertTrue(Double.isNaN(sum.getResult())); // positive infinity by itself sum.increment(Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, sum.getResult(), 0); // negative value -- should make NaN sum.increment(-2d); assertTrue(Double.isNaN(sum.getResult())); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.java100644 1750 1750 5676 11532241243 32527 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class ProductTest extends StorelessUnivariateStatisticAbstractTest{ protected Product stat; /** * @param name */ public ProductTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Product(); } /** * {@inheritDoc} */ @Override public double getTolerance() { return 10E8; //sic -- big absolute error due to only 15 digits of accuracy in double } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.product; } /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */ public double expectedWeightedValue() { return this.weightedProduct; } public void testSpecialValues() { Product product = new Product(); assertTrue(Double.isNaN(product.getResult())); product.increment(1); assertEquals(1, product.getResult(), 0); product.increment(Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, product.getResult(), 0); product.increment(Double.NEGATIVE_INFINITY); assertEquals(Double.NEGATIVE_INFINITY, product.getResult(), 0); product.increment(Double.NaN); assertTrue(Double.isNaN(product.getResult())); product.increment(1); assertTrue(Double.isNaN(product.getResult())); } public void testWeightedProduct() { Product product = new Product(); assertEquals(expectedWeightedValue(), product.evaluate(testArray, testWeightsArray, 0, testArray.length),getTolerance()); assertEquals(expectedValue(), product.evaluate(testArray, unitWeightsArray, 0, testArray.length), getTolerance()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/InteractionTest.java100644 1750 1750 5116 11532241243 31656 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.stat.descriptive.moment.FourthMoment; import org.apache.commons.math.stat.descriptive.moment.Kurtosis; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.Skewness; import org.apache.commons.math.stat.descriptive.moment.Variance; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class InteractionTest extends TestCase { protected double mean = 12.40454545454550; protected double var = 10.00235930735930; protected double skew = 1.437423729196190; protected double kurt = 2.377191264804700; protected double tolerance = 10E-12; protected double[] testArray = { 12.5, 12, 11.8, 14.2, 14.9, 14.5, 21, 8.2, 10.3, 11.3, 14.1, 9.9, 12.2, 12, 12.1, 11, 19.8, 11, 10, 8.8, 9, 12.3 }; public InteractionTest(String name) { super(name); } public void testInteraction() { FourthMoment m4 = new FourthMoment(); Mean m = new Mean(m4); Variance v = new Variance(m4); Skewness s= new Skewness(m4); Kurtosis k = new Kurtosis(m4); for (int i = 0; i < testArray.length; i++){ m4.increment(testArray[i]); } assertEquals(mean,m.getResult(),tolerance); assertEquals(var,v.getResult(),tolerance); assertEquals(skew ,s.getResult(),tolerance); assertEquals(kurt,k.getResult(),tolerance); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/ListUnivariateImpl.java100644 1750 1750 13757 11532241243 32356 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.MathException; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.util.DefaultTransformer; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.NumberTransformer; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class ListUnivariateImpl extends DescriptiveStatistics implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -8837442489133392138L; /** * Holds a reference to a list - GENERICs are going to make * our lives easier here as we could only accept List */ protected List list; /** Number Transformer maps Objects to Number for us. */ protected NumberTransformer transformer; /** * No argument Constructor */ public ListUnivariateImpl(){ this(new ArrayList()); } /** * Construct a ListUnivariate with a specific List. * @param list The list that will back this DescriptiveStatistics */ public ListUnivariateImpl(List list) { this(list, new DefaultTransformer()); } /** * Construct a ListUnivariate with a specific List. * @param list The list that will back this DescriptiveStatistics * @param transformer the number transformer used to convert the list items. */ public ListUnivariateImpl(List list, NumberTransformer transformer) { super(); this.list = list; this.transformer = transformer; } /** {@inheritDoc} */ @Override public double[] getValues() { int length = list.size(); // If the window size is not INFINITE_WINDOW AND // the current list is larger that the window size, we need to // take into account only the last n elements of the list // as definied by windowSize if (windowSize != DescriptiveStatistics.INFINITE_WINDOW && windowSize < list.size()) { length = list.size() - FastMath.max(0, list.size() - windowSize); } // Create an array to hold all values double[] copiedArray = new double[length]; for (int i = 0; i < copiedArray.length; i++) { copiedArray[i] = getElement(i); } return copiedArray; } /** {@inheritDoc} */ @Override public double getElement(int index) { double value = Double.NaN; int calcIndex = index; if (windowSize != DescriptiveStatistics.INFINITE_WINDOW && windowSize < list.size()) { calcIndex = (list.size() - windowSize) + index; } try { value = transformer.transform(list.get(calcIndex)); } catch (MathException e) { e.printStackTrace(); } return value; } /** {@inheritDoc} */ @Override public long getN() { int n = 0; if (windowSize != DescriptiveStatistics.INFINITE_WINDOW) { if (list.size() > windowSize) { n = windowSize; } else { n = list.size(); } } else { n = list.size(); } return n; } /** {@inheritDoc} */ @Override public void addValue(double v) { list.add(Double.valueOf(v)); } /** * Adds an object to this list. * @param o Object to add to the list */ public void addObject(Object o) { list.add(o); } /** * Clears all statistics. *

        * N.B.: This method has the side effect of clearing the underlying list. */ @Override public void clear() { list.clear(); } /** * Apply the given statistic to this univariate collection. * @param stat the statistic to apply * @return the computed value of the statistic. */ @Override public double apply(UnivariateStatistic stat) { double[] v = this.getValues(); if (v != null) { return stat.evaluate(v, 0, v.length); } return Double.NaN; } /** * Access the number transformer. * @return the number transformer. */ public NumberTransformer getTransformer() { return transformer; } /** * Modify the number transformer. * @param transformer the new number transformer. */ public void setTransformer(NumberTransformer transformer) { this.transformer = transformer; } /** {@inheritDoc} */ @Override public synchronized void setWindowSize(int windowSize) { this.windowSize = windowSize; //Discard elements from the front of the list if the windowSize is less than // the size of the list. int extra = list.size() - windowSize; for (int i = 0; i < extra; i++) { list.remove(0); } } /** {@inheritDoc} */ @Override public synchronized int getWindowSize() { return windowSize; } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatisti100644 1750 1750 26541 11532241243 32635 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.ArrayList; import java.util.Collection; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.random.RandomData; import org.apache.commons.math.random.RandomDataImpl; /** * Test cases for {@link AggregateSummaryStatistics} * */ public class AggregateSummaryStatisticsTest extends TestCase { /** * Tests the standard aggregation behavior */ public void testAggregation() { AggregateSummaryStatistics aggregate = new AggregateSummaryStatistics(); SummaryStatistics setOneStats = aggregate.createContributingStatistics(); SummaryStatistics setTwoStats = aggregate.createContributingStatistics(); assertNotNull("The set one contributing stats are null", setOneStats); assertNotNull("The set two contributing stats are null", setTwoStats); assertNotSame("Contributing stats objects are the same", setOneStats, setTwoStats); setOneStats.addValue(2); setOneStats.addValue(3); setOneStats.addValue(5); setOneStats.addValue(7); setOneStats.addValue(11); assertEquals("Wrong number of set one values", 5, setOneStats.getN()); assertEquals("Wrong sum of set one values", 28.0, setOneStats.getSum()); setTwoStats.addValue(2); setTwoStats.addValue(4); setTwoStats.addValue(8); assertEquals("Wrong number of set two values", 3, setTwoStats.getN()); assertEquals("Wrong sum of set two values", 14.0, setTwoStats.getSum()); assertEquals("Wrong number of aggregate values", 8, aggregate.getN()); assertEquals("Wrong aggregate sum", 42.0, aggregate.getSum()); } /** * Verify that aggregating over a partition gives the same results * as direct computation. * * 1) Randomly generate a dataset of 10-100 values * from [-100, 100] * 2) Divide the dataset it into 2-5 partitions * 3) Create an AggregateSummaryStatistic and ContributingStatistics * for each partition * 4) Compare results from the AggregateSummaryStatistic with values * returned by a single SummaryStatistics instance that is provided * the full dataset */ public void testAggregationConsistency() throws Exception { // Generate a random sample and random partition double[] totalSample = generateSample(); double[][] subSamples = generatePartition(totalSample); int nSamples = subSamples.length; // Create aggregator and total stats for comparison AggregateSummaryStatistics aggregate = new AggregateSummaryStatistics(); SummaryStatistics totalStats = new SummaryStatistics(); // Create array of component stats SummaryStatistics componentStats[] = new SummaryStatistics[nSamples]; for (int i = 0; i < nSamples; i++) { // Make componentStats[i] a contributing statistic to aggregate componentStats[i] = aggregate.createContributingStatistics(); // Add values from subsample for (int j = 0; j < subSamples[i].length; j++) { componentStats[i].addValue(subSamples[i][j]); } } // Compute totalStats directly for (int i = 0; i < totalSample.length; i++) { totalStats.addValue(totalSample[i]); } /* * Compare statistics in totalStats with aggregate. * Note that guaranteed success of this comparison depends on the * fact that gets values in exactly the same order * as . * */ assertEquals(totalStats.getSummary(), aggregate.getSummary()); } /** * Test aggregate function by randomly generating a dataset of 10-100 values * from [-100, 100], dividing it into 2-5 partitions, computing stats for each * partition and comparing the result of aggregate(...) applied to the collection * of per-partition SummaryStatistics with a single SummaryStatistics computed * over the full sample. * * @throws Exception */ public void testAggregate() throws Exception { // Generate a random sample and random partition double[] totalSample = generateSample(); double[][] subSamples = generatePartition(totalSample); int nSamples = subSamples.length; // Compute combined stats directly SummaryStatistics totalStats = new SummaryStatistics(); for (int i = 0; i < totalSample.length; i++) { totalStats.addValue(totalSample[i]); } // Now compute subsample stats individually and aggregate SummaryStatistics[] subSampleStats = new SummaryStatistics[nSamples]; for (int i = 0; i < nSamples; i++) { subSampleStats[i] = new SummaryStatistics(); } Collection aggregate = new ArrayList(); for (int i = 0; i < nSamples; i++) { for (int j = 0; j < subSamples[i].length; j++) { subSampleStats[i].addValue(subSamples[i][j]); } aggregate.add(subSampleStats[i]); } // Compare values StatisticalSummary aggregatedStats = AggregateSummaryStatistics.aggregate(aggregate); assertEquals(totalStats.getSummary(), aggregatedStats, 10E-12); } public void testAggregateDegenerate() throws Exception { double[] totalSample = {1, 2, 3, 4, 5}; double[][] subSamples = {{1}, {2}, {3}, {4}, {5}}; // Compute combined stats directly SummaryStatistics totalStats = new SummaryStatistics(); for (int i = 0; i < totalSample.length; i++) { totalStats.addValue(totalSample[i]); } // Now compute subsample stats individually and aggregate SummaryStatistics[] subSampleStats = new SummaryStatistics[5]; for (int i = 0; i < 5; i++) { subSampleStats[i] = new SummaryStatistics(); } Collection aggregate = new ArrayList(); for (int i = 0; i < 5; i++) { for (int j = 0; j < subSamples[i].length; j++) { subSampleStats[i].addValue(subSamples[i][j]); } aggregate.add(subSampleStats[i]); } // Compare values StatisticalSummaryValues aggregatedStats = AggregateSummaryStatistics.aggregate(aggregate); assertEquals(totalStats.getSummary(), aggregatedStats, 10E-12); } public void testAggregateSpecialValues() throws Exception { double[] totalSample = {Double.POSITIVE_INFINITY, 2, 3, Double.NaN, 5}; double[][] subSamples = {{Double.POSITIVE_INFINITY, 2}, {3}, {Double.NaN}, {5}}; // Compute combined stats directly SummaryStatistics totalStats = new SummaryStatistics(); for (int i = 0; i < totalSample.length; i++) { totalStats.addValue(totalSample[i]); } // Now compute subsample stats individually and aggregate SummaryStatistics[] subSampleStats = new SummaryStatistics[5]; for (int i = 0; i < 4; i++) { subSampleStats[i] = new SummaryStatistics(); } Collection aggregate = new ArrayList(); for (int i = 0; i < 4; i++) { for (int j = 0; j < subSamples[i].length; j++) { subSampleStats[i].addValue(subSamples[i][j]); } aggregate.add(subSampleStats[i]); } // Compare values StatisticalSummaryValues aggregatedStats = AggregateSummaryStatistics.aggregate(aggregate); assertEquals(totalStats.getSummary(), aggregatedStats, 10E-12); } /** * Verifies that a StatisticalSummary and a StatisticalSummaryValues are equal up * to delta, with NaNs, infinities returned in the same spots. For max, min, n, values * have to agree exactly, delta is used only for sum, mean, variance, std dev. */ protected static void assertEquals(StatisticalSummary expected, StatisticalSummary observed, double delta) { TestUtils.assertEquals(expected.getMax(), observed.getMax(), 0); TestUtils.assertEquals(expected.getMin(), observed.getMin(), 0); assertEquals(expected.getN(), observed.getN()); TestUtils.assertEquals(expected.getSum(), observed.getSum(), delta); TestUtils.assertEquals(expected.getMean(), observed.getMean(), delta); TestUtils.assertEquals(expected.getStandardDeviation(), observed.getStandardDeviation(), delta); TestUtils.assertEquals(expected.getVariance(), observed.getVariance(), delta); } /** * Generates a random sample of double values. * Sample size is random, between 10 and 100 and values are * uniformly distributed over [-100, 100]. * * @return array of random double values */ private double[] generateSample() { final RandomData randomData = new RandomDataImpl(); final int sampleSize = randomData.nextInt(10,100); double[] out = new double[sampleSize]; for (int i = 0; i < out.length; i++) { out[i] = randomData.nextUniform(-100, 100); } return out; } /** * Generates a partition of into up to 5 sequentially selected * subsamples with randomly selected partition points. * * @param sample array to partition * @return rectangular array with rows = subsamples */ private double[][] generatePartition(double[] sample) { final int length = sample.length; final double[][] out = new double[5][]; final RandomData randomData = new RandomDataImpl(); int cur = 0; int offset = 0; int sampleCount = 0; for (int i = 0; i < 5; i++) { if (cur == length || offset == length) { break; } final int next = (i == 4 || cur == length - 1) ? length - 1 : randomData.nextInt(cur, length - 1); final int subLength = next - cur + 1; out[i] = new double[subLength]; System.arraycopy(sample, offset, out[i], 0, subLength); cur = next + 1; sampleCount++; offset += subLength; } if (sampleCount < 5) { double[][] out2 = new double[sampleCount][]; for (int j = 0; j < sampleCount; j++) { final int curSize = out[j].length; out2[j] = new double[curSize]; System.arraycopy(out[j], 0, out2[j], 0, curSize); } return out2; } else { return out; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/MedianTest.java100644 1750 1750 3132 11532241243 31523 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class MedianTest extends UnivariateStatisticAbstractTest{ protected Median stat; /** * @param name */ public MedianTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Median(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.median; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/MaxTest.java100644 1750 1750 5174 11532241243 31063 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class MaxTest extends StorelessUnivariateStatisticAbstractTest{ protected Max stat; /** * @param name */ public MaxTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Max(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.max; } public void testSpecialValues() { double[] testArray = {0d, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}; Max max = new Max(); assertTrue(Double.isNaN(max.getResult())); max.increment(testArray[0]); assertEquals(0d, max.getResult(), 0); max.increment(testArray[1]); assertEquals(0d, max.getResult(), 0); max.increment(testArray[2]); assertEquals(0d, max.getResult(), 0); max.increment(testArray[3]); assertEquals(Double.POSITIVE_INFINITY, max.getResult(), 0); assertEquals(Double.POSITIVE_INFINITY, max.evaluate(testArray), 0); } public void testNaNs() { Max max = new Max(); double nan = Double.NaN; assertEquals(3d, max.evaluate(new double[]{nan, 2d, 3d}), 0); assertEquals(3d, max.evaluate(new double[]{1d, nan, 3d}), 0); assertEquals(2d, max.evaluate(new double[]{1d, 2d, nan}), 0); assertTrue(Double.isNaN(max.evaluate(new double[]{nan, nan, nan}))); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/PercentileTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/PercentileTest.java100644 1750 1750 13151 11532241243 32442 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class PercentileTest extends UnivariateStatisticAbstractTest{ protected Percentile stat; /** * @param name */ public PercentileTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Percentile(95.0); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.percentile95; } public void testHighPercentile(){ double[] d = new double[]{1, 2, 3}; Percentile p = new Percentile(75); assertEquals(3.0, p.evaluate(d), 1.0e-5); } public void testPercentile() { double[] d = new double[] {1, 3, 2, 4}; Percentile p = new Percentile(30); assertEquals(1.5, p.evaluate(d), 1.0e-5); p.setQuantile(25); assertEquals(1.25, p.evaluate(d), 1.0e-5); p.setQuantile(75); assertEquals(3.75, p.evaluate(d), 1.0e-5); p.setQuantile(50); assertEquals(2.5, p.evaluate(d), 1.0e-5); // invalid percentiles try { p.evaluate(d, 0, d.length, -1.0); fail(); } catch (IllegalArgumentException ex) { // success } try { p.evaluate(d, 0, d.length, 101.0); fail(); } catch (IllegalArgumentException ex) { // success } } public void testNISTExample() { double[] d = new double[] {95.1772, 95.1567, 95.1937, 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, 95.1682 }; Percentile p = new Percentile(90); assertEquals(95.1981, p.evaluate(d), 1.0e-4); assertEquals(95.1990, p.evaluate(d,0,d.length, 100d), 0); } public void test5() { Percentile percentile = new Percentile(5); assertEquals(this.percentile5, percentile.evaluate(testArray), getTolerance()); } public void testNullEmpty() { Percentile percentile = new Percentile(50); double[] nullArray = null; double[] emptyArray = new double[] {}; try { percentile.evaluate(nullArray); fail("Expecting IllegalArgumentException for null array"); } catch (IllegalArgumentException ex) { // expected } assertTrue(Double.isNaN(percentile.evaluate(emptyArray))); } public void testSingleton() { Percentile percentile = new Percentile(50); double[] singletonArray = new double[] {1d}; assertEquals(1d, percentile.evaluate(singletonArray), 0); assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0); assertEquals(1d, percentile.evaluate(singletonArray, 0, 1, 5), 0); assertEquals(1d, percentile.evaluate(singletonArray, 0, 1, 100), 0); assertTrue(Double.isNaN(percentile.evaluate(singletonArray, 0, 0))); } public void testSpecialValues() { Percentile percentile = new Percentile(50); double[] specialValues = new double[] {0d, 1d, 2d, 3d, 4d, Double.NaN}; assertEquals(2.5d, percentile.evaluate(specialValues), 0); specialValues = new double[] {Double.NEGATIVE_INFINITY, 1d, 2d, 3d, Double.NaN, Double.POSITIVE_INFINITY}; assertEquals(2.5d, percentile.evaluate(specialValues), 0); specialValues = new double[] {1d, 1d, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY}; assertTrue(Double.isInfinite(percentile.evaluate(specialValues))); specialValues = new double[] {1d, 1d, Double.NaN, Double.NaN}; assertTrue(Double.isNaN(percentile.evaluate(specialValues))); specialValues = new double[] {1d, 1d, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY}; // Interpolation results in NEGATIVE_INFINITY + POSITIVE_INFINITY assertTrue(Double.isNaN(percentile.evaluate(specialValues))); } public void testSetQuantile() { Percentile percentile = new Percentile(10); percentile.setQuantile(100); // OK assertEquals(100, percentile.getQuantile(), 0); try { percentile.setQuantile(0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { new Percentile(0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/rank/MinTest.java100644 1750 1750 5174 11532241243 31061 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class MinTest extends StorelessUnivariateStatisticAbstractTest{ protected Min stat; /** * @param name */ public MinTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Min(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.min; } public void testSpecialValues() { double[] testArray = {0d, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}; Min min = new Min(); assertTrue(Double.isNaN(min.getResult())); min.increment(testArray[0]); assertEquals(0d, min.getResult(), 0); min.increment(testArray[1]); assertEquals(0d, min.getResult(), 0); min.increment(testArray[2]); assertEquals(0d, min.getResult(), 0); min.increment(testArray[3]); assertEquals(Double.NEGATIVE_INFINITY, min.getResult(), 0); assertEquals(Double.NEGATIVE_INFINITY, min.evaluate(testArray), 0); } public void testNaNs() { Min min = new Min(); double nan = Double.NaN; assertEquals(2d, min.evaluate(new double[]{nan, 2d, 3d}), 0); assertEquals(1d, min.evaluate(new double[]{1d, nan, 3d}), 0); assertEquals(1d, min.evaluate(new double[]{1d, 2d, nan}), 0); assertTrue(Double.isNaN(min.evaluate(new double[]{nan, nan, nan}))); } } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStati100644 1750 1750 31110 11532241243 32661 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.Locale; import junit.framework.TestCase; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link MultivariateSummaryStatistics} class. * * @version $Revision: 1003907 $ $Date: 2010-10-03 00:23:34 +0200 (dim. 03 oct. 2010) $ */ public class MultivariateSummaryStatisticsTest extends TestCase { public MultivariateSummaryStatisticsTest(String name) { super(name); } protected MultivariateSummaryStatistics createMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { return new MultivariateSummaryStatistics(k, isCovarianceBiasCorrected); } public void testSetterInjection() throws Exception { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(2, true); u.setMeanImpl(new StorelessUnivariateStatistic[] { new sumMean(), new sumMean() }); u.addValue(new double[] { 1, 2 }); u.addValue(new double[] { 3, 4 }); assertEquals(4, u.getMean()[0], 1E-14); assertEquals(6, u.getMean()[1], 1E-14); u.clear(); u.addValue(new double[] { 1, 2 }); u.addValue(new double[] { 3, 4 }); assertEquals(4, u.getMean()[0], 1E-14); assertEquals(6, u.getMean()[1], 1E-14); u.clear(); u.setMeanImpl(new StorelessUnivariateStatistic[] { new Mean(), new Mean() }); // OK after clear u.addValue(new double[] { 1, 2 }); u.addValue(new double[] { 3, 4 }); assertEquals(2, u.getMean()[0], 1E-14); assertEquals(3, u.getMean()[1], 1E-14); assertEquals(2, u.getDimension()); } public void testSetterIllegalState() throws Exception { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(2, true); u.addValue(new double[] { 1, 2 }); u.addValue(new double[] { 3, 4 }); try { u.setMeanImpl(new StorelessUnivariateStatistic[] { new sumMean(), new sumMean() }); fail("Expecting IllegalStateException"); } catch (IllegalStateException ex) { // expected } } public void testToString() throws DimensionMismatchException { MultivariateSummaryStatistics stats = createMultivariateSummaryStatistics(2, true); stats.addValue(new double[] {1, 3}); stats.addValue(new double[] {2, 2}); stats.addValue(new double[] {3, 1}); Locale d = Locale.getDefault(); Locale.setDefault(Locale.US); final String suffix = System.getProperty("line.separator"); assertEquals("MultivariateSummaryStatistics:" + suffix+ "n: 3" +suffix+ "min: 1.0, 1.0" +suffix+ "max: 3.0, 3.0" +suffix+ "mean: 2.0, 2.0" +suffix+ "geometric mean: 1.817..., 1.817..." +suffix+ "sum of squares: 14.0, 14.0" +suffix+ "sum of logarithms: 1.791..., 1.791..." +suffix+ "standard deviation: 1.0, 1.0" +suffix+ "covariance: Array2DRowRealMatrix{{1.0,-1.0},{-1.0,1.0}}" +suffix, stats.toString().replaceAll("([0-9]+\\.[0-9][0-9][0-9])[0-9]+", "$1...")); Locale.setDefault(d); } public void testShuffledStatistics() throws DimensionMismatchException { // the purpose of this test is only to check the get/set methods // we are aware shuffling statistics like this is really not // something sensible to do in production ... MultivariateSummaryStatistics reference = createMultivariateSummaryStatistics(2, true); MultivariateSummaryStatistics shuffled = createMultivariateSummaryStatistics(2, true); StorelessUnivariateStatistic[] tmp = shuffled.getGeoMeanImpl(); shuffled.setGeoMeanImpl(shuffled.getMeanImpl()); shuffled.setMeanImpl(shuffled.getMaxImpl()); shuffled.setMaxImpl(shuffled.getMinImpl()); shuffled.setMinImpl(shuffled.getSumImpl()); shuffled.setSumImpl(shuffled.getSumsqImpl()); shuffled.setSumsqImpl(shuffled.getSumLogImpl()); shuffled.setSumLogImpl(tmp); for (int i = 100; i > 0; --i) { reference.addValue(new double[] {i, i}); shuffled.addValue(new double[] {i, i}); } TestUtils.assertEquals(reference.getMean(), shuffled.getGeometricMean(), 1.0e-10); TestUtils.assertEquals(reference.getMax(), shuffled.getMean(), 1.0e-10); TestUtils.assertEquals(reference.getMin(), shuffled.getMax(), 1.0e-10); TestUtils.assertEquals(reference.getSum(), shuffled.getMin(), 1.0e-10); TestUtils.assertEquals(reference.getSumSq(), shuffled.getSum(), 1.0e-10); TestUtils.assertEquals(reference.getSumLog(), shuffled.getSumSq(), 1.0e-10); TestUtils.assertEquals(reference.getGeometricMean(), shuffled.getSumLog(), 1.0e-10); } /** * Bogus mean implementation to test setter injection. * Returns the sum instead of the mean. */ static class sumMean implements StorelessUnivariateStatistic { private double sum = 0; private long n = 0; public double evaluate(double[] values, int begin, int length) { return 0; } public double evaluate(double[] values) { return 0; } public void clear() { sum = 0; n = 0; } public long getN() { return n; } public double getResult() { return sum; } public void increment(double d) { sum += d; n++; } public void incrementAll(double[] values, int start, int length) { } public void incrementAll(double[] values) { } public StorelessUnivariateStatistic copy() { return new sumMean(); } } public void testDimension() { try { createMultivariateSummaryStatistics(2, true).addValue(new double[3]); fail("Expecting DimensionMismatchException"); } catch (DimensionMismatchException dme) { // expected behavior } } /** test stats */ public void testStats() throws DimensionMismatchException { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(2, true); assertEquals(0, u.getN()); u.addValue(new double[] { 1, 2 }); u.addValue(new double[] { 2, 3 }); u.addValue(new double[] { 2, 3 }); u.addValue(new double[] { 3, 4 }); assertEquals( 4, u.getN()); assertEquals( 8, u.getSum()[0], 1.0e-10); assertEquals(12, u.getSum()[1], 1.0e-10); assertEquals(18, u.getSumSq()[0], 1.0e-10); assertEquals(38, u.getSumSq()[1], 1.0e-10); assertEquals( 1, u.getMin()[0], 1.0e-10); assertEquals( 2, u.getMin()[1], 1.0e-10); assertEquals( 3, u.getMax()[0], 1.0e-10); assertEquals( 4, u.getMax()[1], 1.0e-10); assertEquals(2.4849066497880003102, u.getSumLog()[0], 1.0e-10); assertEquals( 4.276666119016055311, u.getSumLog()[1], 1.0e-10); assertEquals( 1.8612097182041991979, u.getGeometricMean()[0], 1.0e-10); assertEquals( 2.9129506302439405217, u.getGeometricMean()[1], 1.0e-10); assertEquals( 2, u.getMean()[0], 1.0e-10); assertEquals( 3, u.getMean()[1], 1.0e-10); assertEquals(FastMath.sqrt(2.0 / 3.0), u.getStandardDeviation()[0], 1.0e-10); assertEquals(FastMath.sqrt(2.0 / 3.0), u.getStandardDeviation()[1], 1.0e-10); assertEquals(2.0 / 3.0, u.getCovariance().getEntry(0, 0), 1.0e-10); assertEquals(2.0 / 3.0, u.getCovariance().getEntry(0, 1), 1.0e-10); assertEquals(2.0 / 3.0, u.getCovariance().getEntry(1, 0), 1.0e-10); assertEquals(2.0 / 3.0, u.getCovariance().getEntry(1, 1), 1.0e-10); u.clear(); assertEquals(0, u.getN()); } public void testN0andN1Conditions() throws Exception { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(1, true); assertTrue(Double.isNaN(u.getMean()[0])); assertTrue(Double.isNaN(u.getStandardDeviation()[0])); /* n=1 */ u.addValue(new double[] { 1 }); assertEquals(1.0, u.getMean()[0], 1.0e-10); assertEquals(1.0, u.getGeometricMean()[0], 1.0e-10); assertEquals(0.0, u.getStandardDeviation()[0], 1.0e-10); /* n=2 */ u.addValue(new double[] { 2 }); assertTrue(u.getStandardDeviation()[0] > 0); } public void testNaNContracts() throws DimensionMismatchException { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(1, true); assertTrue(Double.isNaN(u.getMean()[0])); assertTrue(Double.isNaN(u.getMin()[0])); assertTrue(Double.isNaN(u.getStandardDeviation()[0])); assertTrue(Double.isNaN(u.getGeometricMean()[0])); u.addValue(new double[] { 1.0 }); assertFalse(Double.isNaN(u.getMean()[0])); assertFalse(Double.isNaN(u.getMin()[0])); assertFalse(Double.isNaN(u.getStandardDeviation()[0])); assertFalse(Double.isNaN(u.getGeometricMean()[0])); } public void testSerialization() throws DimensionMismatchException { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(2, true); // Empty test TestUtils.checkSerializedEquality(u); MultivariateSummaryStatistics s = (MultivariateSummaryStatistics) TestUtils.serializeAndRecover(u); assertEquals(u, s); // Add some data u.addValue(new double[] { 2d, 1d }); u.addValue(new double[] { 1d, 1d }); u.addValue(new double[] { 3d, 1d }); u.addValue(new double[] { 4d, 1d }); u.addValue(new double[] { 5d, 1d }); // Test again TestUtils.checkSerializedEquality(u); s = (MultivariateSummaryStatistics) TestUtils.serializeAndRecover(u); assertEquals(u, s); } public void testEqualsAndHashCode() throws DimensionMismatchException { MultivariateSummaryStatistics u = createMultivariateSummaryStatistics(2, true); MultivariateSummaryStatistics t = null; int emptyHash = u.hashCode(); assertTrue(u.equals(u)); assertFalse(u.equals(t)); assertFalse(u.equals(Double.valueOf(0))); t = createMultivariateSummaryStatistics(2, true); assertTrue(t.equals(u)); assertTrue(u.equals(t)); assertEquals(emptyHash, t.hashCode()); // Add some data to u u.addValue(new double[] { 2d, 1d }); u.addValue(new double[] { 1d, 1d }); u.addValue(new double[] { 3d, 1d }); u.addValue(new double[] { 4d, 1d }); u.addValue(new double[] { 5d, 1d }); assertFalse(t.equals(u)); assertFalse(u.equals(t)); assertTrue(u.hashCode() != t.hashCode()); //Add data in same order to t t.addValue(new double[] { 2d, 1d }); t.addValue(new double[] { 1d, 1d }); t.addValue(new double[] { 3d, 1d }); t.addValue(new double[] { 4d, 1d }); t.addValue(new double[] { 5d, 1d }); assertTrue(t.equals(u)); assertTrue(u.equals(t)); assertEquals(u.hashCode(), t.hashCode()); // Clear and make sure summaries are indistinguishable from empty summary u.clear(); t.clear(); assertTrue(t.equals(u)); assertTrue(u.equals(t)); assertEquals(emptyHash, t.hashCode()); assertEquals(emptyHash, u.hashCode()); } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTes100644 1750 1750 25044 11532241243 32651 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.Locale; import junit.framework.TestCase; import org.apache.commons.math.stat.descriptive.rank.Percentile; import org.apache.commons.math.util.MathUtils; /** * Test cases for the DescriptiveStatistics class. * * @version $Revision: 1003907 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug * 2007) $ */ public class DescriptiveStatisticsTest extends TestCase { public DescriptiveStatisticsTest(String name) { super(name); } protected DescriptiveStatistics createDescriptiveStatistics() { return new DescriptiveStatistics(); } public void testSetterInjection() { DescriptiveStatistics stats = createDescriptiveStatistics(); stats.addValue(1); stats.addValue(3); assertEquals(2, stats.getMean(), 1E-10); // Now lets try some new math stats.setMeanImpl(new deepMean()); assertEquals(42, stats.getMean(), 1E-10); } public void testCopy() { DescriptiveStatistics stats = createDescriptiveStatistics(); stats.addValue(1); stats.addValue(3); DescriptiveStatistics copy = new DescriptiveStatistics(stats); assertEquals(2, copy.getMean(), 1E-10); // Now lets try some new math stats.setMeanImpl(new deepMean()); copy = stats.copy(); assertEquals(42, copy.getMean(), 1E-10); } public void testWindowSize() { DescriptiveStatistics stats = createDescriptiveStatistics(); stats.setWindowSize(300); for (int i = 0; i < 100; ++i) { stats.addValue(i + 1); } int refSum = (100 * 101) / 2; assertEquals(refSum / 100.0, stats.getMean(), 1E-10); assertEquals(300, stats.getWindowSize()); try { stats.setWindowSize(-3); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected } assertEquals(300, stats.getWindowSize()); stats.setWindowSize(50); assertEquals(50, stats.getWindowSize()); int refSum2 = refSum - (50 * 51) / 2; assertEquals(refSum2 / 50.0, stats.getMean(), 1E-10); } public void testGetValues() { DescriptiveStatistics stats = createDescriptiveStatistics(); for (int i = 100; i > 0; --i) { stats.addValue(i); } int refSum = (100 * 101) / 2; assertEquals(refSum / 100.0, stats.getMean(), 1E-10); double[] v = stats.getValues(); for (int i = 0; i < v.length; ++i) { assertEquals(100.0 - i, v[i], 1.0e-10); } double[] s = stats.getSortedValues(); for (int i = 0; i < s.length; ++i) { assertEquals(i + 1.0, s[i], 1.0e-10); } assertEquals(12.0, stats.getElement(88), 1.0e-10); } public void testToString() { DescriptiveStatistics stats = createDescriptiveStatistics(); stats.addValue(1); stats.addValue(2); stats.addValue(3); Locale d = Locale.getDefault(); Locale.setDefault(Locale.US); assertEquals("DescriptiveStatistics:\n" + "n: 3\n" + "min: 1.0\n" + "max: 3.0\n" + "mean: 2.0\n" + "std dev: 1.0\n" + "median: 2.0\n" + "skewness: 0.0\n" + "kurtosis: NaN\n", stats.toString()); Locale.setDefault(d); } public void testShuffledStatistics() { // the purpose of this test is only to check the get/set methods // we are aware shuffling statistics like this is really not // something sensible to do in production ... DescriptiveStatistics reference = createDescriptiveStatistics(); DescriptiveStatistics shuffled = createDescriptiveStatistics(); UnivariateStatistic tmp = shuffled.getGeometricMeanImpl(); shuffled.setGeometricMeanImpl(shuffled.getMeanImpl()); shuffled.setMeanImpl(shuffled.getKurtosisImpl()); shuffled.setKurtosisImpl(shuffled.getSkewnessImpl()); shuffled.setSkewnessImpl(shuffled.getVarianceImpl()); shuffled.setVarianceImpl(shuffled.getMaxImpl()); shuffled.setMaxImpl(shuffled.getMinImpl()); shuffled.setMinImpl(shuffled.getSumImpl()); shuffled.setSumImpl(shuffled.getSumsqImpl()); shuffled.setSumsqImpl(tmp); for (int i = 100; i > 0; --i) { reference.addValue(i); shuffled.addValue(i); } assertEquals(reference.getMean(), shuffled.getGeometricMean(), 1.0e-10); assertEquals(reference.getKurtosis(), shuffled.getMean(), 1.0e-10); assertEquals(reference.getSkewness(), shuffled.getKurtosis(), 1.0e-10); assertEquals(reference.getVariance(), shuffled.getSkewness(), 1.0e-10); assertEquals(reference.getMax(), shuffled.getVariance(), 1.0e-10); assertEquals(reference.getMin(), shuffled.getMax(), 1.0e-10); assertEquals(reference.getSum(), shuffled.getMin(), 1.0e-10); assertEquals(reference.getSumsq(), shuffled.getSum(), 1.0e-10); assertEquals(reference.getGeometricMean(), shuffled.getSumsq(), 1.0e-10); } public void testPercentileSetter() throws Exception { DescriptiveStatistics stats = createDescriptiveStatistics(); stats.addValue(1); stats.addValue(2); stats.addValue(3); assertEquals(2, stats.getPercentile(50.0), 1E-10); // Inject wrapped Percentile impl stats.setPercentileImpl(new goodPercentile()); assertEquals(2, stats.getPercentile(50.0), 1E-10); // Try "new math" impl stats.setPercentileImpl(new subPercentile()); assertEquals(10.0, stats.getPercentile(10.0), 1E-10); // Try to set bad impl try { stats.setPercentileImpl(new badPercentile()); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void test20090720() { DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(100); for (int i = 0; i < 161; i++) { descriptiveStatistics.addValue(1.2); } descriptiveStatistics.clear(); descriptiveStatistics.addValue(1.2); assertEquals(1, descriptiveStatistics.getN()); } public void testRemoval() { final DescriptiveStatistics dstat = createDescriptiveStatistics(); checkremoval(dstat, 1, 6.0, 0.0, Double.NaN); checkremoval(dstat, 3, 5.0, 3.0, 4.5); checkremoval(dstat, 6, 3.5, 2.5, 3.0); checkremoval(dstat, 9, 3.5, 2.5, 3.0); checkremoval(dstat, DescriptiveStatistics.INFINITE_WINDOW, 3.5, 2.5, 3.0); } public void checkremoval(DescriptiveStatistics dstat, int wsize, double mean1, double mean2, double mean3) { dstat.setWindowSize(wsize); dstat.clear(); for (int i = 1 ; i <= 6 ; ++i) { dstat.addValue(i); } assertTrue(MathUtils.equalsIncludingNaN(mean1, dstat.getMean())); dstat.replaceMostRecentValue(0); assertTrue(MathUtils.equalsIncludingNaN(mean2, dstat.getMean())); dstat.removeMostRecentValue(); assertTrue(MathUtils.equalsIncludingNaN(mean3, dstat.getMean())); } // Test UnivariateStatistics impls for setter injection tests /** * A new way to compute the mean */ static class deepMean implements UnivariateStatistic { public double evaluate(double[] values, int begin, int length) { return 42; } public double evaluate(double[] values) { return 42; } public UnivariateStatistic copy() { return new deepMean(); } } /** * Test percentile implementation - wraps a Percentile */ static class goodPercentile implements UnivariateStatistic { private Percentile percentile = new Percentile(); public void setQuantile(double quantile) { percentile.setQuantile(quantile); } public double evaluate(double[] values, int begin, int length) { return percentile.evaluate(values, begin, length); } public double evaluate(double[] values) { return percentile.evaluate(values); } public UnivariateStatistic copy() { goodPercentile result = new goodPercentile(); result.setQuantile(percentile.getQuantile()); return result; } } /** * Test percentile subclass - another "new math" impl * Always returns currently set quantile */ static class subPercentile extends Percentile { @Override public double evaluate(double[] values, int begin, int length) { return getQuantile(); } @Override public double evaluate(double[] values) { return getQuantile(); } private static final long serialVersionUID = 8040701391045914979L; @Override public Percentile copy() { subPercentile result = new subPercentile(); return result; } } /** * "Bad" test percentile implementation - no setQuantile */ static class badPercentile implements UnivariateStatistic { private Percentile percentile = new Percentile(); public double evaluate(double[] values, int begin, int length) { return percentile.evaluate(values, begin, length); } public double evaluate(double[] values) { return percentile.evaluate(values); } public UnivariateStatistic copy() { return new badPercentile(); } } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/ListUnivariateImplTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/ListUnivariateImplTest.j100644 1750 1750 13227 11532241243 32516 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link ListUnivariateImpl} class. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class ListUnivariateImplTest extends TestCase { private double one = 1; private float two = 2; private int three = 3; private double mean = 2; private double sumSq = 18; private double sum = 8; private double var = 0.666666666666666666667; private double std = FastMath.sqrt(var); private double n = 4; private double min = 1; private double max = 3; private double tolerance = 10E-15; public ListUnivariateImplTest(String name) { super(name); } /** test stats */ public void testStats() { List externalList = new ArrayList(); DescriptiveStatistics u = new ListUnivariateImpl( externalList ); assertEquals("total count",0,u.getN(),tolerance); u.addValue(one); u.addValue(two); u.addValue(two); u.addValue(three); assertEquals("N",n,u.getN(),tolerance); assertEquals("sum",sum,u.getSum(),tolerance); assertEquals("sumsq",sumSq,u.getSumsq(),tolerance); assertEquals("var",var,u.getVariance(),tolerance); assertEquals("std",std,u.getStandardDeviation(),tolerance); assertEquals("mean",mean,u.getMean(),tolerance); assertEquals("min",min,u.getMin(),tolerance); assertEquals("max",max,u.getMax(),tolerance); u.clear(); assertEquals("total count",0,u.getN(),tolerance); } public void testN0andN1Conditions() throws Exception { List list = new ArrayList(); DescriptiveStatistics u = new ListUnivariateImpl( list ); assertTrue("Mean of n = 0 set should be NaN", Double.isNaN( u.getMean() ) ); assertTrue("Standard Deviation of n = 0 set should be NaN", Double.isNaN( u.getStandardDeviation() ) ); assertTrue("Variance of n = 0 set should be NaN", Double.isNaN(u.getVariance() ) ); list.add( Double.valueOf(one)); assertTrue( "Mean of n = 1 set should be value of single item n1", u.getMean() == one); assertTrue( "StdDev of n = 1 set should be zero, instead it is: " + u.getStandardDeviation(), u.getStandardDeviation() == 0); assertTrue( "Variance of n = 1 set should be zero", u.getVariance() == 0); } public void testSkewAndKurtosis() { DescriptiveStatistics u = new DescriptiveStatistics(); double[] testArray = { 12.5, 12, 11.8, 14.2, 14.9, 14.5, 21, 8.2, 10.3, 11.3, 14.1, 9.9, 12.2, 12, 12.1, 11, 19.8, 11, 10, 8.8, 9, 12.3 }; for( int i = 0; i < testArray.length; i++) { u.addValue( testArray[i]); } assertEquals("mean", 12.40455, u.getMean(), 0.0001); assertEquals("variance", 10.00236, u.getVariance(), 0.0001); assertEquals("skewness", 1.437424, u.getSkewness(), 0.0001); assertEquals("kurtosis", 2.37719, u.getKurtosis(), 0.0001); } public void testProductAndGeometricMean() throws Exception { ListUnivariateImpl u = new ListUnivariateImpl(new ArrayList()); u.setWindowSize(10); u.addValue( 1.0 ); u.addValue( 2.0 ); u.addValue( 3.0 ); u.addValue( 4.0 ); assertEquals( "Geometric mean not expected", 2.213364, u.getGeometricMean(), 0.00001 ); // Now test rolling - StorelessDescriptiveStatistics should discount the contribution // of a discarded element for( int i = 0; i < 10; i++ ) { u.addValue( i + 2 ); } // Values should be (2,3,4,5,6,7,8,9,10,11) assertEquals( "Geometric mean not expected", 5.755931, u.getGeometricMean(), 0.00001 ); } /** test stats */ public void testSerialization() { DescriptiveStatistics u = new ListUnivariateImpl(); assertEquals("total count",0,u.getN(),tolerance); u.addValue(one); u.addValue(two); DescriptiveStatistics u2 = (DescriptiveStatistics)TestUtils.serializeAndRecover(u); u2.addValue(two); u2.addValue(three); assertEquals("N",n,u2.getN(),tolerance); assertEquals("sum",sum,u2.getSum(),tolerance); assertEquals("sumsq",sumSq,u2.getSumsq(),tolerance); assertEquals("var",var,u2.getVariance(),tolerance); assertEquals("std",std,u2.getStandardDeviation(),tolerance); assertEquals("mean",mean,u2.getMean(),tolerance); assertEquals("min",min,u2.getMin(),tolerance); assertEquals("max",max,u2.getMax(),tolerance); u2.clear(); assertEquals("total count",0,u2.getN(),tolerance); } } ././@LongLink100644 0 0 172 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatisticAbstractTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStati100644 1750 1750 20026 11532241243 32654 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.moment.SecondMoment; import org.apache.commons.math.util.FastMath; /** * Test cases for {@link StorelessUnivariateStatistic} classes. * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class StorelessUnivariateStatisticAbstractTest extends UnivariateStatisticAbstractTest { public StorelessUnivariateStatisticAbstractTest(String name) { super(name); } /** Small sample arrays */ protected double[][] smallSamples = {{}, {1}, {1,2}, {1,2,3}, {1,2,3,4}}; /** Return a new instance of the statistic */ @Override public abstract UnivariateStatistic getUnivariateStatistic(); /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */ @Override public abstract double expectedValue(); /** * Verifies that increment() and incrementAll work properly. */ public void testIncrementation() throws Exception { StorelessUnivariateStatistic statistic = (StorelessUnivariateStatistic) getUnivariateStatistic(); // Add testArray one value at a time and check result for (int i = 0; i < testArray.length; i++) { statistic.increment(testArray[i]); } assertEquals(expectedValue(), statistic.getResult(), getTolerance()); assertEquals(testArray.length, statistic.getN()); statistic.clear(); // Add testArray all at once and check again statistic.incrementAll(testArray); assertEquals(expectedValue(), statistic.getResult(), getTolerance()); assertEquals(testArray.length, statistic.getN()); statistic.clear(); // Cleared assertTrue(Double.isNaN(statistic.getResult())); assertEquals(0, statistic.getN()); } public void testSerialization() throws Exception { StorelessUnivariateStatistic statistic = (StorelessUnivariateStatistic) getUnivariateStatistic(); TestUtils.checkSerializedEquality(statistic); statistic.clear(); for (int i = 0; i < testArray.length; i++) { statistic.increment(testArray[i]); if(i % 5 == 0) statistic = (StorelessUnivariateStatistic)TestUtils.serializeAndRecover(statistic); } TestUtils.checkSerializedEquality(statistic); assertEquals(expectedValue(), statistic.getResult(), getTolerance()); statistic.clear(); assertTrue(Double.isNaN(statistic.getResult())); } public void testEqualsAndHashCode() { StorelessUnivariateStatistic statistic = (StorelessUnivariateStatistic) getUnivariateStatistic(); StorelessUnivariateStatistic statistic2 = null; assertTrue("non-null, compared to null", !statistic.equals(statistic2)); assertTrue("reflexive, non-null", statistic.equals(statistic)); int emptyHash = statistic.hashCode(); statistic2 = (StorelessUnivariateStatistic) getUnivariateStatistic(); assertTrue("empty stats should be equal", statistic.equals(statistic2)); assertEquals("empty stats should have the same hashcode", emptyHash, statistic2.hashCode()); statistic.increment(1d); assertTrue("reflexive, non-empty", statistic.equals(statistic)); assertTrue("non-empty, compared to empty", !statistic.equals(statistic2)); assertTrue("non-empty, compared to empty", !statistic2.equals(statistic)); assertTrue("non-empty stat should have different hashcode from empty stat", statistic.hashCode() != emptyHash); statistic2.increment(1d); assertTrue("stats with same data should be equal", statistic.equals(statistic2)); assertEquals("stats with same data should have the same hashcode", statistic.hashCode(), statistic2.hashCode()); statistic.increment(Double.POSITIVE_INFINITY); assertTrue("stats with different n's should not be equal", !statistic2.equals(statistic)); assertTrue("stats with different n's should have different hashcodes", statistic.hashCode() != statistic2.hashCode()); statistic2.increment(Double.POSITIVE_INFINITY); assertTrue("stats with same data should be equal", statistic.equals(statistic2)); assertEquals("stats with same data should have the same hashcode", statistic.hashCode(), statistic2.hashCode()); statistic.clear(); statistic2.clear(); assertTrue("cleared stats should be equal", statistic.equals(statistic2)); assertEquals("cleared stats should have thashcode of empty stat", emptyHash, statistic2.hashCode()); assertEquals("cleared stats should have thashcode of empty stat", emptyHash, statistic.hashCode()); } public void testMomentSmallSamples() { UnivariateStatistic stat = getUnivariateStatistic(); if (stat instanceof SecondMoment) { SecondMoment moment = (SecondMoment) getUnivariateStatistic(); assertTrue(Double.isNaN(moment.getResult())); moment.increment(1d); assertEquals(0d, moment.getResult(), 0); } } /** * Make sure that evaluate(double[]) and inrementAll(double[]), * getResult() give same results. */ public void testConsistency() { StorelessUnivariateStatistic stat = (StorelessUnivariateStatistic) getUnivariateStatistic(); stat.incrementAll(testArray); assertEquals(stat.getResult(), stat.evaluate(testArray), getTolerance()); for (int i = 0; i < smallSamples.length; i++) { stat.clear(); for (int j =0; j < smallSamples[i].length; j++) { stat.increment(smallSamples[i][j]); } TestUtils.assertEquals(stat.getResult(), stat.evaluate(smallSamples[i]), getTolerance()); } } /** * Verifies that copied statistics remain equal to originals when * incremented the same way. * */ public void testCopyConsistency() { StorelessUnivariateStatistic master = (StorelessUnivariateStatistic) getUnivariateStatistic(); StorelessUnivariateStatistic replica = null; // Randomly select a portion of testArray to load first long index = FastMath.round((FastMath.random()) * testArray.length); // Put first half in master and copy master to replica master.incrementAll(testArray, 0, (int) index); replica = master.copy(); // Check same assertTrue(replica.equals(master)); assertTrue(master.equals(replica)); // Now add second part to both and check again master.incrementAll(testArray, (int) index, (int) (testArray.length - index)); replica.incrementAll(testArray, (int) index, (int) (testArray.length - index)); assertTrue(replica.equals(master)); assertTrue(master.equals(replica)); } public void testSerial() { StorelessUnivariateStatistic s = (StorelessUnivariateStatistic) getUnivariateStatistic(); assertEquals(s, TestUtils.serializeAndRecover(s)); } } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStati100644 1750 1750 2453 11532241243 32662 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Test cases for the {@link SynchronizedSummaryStatisticsTest} class. * @version $Revision: 902201 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug * 2007) $ */ public final class SynchronizedSummaryStatisticsTest extends SummaryStatisticsTest { public SynchronizedSummaryStatisticsTest(String name) { super(name); } @Override protected SummaryStatistics createSummaryStatistics() { return new SynchronizedSummaryStatistics(); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviationTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation100644 1750 1750 6265 11532241243 32527 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link UnivariateStatistic} class. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class StandardDeviationTest extends StorelessUnivariateStatisticAbstractTest{ protected StandardDeviation stat; /** * @param name */ public StandardDeviationTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new StandardDeviation(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.std; } /** * Make sure Double.NaN is returned iff n = 0 * */ public void testNaN() { StandardDeviation std = new StandardDeviation(); assertTrue(Double.isNaN(std.getResult())); std.increment(1d); assertEquals(0d, std.getResult(), 0); } /** * Test population version of variance */ public void testPopulation() { double[] values = {-1.0d, 3.1d, 4.0d, -2.1d, 22d, 11.7d, 3d, 14d}; double sigma = populationStandardDeviation(values); SecondMoment m = new SecondMoment(); m.evaluate(values); // side effect is to add values StandardDeviation s1 = new StandardDeviation(); s1.setBiasCorrected(false); assertEquals(sigma, s1.evaluate(values), 1E-14); s1.incrementAll(values); assertEquals(sigma, s1.getResult(), 1E-14); s1 = new StandardDeviation(false, m); assertEquals(sigma, s1.getResult(), 1E-14); s1 = new StandardDeviation(false); assertEquals(sigma, s1.evaluate(values), 1E-14); s1.incrementAll(values); assertEquals(sigma, s1.getResult(), 1E-14); } /** * Definitional formula for population standard deviation */ protected double populationStandardDeviation(double[] v) { double mean = new Mean().evaluate(v); double sum = 0; for (int i = 0; i < v.length; i++) { sum += (v[i] - mean) * (v[i] - mean); } return FastMath.sqrt(sum / v.length); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/FirstMomentTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/FirstMomentTest.j100644 1750 1750 3503 11532241243 32453 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link FirstMoment} class. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class FirstMomentTest extends StorelessUnivariateStatisticAbstractTest{ /** descriptive statistic. */ protected FirstMoment stat; /** * @param name */ public FirstMomentTest(String name) { super(name); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#getUnivariateStatistic() */ @Override public UnivariateStatistic getUnivariateStatistic() { return new FirstMoment(); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#expectedValue() */ @Override public double expectedValue() { return this.mean; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/KurtosisTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/KurtosisTest.java100644 1750 1750 4175 11532241243 32525 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class KurtosisTest extends StorelessUnivariateStatisticAbstractTest{ protected Kurtosis stat; /** * @param name */ public KurtosisTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Kurtosis(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.kurt; } /** * Make sure Double.NaN is returned iff n < 4 * */ public void testNaN() { Kurtosis kurt = new Kurtosis(); assertTrue(Double.isNaN(kurt.getResult())); kurt.increment(1d); assertTrue(Double.isNaN(kurt.getResult())); kurt.increment(1d); assertTrue(Double.isNaN(kurt.getResult())); kurt.increment(1d); assertTrue(Double.isNaN(kurt.getResult())); kurt.increment(1d); assertFalse(Double.isNaN(kurt.getResult())); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/ThirdMomentTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/ThirdMomentTest.j100644 1750 1750 3510 11532241243 32434 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link ThirdMoment} class. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class ThirdMomentTest extends StorelessUnivariateStatisticAbstractTest{ /** descriptive statistic. */ protected ThirdMoment stat; /** * @param name */ public ThirdMomentTest(String name) { super(name); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#getUnivariateStatistic() */ @Override public UnivariateStatistic getUnivariateStatistic() { return new ThirdMoment(); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#expectedValue() */ @Override public double expectedValue() { return this.thirdMoment; } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovarianceTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovarian100644 1750 1750 6317 11532241243 32535 0ustarlucluc 0 0 //Licensed to the Apache Software Foundation (ASF) under one //or more contributor license agreements. See the NOTICE file //distributed with this work for additional information //regarding copyright ownership. The ASF licenses this file //to you under the Apache License, Version 2.0 (the //"License"); you may not use this file except in compliance //with the License. You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, //software distributed under the License is distributed on an //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY //KIND, either express or implied. See the License for the //specific language governing permissions and limitations //under the License. package org.apache.commons.math.stat.descriptive.moment; import junit.framework.TestCase; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.RealMatrix; public class VectorialCovarianceTest extends TestCase { public VectorialCovarianceTest(String name) { super(name); points = null; } public void testMismatch() { try { new VectorialCovariance(8, true).increment(new double[5]); fail("an exception should have been thrown"); } catch (DimensionMismatchException dme) { assertEquals(5, dme.getDimension1()); assertEquals(8, dme.getDimension2()); } } public void testSimplistic() throws DimensionMismatchException { VectorialCovariance stat = new VectorialCovariance(2, true); stat.increment(new double[] {-1.0, 1.0}); stat.increment(new double[] { 1.0, -1.0}); RealMatrix c = stat.getResult(); assertEquals( 2.0, c.getEntry(0, 0), 1.0e-12); assertEquals(-2.0, c.getEntry(1, 0), 1.0e-12); assertEquals( 2.0, c.getEntry(1, 1), 1.0e-12); } public void testBasicStats() throws DimensionMismatchException { VectorialCovariance stat = new VectorialCovariance(points[0].length, true); for (int i = 0; i < points.length; ++i) { stat.increment(points[i]); } assertEquals(points.length, stat.getN()); RealMatrix c = stat.getResult(); double[][] refC = new double[][] { { 8.0470, -1.9195, -3.4445}, {-1.9195, 1.0470, 3.2795}, {-3.4445, 3.2795, 12.2070} }; for (int i = 0; i < c.getRowDimension(); ++i) { for (int j = 0; j <= i; ++j) { assertEquals(refC[i][j], c.getEntry(i, j), 1.0e-12); } } } public void testSerial(){ VectorialCovariance stat = new VectorialCovariance(points[0].length, true); assertEquals(stat, TestUtils.serializeAndRecover(stat)); } @Override public void setUp() { points = new double[][] { { 1.2, 2.3, 4.5}, {-0.7, 2.3, 5.0}, { 3.1, 0.0, -3.1}, { 6.0, 1.2, 4.2}, {-0.7, 2.3, 5.0} }; } @Override public void tearDown() { points = null; } private double [][] points; } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest100644 1750 1750 5676 11532241243 32522 0ustarlucluc 0 0 //Licensed to the Apache Software Foundation (ASF) under one //or more contributor license agreements. See the NOTICE file //distributed with this work for additional information //regarding copyright ownership. The ASF licenses this file //to you under the Apache License, Version 2.0 (the //"License"); you may not use this file except in compliance //with the License. You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, //software distributed under the License is distributed on an //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY //KIND, either express or implied. See the License for the //specific language governing permissions and limitations //under the License. package org.apache.commons.math.stat.descriptive.moment; import junit.framework.TestCase; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.TestUtils; public class VectorialMeanTest extends TestCase { public VectorialMeanTest(String name) { super(name); points = null; } public void testMismatch() { try { new VectorialMean(8).increment(new double[5]); fail("an exception should have been thrown"); } catch (DimensionMismatchException dme) { assertEquals(5, dme.getDimension1()); assertEquals(8, dme.getDimension2()); } } public void testSimplistic() throws DimensionMismatchException { VectorialMean stat = new VectorialMean(2); stat.increment(new double[] {-1.0, 1.0}); stat.increment(new double[] { 1.0, -1.0}); double[] mean = stat.getResult(); assertEquals(0.0, mean[0], 1.0e-12); assertEquals(0.0, mean[1], 1.0e-12); } public void testBasicStats() throws DimensionMismatchException { VectorialMean stat = new VectorialMean(points[0].length); for (int i = 0; i < points.length; ++i) { stat.increment(points[i]); } assertEquals(points.length, stat.getN()); double[] mean = stat.getResult(); double[] refMean = new double[] { 1.78, 1.62, 3.12}; for (int i = 0; i < mean.length; ++i) { assertEquals(refMean[i], mean[i], 1.0e-12); } } public void testSerial() throws DimensionMismatchException { VectorialMean stat = new VectorialMean(points[0].length); for (int i = 0; i < points.length; ++i) { stat.increment(points[i]); } assertEquals(stat, TestUtils.serializeAndRecover(stat)); } @Override public void setUp() { points = new double[][] { { 1.2, 2.3, 4.5}, {-0.7, 2.3, 5.0}, { 3.1, 0.0, -3.1}, { 6.0, 1.2, 4.2}, {-0.7, 2.3, 5.0} }; } @Override public void tearDown() { points = null; } private double [][] points; } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VarianceTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/VarianceTest.java100644 1750 1750 10126 11532241243 32443 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.util.MathUtils; /** * Test cases for the {@link UnivariateStatistic} class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class VarianceTest extends StorelessUnivariateStatisticAbstractTest{ protected Variance stat; /** * @param name */ public VarianceTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Variance(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.var; } /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */ public double expectedWeightedValue() { return this.weightedVar; } /** * Make sure Double.NaN is returned iff n = 0 * */ public void testNaN() { StandardDeviation std = new StandardDeviation(); assertTrue(Double.isNaN(std.getResult())); std.increment(1d); assertEquals(0d, std.getResult(), 0); } /** * Test population version of variance */ public void testPopulation() { double[] values = {-1.0d, 3.1d, 4.0d, -2.1d, 22d, 11.7d, 3d, 14d}; SecondMoment m = new SecondMoment(); m.evaluate(values); // side effect is to add values Variance v1 = new Variance(); v1.setBiasCorrected(false); assertEquals(populationVariance(values), v1.evaluate(values), 1E-14); v1.incrementAll(values); assertEquals(populationVariance(values), v1.getResult(), 1E-14); v1 = new Variance(false, m); assertEquals(populationVariance(values), v1.getResult(), 1E-14); v1 = new Variance(false); assertEquals(populationVariance(values), v1.evaluate(values), 1E-14); v1.incrementAll(values); assertEquals(populationVariance(values), v1.getResult(), 1E-14); } /** * Definitional formula for population variance */ protected double populationVariance(double[] v) { double mean = new Mean().evaluate(v); double sum = 0; for (int i = 0; i < v.length; i++) { sum += (v[i] - mean) * (v[i] - mean); } return sum / v.length; } public void testWeightedVariance() { Variance variance = new Variance(); assertEquals(expectedWeightedValue(), variance.evaluate(testArray, testWeightsArray, 0, testArray.length), getTolerance()); // All weights = 1 -> weighted variance = unweighted variance assertEquals(expectedValue(), variance.evaluate(testArray, unitWeightsArray, 0, testArray.length), getTolerance()); // All weights the same -> when weights are normalized to sum to the length of the values array, // weighted variance = unweighted value assertEquals(expectedValue(), variance.evaluate(testArray, MathUtils.normalizeArray(identicalWeightsArray, testArray.length), 0, testArray.length), getTolerance()); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/GeometricMeanTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/GeometricMeanTest100644 1750 1750 5116 11532241243 32475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class GeometricMeanTest extends StorelessUnivariateStatisticAbstractTest{ protected GeometricMean stat; /** * @param name */ public GeometricMeanTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new GeometricMean(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.geoMean; } public void testSpecialValues() { GeometricMean mean = new GeometricMean(); // empty assertTrue(Double.isNaN(mean.getResult())); // finite data mean.increment(1d); assertFalse(Double.isNaN(mean.getResult())); // add 0 -- makes log sum blow to minus infinity, should make 0 mean.increment(0d); assertEquals(0d, mean.getResult(), 0); // add positive infinity - note the minus infinity above mean.increment(Double.POSITIVE_INFINITY); assertTrue(Double.isNaN(mean.getResult())); // clear mean.clear(); assertTrue(Double.isNaN(mean.getResult())); // positive infinity by itself mean.increment(Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, mean.getResult(), 0); // negative value -- should make NaN mean.increment(-2d); assertTrue(Double.isNaN(mean.getResult())); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SecondMomentTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SecondMomentTest.100644 1750 1750 3521 11532241243 32425 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link SecondMoment} class. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SecondMomentTest extends StorelessUnivariateStatisticAbstractTest { /** descriptive statistic. */ protected SecondMoment stat; /** * @param name */ public SecondMomentTest(String name) { super(name); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#getUnivariateStatistic() */ @Override public UnivariateStatistic getUnivariateStatistic() { return new SecondMoment(); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#expectedValue() */ @Override public double expectedValue() { return this.secondMoment; } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SemiVarianceTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SemiVarianceTest.100644 1750 1750 14055 11532241243 32424 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.StatUtils; import junit.framework.TestCase; public class SemiVarianceTest extends TestCase { public void testInsufficientData() { double[] nothing = null; SemiVariance sv = new SemiVariance(); try { sv.evaluate(nothing); fail("null is not a valid data array."); } catch (IllegalArgumentException iae) { } try { sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE); sv.evaluate(nothing); fail("null is not a valid data array."); } catch (IllegalArgumentException iae) { } nothing = new double[] {}; assertTrue(Double.isNaN(sv.evaluate(nothing))); } public void testSingleDown() { SemiVariance sv = new SemiVariance(); double[] values = { 50.0d }; double singletest = sv.evaluate(values); assertEquals(0.0d, singletest, 0); } public void testSingleUp() { SemiVariance sv = new SemiVariance(SemiVariance.UPSIDE_VARIANCE); double[] values = { 50.0d }; double singletest = sv.evaluate(values); assertEquals(0.0d, singletest, 0); } public void testSample() { final double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d }; final int length = values.length; final double mean = StatUtils.mean(values); // 6.333... final SemiVariance sv = new SemiVariance(); // Default bias correction is true final double downsideSemiVariance = sv.evaluate(values); // Downside is the default assertEquals(TestUtils.sumSquareDev(new double[] {-2d, 2d, 4d, -2d, 3d, 5d}, mean) / (length - 1), downsideSemiVariance, 1E-14); sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE); final double upsideSemiVariance = sv.evaluate(values); assertEquals(TestUtils.sumSquareDev(new double[] {22d, 11d, 14d}, mean) / (length - 1), upsideSemiVariance, 1E-14); // Verify that upper + lower semivariance against the mean sum to variance assertEquals(StatUtils.variance(values), downsideSemiVariance + upsideSemiVariance, 10e-12); } public void testPopulation() { double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d }; SemiVariance sv = new SemiVariance(false); double singletest = sv.evaluate(values); assertEquals(19.556d, singletest, 0.01d); sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE); singletest = sv.evaluate(values); assertEquals(36.222d, singletest, 0.01d); } public void testNonMeanCutoffs() { double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d }; SemiVariance sv = new SemiVariance(false); // Turn off bias correction - use df = length double singletest = sv.evaluate(values, 1.0d, SemiVariance.DOWNSIDE_VARIANCE, false, 0, values.length); assertEquals(TestUtils.sumSquareDev(new double[] { -2d, -2d }, 1.0d) / values.length, singletest, 0.01d); singletest = sv.evaluate(values, 3.0d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length); assertEquals(TestUtils.sumSquareDev(new double[] { 4d, 22d, 11d, 14d, 5d }, 3.0d) / values.length, singletest, 0.01d); } /** * Check that the lower + upper semivariance against the mean sum to the * variance. */ public void testVarianceDecompMeanCutoff() { double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d }; double variance = StatUtils.variance(values); SemiVariance sv = new SemiVariance(true); // Bias corrected sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE); final double lower = sv.evaluate(values); sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE); final double upper = sv.evaluate(values); assertEquals(variance, lower + upper, 10e-12); } /** * Check that upper and lower semivariances against a cutoff sum to the sum * of squared deviations of the full set of values against the cutoff * divided by df = length - 1 (assuming bias-corrected). */ public void testVarianceDecompNonMeanCutoff() { double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d }; double target = 0; double totalSumOfSquares = TestUtils.sumSquareDev(values, target); SemiVariance sv = new SemiVariance(true); // Bias corrected sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE); double lower = sv.evaluate(values, target); sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE); double upper = sv.evaluate(values, target); assertEquals(totalSumOfSquares / (values.length - 1), lower + upper, 10e-12); } public void testNoVariance() { final double[] values = {100d, 100d, 100d, 100d}; SemiVariance sv = new SemiVariance(); assertEquals(0, sv.evaluate(values), 10E-12); assertEquals(0, sv.evaluate(values, 100d), 10E-12); assertEquals(0, sv.evaluate(values, 100d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length), 10E-12); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/FourthMomentTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/FourthMomentTest.100644 1750 1750 3517 11532241243 32466 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link FourthMoment} class. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class FourthMomentTest extends StorelessUnivariateStatisticAbstractTest{ /** descriptive statistic. */ protected FourthMoment stat; /** * @param name */ public FourthMomentTest(String name) { super(name); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#getUnivariateStatistic() */ @Override public UnivariateStatistic getUnivariateStatistic() { return new FourthMoment(); } /** * @see org.apache.commons.math.stat.descriptive.UnivariateStatisticAbstractTest#expectedValue() */ @Override public double expectedValue() { return this.fourthMoment; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/MeanTest.java100644 1750 1750 4444 11532241243 31561 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class MeanTest extends StorelessUnivariateStatisticAbstractTest{ protected Mean stat; /** * @param name */ public MeanTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Mean(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.mean; } /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */ public double expectedWeightedValue() { return this.weightedMean; } public void testSmallSamples() { Mean mean = new Mean(); assertTrue(Double.isNaN(mean.getResult())); mean.increment(1d); assertEquals(1d, mean.getResult(), 0); } public void testWeightedMean() { Mean mean = new Mean(); assertEquals(expectedWeightedValue(), mean.evaluate(testArray, testWeightsArray, 0, testArray.length), getTolerance()); assertEquals(expectedValue(), mean.evaluate(testArray, identicalWeightsArray, 0, testArray.length), getTolerance()); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SkewnessTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/moment/SkewnessTest.java100644 1750 1750 4060 11532241243 32475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; /** * Test cases for the {@link UnivariateStatistic} class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class SkewnessTest extends StorelessUnivariateStatisticAbstractTest{ protected Skewness stat; /** * @param name */ public SkewnessTest(String name) { super(name); } /** * {@inheritDoc} */ @Override public UnivariateStatistic getUnivariateStatistic() { return new Skewness(); } /** * {@inheritDoc} */ @Override public double expectedValue() { return this.skew; } /** * Make sure Double.NaN is returned iff n < 3 * */ public void testNaN() { Skewness skew = new Skewness(); assertTrue(Double.isNaN(skew.getResult())); skew.increment(1d); assertTrue(Double.isNaN(skew.getResult())); skew.increment(1d); assertTrue(Double.isNaN(skew.getResult())); skew.increment(1d); assertFalse(Double.isNaN(skew.getResult())); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SummaryStatisticsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/SummaryStatisticsTest.ja100644 1750 1750 25452 11532241243 32605 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link SummaryStatistics} class. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class SummaryStatisticsTest extends TestCase { private double one = 1; private float twoF = 2; private long twoL = 2; private int three = 3; private double mean = 2; private double sumSq = 18; private double sum = 8; private double var = 0.666666666666666666667; private double std = FastMath.sqrt(var); private double n = 4; private double min = 1; private double max = 3; private double tolerance = 10E-15; public SummaryStatisticsTest(String name) { super(name); } protected SummaryStatistics createSummaryStatistics() { return new SummaryStatistics(); } /** test stats */ public void testStats() { SummaryStatistics u = createSummaryStatistics(); assertEquals("total count",0,u.getN(),tolerance); u.addValue(one); u.addValue(twoF); u.addValue(twoL); u.addValue(three); assertEquals("N",n,u.getN(),tolerance); assertEquals("sum",sum,u.getSum(),tolerance); assertEquals("sumsq",sumSq,u.getSumsq(),tolerance); assertEquals("var",var,u.getVariance(),tolerance); assertEquals("std",std,u.getStandardDeviation(),tolerance); assertEquals("mean",mean,u.getMean(),tolerance); assertEquals("min",min,u.getMin(),tolerance); assertEquals("max",max,u.getMax(),tolerance); u.clear(); assertEquals("total count",0,u.getN(),tolerance); } public void testN0andN1Conditions() throws Exception { SummaryStatistics u = createSummaryStatistics(); assertTrue("Mean of n = 0 set should be NaN", Double.isNaN( u.getMean() ) ); assertTrue("Standard Deviation of n = 0 set should be NaN", Double.isNaN( u.getStandardDeviation() ) ); assertTrue("Variance of n = 0 set should be NaN", Double.isNaN(u.getVariance() ) ); /* n=1 */ u.addValue(one); assertTrue("mean should be one (n = 1)", u.getMean() == one); assertTrue("geometric should be one (n = 1) instead it is " + u.getGeometricMean(), u.getGeometricMean() == one); assertTrue("Std should be zero (n = 1)", u.getStandardDeviation() == 0.0); assertTrue("variance should be zero (n = 1)", u.getVariance() == 0.0); /* n=2 */ u.addValue(twoF); assertTrue("Std should not be zero (n = 2)", u.getStandardDeviation() != 0.0); assertTrue("variance should not be zero (n = 2)", u.getVariance() != 0.0); } public void testProductAndGeometricMean() throws Exception { SummaryStatistics u = createSummaryStatistics(); u.addValue( 1.0 ); u.addValue( 2.0 ); u.addValue( 3.0 ); u.addValue( 4.0 ); assertEquals( "Geometric mean not expected", 2.213364, u.getGeometricMean(), 0.00001 ); } public void testNaNContracts() { SummaryStatistics u = createSummaryStatistics(); assertTrue("mean not NaN",Double.isNaN(u.getMean())); assertTrue("min not NaN",Double.isNaN(u.getMin())); assertTrue("std dev not NaN",Double.isNaN(u.getStandardDeviation())); assertTrue("var not NaN",Double.isNaN(u.getVariance())); assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); u.addValue(1.0); assertEquals( "mean not expected", 1.0, u.getMean(), Double.MIN_VALUE); assertEquals( "variance not expected", 0.0, u.getVariance(), Double.MIN_VALUE); assertEquals( "geometric mean not expected", 1.0, u.getGeometricMean(), Double.MIN_VALUE); u.addValue(-1.0); assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); u.addValue(0.0); assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); //FiXME: test all other NaN contract specs } public void testGetSummary() { SummaryStatistics u = createSummaryStatistics(); StatisticalSummary summary = u.getSummary(); verifySummary(u, summary); u.addValue(1d); summary = u.getSummary(); verifySummary(u, summary); u.addValue(2d); summary = u.getSummary(); verifySummary(u, summary); u.addValue(2d); summary = u.getSummary(); verifySummary(u, summary); } public void testSerialization() { SummaryStatistics u = createSummaryStatistics(); // Empty test TestUtils.checkSerializedEquality(u); SummaryStatistics s = (SummaryStatistics) TestUtils.serializeAndRecover(u); StatisticalSummary summary = s.getSummary(); verifySummary(u, summary); // Add some data u.addValue(2d); u.addValue(1d); u.addValue(3d); u.addValue(4d); u.addValue(5d); // Test again TestUtils.checkSerializedEquality(u); s = (SummaryStatistics) TestUtils.serializeAndRecover(u); summary = s.getSummary(); verifySummary(u, summary); } public void testEqualsAndHashCode() { SummaryStatistics u = createSummaryStatistics(); SummaryStatistics t = null; int emptyHash = u.hashCode(); assertTrue("reflexive", u.equals(u)); assertFalse("non-null compared to null", u.equals(t)); assertFalse("wrong type", u.equals(Double.valueOf(0))); t = createSummaryStatistics(); assertTrue("empty instances should be equal", t.equals(u)); assertTrue("empty instances should be equal", u.equals(t)); assertEquals("empty hash code", emptyHash, t.hashCode()); // Add some data to u u.addValue(2d); u.addValue(1d); u.addValue(3d); u.addValue(4d); assertFalse("different n's should make instances not equal", t.equals(u)); assertFalse("different n's should make instances not equal", u.equals(t)); assertTrue("different n's should make hashcodes different", u.hashCode() != t.hashCode()); //Add data in same order to t t.addValue(2d); t.addValue(1d); t.addValue(3d); t.addValue(4d); assertTrue("summaries based on same data should be equal", t.equals(u)); assertTrue("summaries based on same data should be equal", u.equals(t)); assertEquals("summaries based on same data should have same hashcodes", u.hashCode(), t.hashCode()); // Clear and make sure summaries are indistinguishable from empty summary u.clear(); t.clear(); assertTrue("empty instances should be equal", t.equals(u)); assertTrue("empty instances should be equal", u.equals(t)); assertEquals("empty hash code", emptyHash, t.hashCode()); assertEquals("empty hash code", emptyHash, u.hashCode()); } public void testCopy() throws Exception { SummaryStatistics u = createSummaryStatistics(); u.addValue(2d); u.addValue(1d); u.addValue(3d); u.addValue(4d); SummaryStatistics v = new SummaryStatistics(u); assertEquals(u, v); assertEquals(v, u); assertTrue(v.geoMean == v.getGeoMeanImpl()); assertTrue(v.mean == v.getMeanImpl()); assertTrue(v.min == v.getMinImpl()); assertTrue(v.max == v.getMaxImpl()); assertTrue(v.sum == v.getSumImpl()); assertTrue(v.sumsq == v.getSumsqImpl()); assertTrue(v.sumLog == v.getSumLogImpl()); assertTrue(v.variance == v.getVarianceImpl()); // Make sure both behave the same with additional values added u.addValue(7d); u.addValue(9d); u.addValue(11d); u.addValue(23d); v.addValue(7d); v.addValue(9d); v.addValue(11d); v.addValue(23d); assertEquals(u, v); assertEquals(v, u); // Check implementation pointers are preserved u.clear(); u.setSumImpl(new Sum()); SummaryStatistics.copy(u,v); assertEquals(u.sum, v.sum); assertEquals(u.getSumImpl(), v.getSumImpl()); } private void verifySummary(SummaryStatistics u, StatisticalSummary s) { assertEquals("N",s.getN(),u.getN()); TestUtils.assertEquals("sum",s.getSum(),u.getSum(),tolerance); TestUtils.assertEquals("var",s.getVariance(),u.getVariance(),tolerance); TestUtils.assertEquals("std",s.getStandardDeviation(),u.getStandardDeviation(),tolerance); TestUtils.assertEquals("mean",s.getMean(),u.getMean(),tolerance); TestUtils.assertEquals("min",s.getMin(),u.getMin(),tolerance); TestUtils.assertEquals("max",s.getMax(),u.getMax(),tolerance); } public void testSetterInjection() throws Exception { SummaryStatistics u = createSummaryStatistics(); u.setMeanImpl(new Sum()); u.setSumLogImpl(new Sum()); u.addValue(1); u.addValue(3); assertEquals(4, u.getMean(), 1E-14); assertEquals(4, u.getSumOfLogs(), 1E-14); assertEquals(FastMath.exp(2), u.getGeometricMean(), 1E-14); u.clear(); u.addValue(1); u.addValue(2); assertEquals(3, u.getMean(), 1E-14); u.clear(); u.setMeanImpl(new Mean()); // OK after clear } public void testSetterIllegalState() throws Exception { SummaryStatistics u = createSummaryStatistics(); u.addValue(1); u.addValue(3); try { u.setMeanImpl(new Sum()); fail("Expecting IllegalStateException"); } catch (IllegalStateException ex) { // expected } } } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstr100644 1750 1750 15472 11532241243 32640 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * s * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.random.RandomData; import org.apache.commons.math.random.RandomDataImpl; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link UnivariateStatistic} class. * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class UnivariateStatisticAbstractTest extends TestCase { protected double mean = 12.404545454545455d; protected double geoMean = 12.070589161633011d; protected double var = 10.00235930735931d; protected double std = FastMath.sqrt(var); protected double skew = 1.437423729196190d; protected double kurt = 2.377191264804700d; protected double min = 8.2d; protected double max = 21d; protected double median = 12d; protected double percentile5 = 8.29d; protected double percentile95 = 20.82d; protected double product = 628096400563833396009676.9200400128d; protected double sumLog = 54.7969806116451507d; protected double sumSq = 3595.250d; protected double sum = 272.90d; protected double secondMoment = 210.04954545454547d; protected double thirdMoment = 868.0906859504136; protected double fourthMoment = 9244.080993773481; protected double weightedMean = 12.366995073891626d; protected double weightedVar = 9.974760968886391d; protected double weightedStd = FastMath.sqrt(weightedVar); protected double weightedProduct = 8517647448765288000000d; protected double weightedSum = 251.05d; protected double tolerance = 10E-12; protected double[] testArray = { 12.5, 12.0, 11.8, 14.2, 14.9, 14.5, 21.0, 8.2, 10.3, 11.3, 14.1, 9.9, 12.2, 12.0, 12.1, 11.0, 19.8, 11.0, 10.0, 8.8, 9.0, 12.3 }; protected double[] testWeightsArray = { 1.5, 0.8, 1.2, 0.4, 0.8, 1.8, 1.2, 1.1, 1.0, 0.7, 1.3, 0.6, 0.7, 1.3, 0.7, 1.0, 0.4, 0.1, 1.4, 0.9, 1.1, 0.3 }; protected double[] identicalWeightsArray = { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 }; protected double[] unitWeightsArray = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; public UnivariateStatisticAbstractTest(String name) { super(name); } public abstract UnivariateStatistic getUnivariateStatistic(); public abstract double expectedValue(); public double getTolerance() { return tolerance; } public void testEvaluation() throws Exception { assertEquals( expectedValue(), getUnivariateStatistic().evaluate(testArray), getTolerance()); } public void testCopy() throws Exception { UnivariateStatistic original = getUnivariateStatistic(); UnivariateStatistic copy = original.copy(); assertEquals( expectedValue(), copy.evaluate(testArray), getTolerance()); } /** * Tests consistency of weighted statistic computation. * For statistics that support weighted evaluation, this test case compares * the result of direct computation on an array with repeated values with * a weighted computation on the corresponding (shorter) array with each * value appearing only once but with a weight value equal to its multiplicity * in the repeating array. */ public void testWeightedConsistency() throws Exception { // See if this statistic computes weighted statistics // If not, skip this test UnivariateStatistic statistic = getUnivariateStatistic(); if (!(statistic instanceof WeightedEvaluation)) { return; } // Create arrays of values and corresponding integral weights // and longer array with values repeated according to the weights final int len = 10; // length of values array final double mu = 0; // mean of test data final double sigma = 5; // std dev of test data double[] values = new double[len]; double[] weights = new double[len]; RandomData randomData = new RandomDataImpl(); // Fill weights array with random int values between 1 and 5 int[] intWeights = new int[len]; for (int i = 0; i < len; i++) { intWeights[i] = randomData.nextInt(1, 5); weights[i] = intWeights[i]; } // Fill values array with random data from N(mu, sigma) // and fill valuesList with values from values array with // values[i] repeated weights[i] times, each i List valuesList = new ArrayList(); for (int i = 0; i < len; i++) { double value = randomData.nextGaussian(mu, sigma); values[i] = value; for (int j = 0; j < intWeights[i]; j++) { valuesList.add(new Double(value)); } } // Dump valuesList into repeatedValues array int sumWeights = valuesList.size(); double[] repeatedValues = new double[sumWeights]; for (int i = 0; i < sumWeights; i++) { repeatedValues[i] = valuesList.get(i); } // Compare result of weighted statistic computation with direct computation // on array of repeated values WeightedEvaluation weightedStatistic = (WeightedEvaluation) statistic; TestUtils.assertRelativelyEquals(statistic.evaluate(repeatedValues), weightedStatistic.evaluate(values, weights, 0, values.length), 10E-14); // Check consistency of weighted evaluation methods assertEquals(weightedStatistic.evaluate(values, weights, 0, values.length), weightedStatistic.evaluate(values, weights), Double.MIN_VALUE); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/CertifiedDataTest.java100644 1750 1750 12517 11532241243 27571 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat; import java.io.BufferedReader; import java.io.InputStreamReader; import junit.framework.TestCase; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Certified data test cases. * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class CertifiedDataTest extends TestCase { protected double mean = Double.NaN; protected double std = Double.NaN; /** * Certified Data Test Constructor * @param name */ public CertifiedDataTest(String name) { super(name); } /** * Test SummaryStatistics - implementations that do not store the data * and use single pass algorithms to compute statistics */ public void testSummaryStatistics() throws Exception { SummaryStatistics u = new SummaryStatistics(); loadStats("data/PiDigits.txt", u); assertEquals("PiDigits: std", std, u.getStandardDeviation(), 1E-13); assertEquals("PiDigits: mean", mean, u.getMean(), 1E-13); loadStats("data/Mavro.txt", u); assertEquals("Mavro: std", std, u.getStandardDeviation(), 1E-14); assertEquals("Mavro: mean", mean, u.getMean(), 1E-14); loadStats("data/Michelso.txt", u); assertEquals("Michelso: std", std, u.getStandardDeviation(), 1E-13); assertEquals("Michelso: mean", mean, u.getMean(), 1E-13); loadStats("data/NumAcc1.txt", u); assertEquals("NumAcc1: std", std, u.getStandardDeviation(), 1E-14); assertEquals("NumAcc1: mean", mean, u.getMean(), 1E-14); loadStats("data/NumAcc2.txt", u); assertEquals("NumAcc2: std", std, u.getStandardDeviation(), 1E-14); assertEquals("NumAcc2: mean", mean, u.getMean(), 1E-14); } /** * Test DescriptiveStatistics - implementations that store full array of * values and execute multi-pass algorithms */ public void testDescriptiveStatistics() throws Exception { DescriptiveStatistics u = new DescriptiveStatistics(); loadStats("data/PiDigits.txt", u); assertEquals("PiDigits: std", std, u.getStandardDeviation(), 1E-14); assertEquals("PiDigits: mean", mean, u.getMean(), 1E-14); loadStats("data/Mavro.txt", u); assertEquals("Mavro: std", std, u.getStandardDeviation(), 1E-14); assertEquals("Mavro: mean", mean, u.getMean(), 1E-14); loadStats("data/Michelso.txt", u); assertEquals("Michelso: std", std, u.getStandardDeviation(), 1E-14); assertEquals("Michelso: mean", mean, u.getMean(), 1E-14); loadStats("data/NumAcc1.txt", u); assertEquals("NumAcc1: std", std, u.getStandardDeviation(), 1E-14); assertEquals("NumAcc1: mean", mean, u.getMean(), 1E-14); loadStats("data/NumAcc2.txt", u); assertEquals("NumAcc2: std", std, u.getStandardDeviation(), 1E-14); assertEquals("NumAcc2: mean", mean, u.getMean(), 1E-14); } /** * loads a DescriptiveStatistics off of a test file * @param file * @param statistical summary */ private void loadStats(String resource, Object u) throws Exception { DescriptiveStatistics d = null; SummaryStatistics s = null; if (u instanceof DescriptiveStatistics) { d = (DescriptiveStatistics) u; } else { s = (SummaryStatistics) u; } u.getClass().getDeclaredMethod( "clear", new Class[]{}).invoke(u, new Object[]{}); mean = Double.NaN; std = Double.NaN; BufferedReader in = new BufferedReader( new InputStreamReader( CertifiedDataTest.class.getResourceAsStream(resource))); String line = null; for (int j = 0; j < 60; j++) { line = in.readLine(); if (j == 40) { mean = Double.parseDouble( line.substring(line.lastIndexOf(":") + 1).trim()); } if (j == 41) { std = Double.parseDouble( line.substring(line.lastIndexOf(":") + 1).trim()); } } line = in.readLine(); while (line != null) { if (d != null) { d.addValue(Double.parseDouble(line.trim())); } else { s.addValue(Double.parseDouble(line.trim())); } line = in.readLine(); } in.close(); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/StatUtilsTest.java100644 1750 1750 36402 11532241243 27034 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.util.FastMath; /** * Test cases for the {@link StatUtils} class. * @version $Revision: 1060124 $ $Date: 2011-01-18 00:00:52 +0100 (mar. 18 janv. 2011) $ */ public final class StatUtilsTest extends TestCase { private double one = 1; private float two = 2; private int three = 3; private double mean = 2; private double sumSq = 18; private double sum = 8; private double var = 0.666666666666666666667; private double min = 1; private double max = 3; private double tolerance = 10E-15; private double nan = Double.NaN; public StatUtilsTest(String name) { super(name); } /** test stats */ public void testStats() { double[] values = new double[] { one, two, two, three }; assertEquals("sum", sum, StatUtils.sum(values), tolerance); assertEquals("sumsq", sumSq, StatUtils.sumSq(values), tolerance); assertEquals("var", var, StatUtils.variance(values), tolerance); assertEquals("var with mean", var, StatUtils.variance(values, mean), tolerance); assertEquals("mean", mean, StatUtils.mean(values), tolerance); assertEquals("min", min, StatUtils.min(values), tolerance); assertEquals("max", max, StatUtils.max(values), tolerance); } public void testN0andN1Conditions() throws Exception { double[] values = new double[0]; assertTrue( "Mean of n = 0 set should be NaN", Double.isNaN(StatUtils.mean(values))); assertTrue( "Variance of n = 0 set should be NaN", Double.isNaN(StatUtils.variance(values))); values = new double[] { one }; assertTrue( "Mean of n = 1 set should be value of single item n1", StatUtils.mean(values) == one); assertTrue( "Variance of n = 1 set should be zero", StatUtils.variance(values) == 0); } public void testArrayIndexConditions() throws Exception { double[] values = { 1.0, 2.0, 3.0, 4.0 }; assertEquals( "Sum not expected", 5.0, StatUtils.sum(values, 1, 2), Double.MIN_VALUE); assertEquals( "Sum not expected", 3.0, StatUtils.sum(values, 0, 2), Double.MIN_VALUE); assertEquals( "Sum not expected", 7.0, StatUtils.sum(values, 2, 2), Double.MIN_VALUE); try { StatUtils.sum(values, 2, 3); fail("Expected RuntimeException"); } catch (RuntimeException e) { // expected } try { StatUtils.sum(values, -1, 2); fail("Expected RuntimeException"); } catch (RuntimeException e) { // expected } } public void testSumSq() { double[] x = null; // test null try { StatUtils.sumSq(x); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } try { StatUtils.sumSq(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x), tolerance); TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(4, StatUtils.sumSq(x), tolerance); TestUtils.assertEquals(4, StatUtils.sumSq(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(18, StatUtils.sumSq(x), tolerance); TestUtils.assertEquals(8, StatUtils.sumSq(x, 1, 2), tolerance); } public void testProduct() { double[] x = null; // test null try { StatUtils.product(x); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } try { StatUtils.product(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.product(x), tolerance); TestUtils.assertEquals(Double.NaN, StatUtils.product(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(two, StatUtils.product(x), tolerance); TestUtils.assertEquals(two, StatUtils.product(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(12, StatUtils.product(x), tolerance); TestUtils.assertEquals(4, StatUtils.product(x, 1, 2), tolerance); } public void testSumLog() { double[] x = null; // test null try { StatUtils.sumLog(x); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } try { StatUtils.sumLog(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x), tolerance); TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(FastMath.log(two), StatUtils.sumLog(x), tolerance); TestUtils.assertEquals(FastMath.log(two), StatUtils.sumLog(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(FastMath.log(one) + 2.0 * FastMath.log(two) + FastMath.log(three), StatUtils.sumLog(x), tolerance); TestUtils.assertEquals(2.0 * FastMath.log(two), StatUtils.sumLog(x, 1, 2), tolerance); } public void testMean() { double[] x = null; try { StatUtils.mean(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.mean(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(two, StatUtils.mean(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(2.5, StatUtils.mean(x, 2, 2), tolerance); } public void testVariance() { double[] x = null; try { StatUtils.variance(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.variance(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(0.0, StatUtils.variance(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(0.5, StatUtils.variance(x, 2, 2), tolerance); // test precomputed mean x = new double[] {one, two, two, three}; TestUtils.assertEquals(0.5, StatUtils.variance(x,2.5, 2, 2), tolerance); } public void testMax() { double[] x = null; try { StatUtils.max(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.max(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(two, StatUtils.max(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(three, StatUtils.max(x, 1, 3), tolerance); // test first nan is ignored x = new double[] {nan, two, three}; TestUtils.assertEquals(three, StatUtils.max(x), tolerance); // test middle nan is ignored x = new double[] {one, nan, three}; TestUtils.assertEquals(three, StatUtils.max(x), tolerance); // test last nan is ignored x = new double[] {one, two, nan}; TestUtils.assertEquals(two, StatUtils.max(x), tolerance); // test all nan returns nan x = new double[] {nan, nan, nan}; TestUtils.assertEquals(nan, StatUtils.max(x), tolerance); } public void testMin() { double[] x = null; try { StatUtils.min(x, 0, 4); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.min(x, 0, 0), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(two, StatUtils.min(x, 0, 1), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(two, StatUtils.min(x, 1, 3), tolerance); // test first nan is ignored x = new double[] {nan, two, three}; TestUtils.assertEquals(two, StatUtils.min(x), tolerance); // test middle nan is ignored x = new double[] {one, nan, three}; TestUtils.assertEquals(one, StatUtils.min(x), tolerance); // test last nan is ignored x = new double[] {one, two, nan}; TestUtils.assertEquals(one, StatUtils.min(x), tolerance); // test all nan returns nan x = new double[] {nan, nan, nan}; TestUtils.assertEquals(nan, StatUtils.min(x), tolerance); } public void testPercentile() { double[] x = null; // test null try { StatUtils.percentile(x, .25); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } try { StatUtils.percentile(x, 0, 4, 0.25); fail("null is not a valid data array."); } catch (IllegalArgumentException ex) { // success } // test empty x = new double[] {}; TestUtils.assertEquals(Double.NaN, StatUtils.percentile(x, 25), tolerance); TestUtils.assertEquals(Double.NaN, StatUtils.percentile(x, 0, 0, 25), tolerance); // test one x = new double[] {two}; TestUtils.assertEquals(two, StatUtils.percentile(x, 25), tolerance); TestUtils.assertEquals(two, StatUtils.percentile(x, 0, 1, 25), tolerance); // test many x = new double[] {one, two, two, three}; TestUtils.assertEquals(2.5, StatUtils.percentile(x, 70), tolerance); TestUtils.assertEquals(2.5, StatUtils.percentile(x, 1, 3, 62.5), tolerance); } public void testDifferenceStats() throws Exception { double sample1[] = {1d, 2d, 3d, 4d}; double sample2[] = {1d, 3d, 4d, 2d}; double diff[] = {0d, -1d, -1d, 2d}; double small[] = {1d, 4d}; double meanDifference = StatUtils.meanDifference(sample1, sample2); assertEquals(StatUtils.sumDifference(sample1, sample2), StatUtils.sum(diff), tolerance); assertEquals(meanDifference, StatUtils.mean(diff), tolerance); assertEquals(StatUtils.varianceDifference(sample1, sample2, meanDifference), StatUtils.variance(diff), tolerance); try { StatUtils.meanDifference(sample1, small); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { StatUtils.varianceDifference(sample1, small, meanDifference); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { double[] single = {1.0}; StatUtils.varianceDifference(single, single, meanDifference); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testGeometricMean() throws Exception { double[] test = null; try { StatUtils.geometricMean(test); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } test = new double[] {2, 4, 6, 8}; assertEquals(FastMath.exp(0.25d * StatUtils.sumLog(test)), StatUtils.geometricMean(test), Double.MIN_VALUE); assertEquals(FastMath.exp(0.5 * StatUtils.sumLog(test, 0, 2)), StatUtils.geometricMean(test, 0, 2), Double.MIN_VALUE); } /** * Run the test with the values 50 and 100 and assume standardized values */ public void testNormalize1() { double sample[] = { 50, 100 }; double expectedSample[] = { -25 / Math.sqrt(1250), 25 / Math.sqrt(1250) }; double[] out = StatUtils.normalize(sample); for (int i = 0; i < out.length; i++) { assertEquals(out[i], expectedSample[i]); } } /** * Run with 77 random values, assuming that the outcome has a mean of 0 and a standard deviation of 1 with a * precision of 1E-10. */ public void testNormalize2() { // create an sample with 77 values int length = 77; double sample[] = new double[length]; for (int i = 0; i < length; i++) { sample[i] = Math.random(); } // normalize this sample double standardizedSample[] = StatUtils.normalize(sample); DescriptiveStatistics stats = new DescriptiveStatistics(); // Add the data from the array for (int i = 0; i < length; i++) { stats.addValue(standardizedSample[i]); } // the calculations do have a limited precision double distance = 1E-10; // check the mean an standard deviation assertEquals(0.0, stats.getMean(), distance); assertEquals(1.0, stats.getStandardDeviation(), distance); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/FrequencyTest.java100644 1750 1750 24752 11532241243 27046 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.Iterator; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; /** * Test cases for the {@link Frequency} class. * * @version $Revision: 1044981 $ $Date: 2010-12-13 01:43:57 +0100 (lun. 13 déc. 2010) $ */ public final class FrequencyTest extends TestCase { private long oneL = 1; private long twoL = 2; private long threeL = 3; private int oneI = 1; private int twoI = 2; private int threeI=3; private double tolerance = 10E-15; private Frequency f = null; public FrequencyTest(String name) { super(name); } @Override public void setUp() { f = new Frequency(); } /** test freq counts */ @SuppressWarnings("deprecation") public void testCounts() { assertEquals("total count",0,f.getSumFreq()); f.addValue(oneL); f.addValue(twoL); f.addValue(1); f.addValue(oneI); assertEquals("one frequency count",3,f.getCount(1)); assertEquals("two frequency count",1,f.getCount(2)); assertEquals("three frequency count",0,f.getCount(3)); assertEquals("total count",4,f.getSumFreq()); assertEquals("zero cumulative frequency", 0, f.getCumFreq(0)); assertEquals("one cumulative frequency", 3, f.getCumFreq(1)); assertEquals("two cumulative frequency", 4, f.getCumFreq(2)); assertEquals("Integer argument cum freq",4, f.getCumFreq(Integer.valueOf(2))); assertEquals("five cumulative frequency", 4, f.getCumFreq(5)); assertEquals("foo cumulative frequency", 0, f.getCumFreq("foo")); f.clear(); assertEquals("total count",0,f.getSumFreq()); // userguide examples ------------------------------------------------------------------- f.addValue("one"); f.addValue("One"); f.addValue("oNe"); f.addValue("Z"); assertEquals("one cumulative frequency", 1 , f.getCount("one")); assertEquals("Z cumulative pct", 0.5, f.getCumPct("Z"), tolerance); assertEquals("z cumulative pct", 1.0, f.getCumPct("z"), tolerance); assertEquals("Ot cumulative pct", 0.25, f.getCumPct("Ot"), tolerance); f.clear(); f = null; Frequency f = new Frequency(); f.addValue(1); f.addValue(Integer.valueOf(1)); f.addValue(Long.valueOf(1)); f.addValue(2); f.addValue(Integer.valueOf(-1)); assertEquals("1 count", 3, f.getCount(1)); assertEquals("1 count", 3, f.getCount(Integer.valueOf(1))); assertEquals("0 cum pct", 0.2, f.getCumPct(0), tolerance); assertEquals("1 pct", 0.6, f.getPct(Integer.valueOf(1)), tolerance); assertEquals("-2 cum pct", 0, f.getCumPct(-2), tolerance); assertEquals("10 cum pct", 1, f.getCumPct(10), tolerance); f = null; f = new Frequency(String.CASE_INSENSITIVE_ORDER); f.addValue("one"); f.addValue("One"); f.addValue("oNe"); f.addValue("Z"); assertEquals("one count", 3 , f.getCount("one")); assertEquals("Z cumulative pct -- case insensitive", 1 , f.getCumPct("Z"), tolerance); assertEquals("z cumulative pct -- case insensitive", 1 , f.getCumPct("z"), tolerance); f = null; f = new Frequency(); assertEquals(0L, f.getCount('a')); assertEquals(0L, f.getCumFreq('b')); TestUtils.assertEquals(Double.NaN, f.getPct('a'), 0.0); TestUtils.assertEquals(Double.NaN, f.getCumPct('b'), 0.0); f.addValue('a'); f.addValue('b'); f.addValue('c'); f.addValue('d'); assertEquals(1L, f.getCount('a')); assertEquals(2L, f.getCumFreq('b')); assertEquals(0.25, f.getPct('a'), 0.0); assertEquals(0.5, f.getCumPct('b'), 0.0); assertEquals(1.0, f.getCumPct('e'), 0.0); } /** test pcts */ @SuppressWarnings("deprecation") public void testPcts() { f.addValue(oneL); f.addValue(twoL); f.addValue(oneI); f.addValue(twoI); f.addValue(threeL); f.addValue(threeL); f.addValue(3); f.addValue(threeI); assertEquals("one pct",0.25,f.getPct(1),tolerance); assertEquals("two pct",0.25,f.getPct(Long.valueOf(2)),tolerance); assertEquals("three pct",0.5,f.getPct(threeL),tolerance); // MATH-329 assertEquals("three (Object) pct",0.5,f.getPct((Object) (Integer.valueOf(3))),tolerance); assertEquals("five pct",0,f.getPct(5),tolerance); assertEquals("foo pct",0,f.getPct("foo"),tolerance); assertEquals("one cum pct",0.25,f.getCumPct(1),tolerance); assertEquals("two cum pct",0.50,f.getCumPct(Long.valueOf(2)),tolerance); assertEquals("Integer argument",0.50,f.getCumPct(Integer.valueOf(2)),tolerance); assertEquals("three cum pct",1.0,f.getCumPct(threeL),tolerance); assertEquals("five cum pct",1.0,f.getCumPct(5),tolerance); assertEquals("zero cum pct",0.0,f.getCumPct(0),tolerance); assertEquals("foo cum pct",0,f.getCumPct("foo"),tolerance); } /** test adding incomparable values */ @SuppressWarnings("deprecation") public void testAdd() { char aChar = 'a'; char bChar = 'b'; String aString = "a"; f.addValue(aChar); f.addValue(bChar); try { f.addValue(aString); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { f.addValue(2); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } assertEquals("a pct",0.5,f.getPct(aChar),tolerance); assertEquals("b cum pct",1.0,f.getCumPct(bChar),tolerance); assertEquals("a string pct",0.0,f.getPct(aString),tolerance); assertEquals("a string cum pct",0.0,f.getCumPct(aString),tolerance); f = new Frequency(); f.addValue("One"); try { f.addValue(new Integer("One")); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } // Check what happens when non-Comparable objects are added @SuppressWarnings("deprecation") public void testAddNonComparable(){ try { f.addValue(new Object()); // This was previously OK fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } f.clear(); f.addValue(1); try { f.addValue(new Object()); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } } /** test empty table */ public void testEmptyTable() { assertEquals("freq sum, empty table", 0, f.getSumFreq()); assertEquals("count, empty table", 0, f.getCount(0)); assertEquals("count, empty table",0, f.getCount(Integer.valueOf(0))); assertEquals("cum freq, empty table", 0, f.getCumFreq(0)); assertEquals("cum freq, empty table", 0, f.getCumFreq("x")); assertTrue("pct, empty table", Double.isNaN(f.getPct(0))); assertTrue("pct, empty table", Double.isNaN(f.getPct(Integer.valueOf(0)))); assertTrue("cum pct, empty table", Double.isNaN(f.getCumPct(0))); assertTrue("cum pct, empty table", Double.isNaN(f.getCumPct(Integer.valueOf(0)))); } /** * Tests toString() */ public void testToString(){ f.addValue(oneL); f.addValue(twoL); f.addValue(oneI); f.addValue(twoI); String s = f.toString(); //System.out.println(s); assertNotNull(s); BufferedReader reader = new BufferedReader(new StringReader(s)); try { String line = reader.readLine(); // header line assertNotNull(line); line = reader.readLine(); // one's or two's line assertNotNull(line); line = reader.readLine(); // one's or two's line assertNotNull(line); line = reader.readLine(); // no more elements assertNull(line); } catch(IOException ex){ fail(ex.getMessage()); } } @SuppressWarnings("deprecation") public void testIntegerValues() { Comparable obj1 = null; obj1 = Integer.valueOf(1); Integer int1 = Integer.valueOf(1); f.addValue(obj1); f.addValue(int1); f.addValue(2); f.addValue(Long.valueOf(2)); assertEquals("Integer 1 count", 2, f.getCount(1)); assertEquals("Integer 1 count", 2, f.getCount(Integer.valueOf(1))); assertEquals("Integer 1 count", 2, f.getCount(Long.valueOf(1))); assertEquals("Integer 1 cumPct", 0.5, f.getCumPct(1), tolerance); assertEquals("Integer 1 cumPct", 0.5, f.getCumPct(Long.valueOf(1)), tolerance); assertEquals("Integer 1 cumPct", 0.5, f.getCumPct(Integer.valueOf(1)), tolerance); Iterator it = f.valuesIterator(); while (it.hasNext()) { assertTrue(it.next() instanceof Long); } } public void testSerial() { f.addValue(oneL); f.addValue(twoL); f.addValue(oneI); f.addValue(twoI); assertEquals(f, TestUtils.serializeAndRecover(f)); } public void testGetUniqueCount() { assertEquals(0, f.getUniqueCount()); f.addValue(oneL); assertEquals(1, f.getUniqueCount()); f.addValue(oneL); assertEquals(1, f.getUniqueCount()); f.addValue(twoI); assertEquals(2, f.getUniqueCount()); } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressi100644 1750 1750 30120 11532241243 32467 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.random.CorrelatedRandomVectorGenerator; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.random.GaussianRandomGenerator; import org.apache.commons.math.random.RandomGenerator; import org.apache.commons.math.stat.correlation.Covariance; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; public class GLSMultipleLinearRegressionTest extends MultipleLinearRegressionAbstractTest { private double[] y; private double[][] x; private double[][] omega; private double[] longley = new double[] { 60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962 }; @Before @Override public void setUp(){ y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; x = new double[6][]; x[0] = new double[]{0, 0, 0, 0, 0}; x[1] = new double[]{2.0, 0, 0, 0, 0}; x[2] = new double[]{0, 3.0, 0, 0, 0}; x[3] = new double[]{0, 0, 4.0, 0, 0}; x[4] = new double[]{0, 0, 0, 5.0, 0}; x[5] = new double[]{0, 0, 0, 0, 6.0}; omega = new double[6][]; omega[0] = new double[]{1.0, 0, 0, 0, 0, 0}; omega[1] = new double[]{0, 2.0, 0, 0, 0, 0}; omega[2] = new double[]{0, 0, 3.0, 0, 0, 0}; omega[3] = new double[]{0, 0, 0, 4.0, 0, 0}; omega[4] = new double[]{0, 0, 0, 0, 5.0, 0}; omega[5] = new double[]{0, 0, 0, 0, 0, 6.0}; super.setUp(); } @Test(expected=IllegalArgumentException.class) public void cannotAddXSampleData() { createRegression().newSampleData(new double[]{}, null, null); } @Test(expected=IllegalArgumentException.class) public void cannotAddNullYSampleData() { createRegression().newSampleData(null, new double[][]{}, null); } @Test(expected=IllegalArgumentException.class) public void cannotAddSampleDataWithSizeMismatch() { double[] y = new double[]{1.0, 2.0}; double[][] x = new double[1][]; x[0] = new double[]{1.0, 0}; createRegression().newSampleData(y, x, null); } @Test(expected=IllegalArgumentException.class) public void cannotAddNullCovarianceData() { createRegression().newSampleData(new double[]{}, new double[][]{}, null); } @Test(expected=IllegalArgumentException.class) public void notEnoughData() { double[] reducedY = new double[y.length - 1]; double[][] reducedX = new double[x.length - 1][]; double[][] reducedO = new double[omega.length - 1][]; System.arraycopy(y, 0, reducedY, 0, reducedY.length); System.arraycopy(x, 0, reducedX, 0, reducedX.length); System.arraycopy(omega, 0, reducedO, 0, reducedO.length); createRegression().newSampleData(reducedY, reducedX, reducedO); } @Test(expected=IllegalArgumentException.class) public void cannotAddCovarianceDataWithSampleSizeMismatch() { double[] y = new double[]{1.0, 2.0}; double[][] x = new double[2][]; x[0] = new double[]{1.0, 0}; x[1] = new double[]{0, 1.0}; double[][] omega = new double[1][]; omega[0] = new double[]{1.0, 0}; createRegression().newSampleData(y, x, omega); } @Test(expected=IllegalArgumentException.class) public void cannotAddCovarianceDataThatIsNotSquare() { double[] y = new double[]{1.0, 2.0}; double[][] x = new double[2][]; x[0] = new double[]{1.0, 0}; x[1] = new double[]{0, 1.0}; double[][] omega = new double[3][]; omega[0] = new double[]{1.0, 0}; omega[1] = new double[]{0, 1.0}; omega[2] = new double[]{0, 2.0}; createRegression().newSampleData(y, x, omega); } @Override protected GLSMultipleLinearRegression createRegression() { GLSMultipleLinearRegression regression = new GLSMultipleLinearRegression(); regression.newSampleData(y, x, omega); return regression; } @Override protected int getNumberOfRegressors() { return x[0].length + 1; } @Override protected int getSampleSize() { return y.length; } /** * test calculateYVariance */ @Test public void testYVariance() { // assumes: y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; GLSMultipleLinearRegression model = new GLSMultipleLinearRegression(); model.newSampleData(y, x, omega); TestUtils.assertEquals(model.calculateYVariance(), 3.5, 0); } /** * Verifies that setting X, Y and covariance separately has the same effect as newSample(X,Y,cov). */ @Test public void testNewSample2() throws Exception { double[] y = new double[] {1, 2, 3, 4}; double[][] x = new double[][] { {19, 22, 33}, {20, 30, 40}, {25, 35, 45}, {27, 37, 47} }; double[][] covariance = MatrixUtils.createRealIdentityMatrix(4).scalarMultiply(2).getData(); GLSMultipleLinearRegression regression = new GLSMultipleLinearRegression(); regression.newSampleData(y, x, covariance); RealMatrix combinedX = regression.X.copy(); RealVector combinedY = regression.Y.copy(); RealMatrix combinedCovInv = regression.getOmegaInverse(); regression.newXSampleData(x); regression.newYSampleData(y); assertEquals(combinedX, regression.X); assertEquals(combinedY, regression.Y); assertEquals(combinedCovInv, regression.getOmegaInverse()); } /** * Verifies that GLS with identity covariance matrix gives the same results * as OLS. */ @Test public void testGLSOLSConsistency() throws Exception { RealMatrix identityCov = MatrixUtils.createRealIdentityMatrix(16); GLSMultipleLinearRegression glsModel = new GLSMultipleLinearRegression(); OLSMultipleLinearRegression olsModel = new OLSMultipleLinearRegression(); glsModel.newSampleData(longley, 16, 6); olsModel.newSampleData(longley, 16, 6); glsModel.newCovarianceData(identityCov.getData()); double[] olsBeta = olsModel.calculateBeta().getData(); double[] glsBeta = glsModel.calculateBeta().getData(); // TODO: Should have assertRelativelyEquals(double[], double[], eps) in TestUtils // Should also add RealVector and RealMatrix versions for (int i = 0; i < olsBeta.length; i++) { TestUtils.assertRelativelyEquals(olsBeta[i], glsBeta[i], 10E-7); } } /** * Generate an error covariance matrix and sample data representing models * with this error structure. Then verify that GLS estimated coefficients, * on average, perform better than OLS. */ @Test public void testGLSEfficiency() throws Exception { RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(200); // Seed has been selected to generate non-trivial covariance // Assume model has 16 observations (will use Longley data). Start by generating // non-constant variances for the 16 error terms. final int nObs = 16; double[] sigma = new double[nObs]; for (int i = 0; i < nObs; i++) { sigma[i] = 10 * rg.nextDouble(); } // Now generate 1000 error vectors to use to estimate the covariance matrix // Columns are draws on N(0, sigma[col]) final int numSeeds = 1000; RealMatrix errorSeeds = MatrixUtils.createRealMatrix(numSeeds, nObs); for (int i = 0; i < numSeeds; i++) { for (int j = 0; j < nObs; j++) { errorSeeds.setEntry(i, j, rg.nextGaussian() * sigma[j]); } } // Get covariance matrix for columns RealMatrix cov = (new Covariance(errorSeeds)).getCovarianceMatrix(); // Create a CorrelatedRandomVectorGenerator to use to generate correlated errors GaussianRandomGenerator rawGenerator = new GaussianRandomGenerator(rg); double[] errorMeans = new double[nObs]; // Counting on init to 0 here CorrelatedRandomVectorGenerator gen = new CorrelatedRandomVectorGenerator(errorMeans, cov, 1.0e-12 * cov.getNorm(), rawGenerator); // Now start generating models. Use Longley X matrix on LHS // and Longley OLS beta vector as "true" beta. Generate // Y values by XB + u where u is a CorrelatedRandomVector generated // from cov. OLSMultipleLinearRegression ols = new OLSMultipleLinearRegression(); ols.newSampleData(longley, nObs, 6); final RealVector b = ols.calculateBeta().copy(); final RealMatrix x = ols.X.copy(); // Create a GLS model to reuse GLSMultipleLinearRegression gls = new GLSMultipleLinearRegression(); gls.newSampleData(longley, nObs, 6); gls.newCovarianceData(cov.getData()); // Create aggregators for stats measuring model performance DescriptiveStatistics olsBetaStats = new DescriptiveStatistics(); DescriptiveStatistics glsBetaStats = new DescriptiveStatistics(); // Generate Y vectors for 10000 models, estimate GLS and OLS and // Verify that OLS estimates are better final int nModels = 10000; for (int i = 0; i < nModels; i++) { // Generate y = xb + u with u cov RealVector u = MatrixUtils.createRealVector(gen.nextVector()); double[] y = u.add(x.operate(b)).getData(); // Estimate OLS parameters ols.newYSampleData(y); RealVector olsBeta = ols.calculateBeta(); // Estimate GLS parameters gls.newYSampleData(y); RealVector glsBeta = gls.calculateBeta(); // Record deviations from "true" beta double dist = olsBeta.getDistance(b); olsBetaStats.addValue(dist * dist); dist = glsBeta.getDistance(b); glsBetaStats.addValue(dist * dist); } // Verify that GLS is on average more efficient, lower variance assert(olsBetaStats.getMean() > 1.5 * glsBetaStats.getMean()); assert(olsBetaStats.getStandardDeviation() > glsBetaStats.getStandardDeviation()); } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/MultipleLinearRegressionAbstractTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/MultipleLinearRegressionA100644 1750 1750 10741 11532241243 32566 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.RealVector; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; public abstract class MultipleLinearRegressionAbstractTest { protected AbstractMultipleLinearRegression regression; @Before public void setUp(){ regression = createRegression(); } protected abstract AbstractMultipleLinearRegression createRegression(); protected abstract int getNumberOfRegressors(); protected abstract int getSampleSize(); @Test public void canEstimateRegressionParameters(){ double[] beta = regression.estimateRegressionParameters(); assertEquals(getNumberOfRegressors(), beta.length); } @Test public void canEstimateResiduals(){ double[] e = regression.estimateResiduals(); assertEquals(getSampleSize(), e.length); } @Test public void canEstimateRegressionParametersVariance(){ double[][] variance = regression.estimateRegressionParametersVariance(); assertEquals(getNumberOfRegressors(), variance.length); } @Test public void canEstimateRegressandVariance(){ if (getSampleSize() > getNumberOfRegressors()) { double variance = regression.estimateRegressandVariance(); assertTrue(variance > 0.0); } } /** * Verifies that newSampleData methods consistently insert unitary columns * in design matrix. Confirms the fix for MATH-411. */ @Test public void testNewSample() throws Exception { double[] design = new double[] { 1, 19, 22, 33, 2, 20, 30, 40, 3, 25, 35, 45, 4, 27, 37, 47 }; double[] y = new double[] {1, 2, 3, 4}; double[][] x = new double[][] { {19, 22, 33}, {20, 30, 40}, {25, 35, 45}, {27, 37, 47} }; AbstractMultipleLinearRegression regression = createRegression(); regression.newSampleData(design, 4, 3); RealMatrix flatX = regression.X.copy(); RealVector flatY = regression.Y.copy(); regression.newXSampleData(x); regression.newYSampleData(y); assertEquals(flatX, regression.X); assertEquals(flatY, regression.Y); // No intercept regression.setNoIntercept(true); regression.newSampleData(design, 4, 3); flatX = regression.X.copy(); flatY = regression.Y.copy(); regression.newXSampleData(x); regression.newYSampleData(y); assertEquals(flatX, regression.X); assertEquals(flatY, regression.Y); } @Test(expected=IllegalArgumentException.class) public void testNewSampleNullData() throws Exception { double[] data = null; createRegression().newSampleData(data, 2, 3); } @Test(expected=IllegalArgumentException.class) public void testNewSampleInvalidData() throws Exception { double[] data = new double[] {1, 2, 3, 4}; createRegression().newSampleData(data, 2, 3); } @Test(expected=IllegalArgumentException.class) public void testNewSampleInsufficientData() throws Exception { double[] data = new double[] {1, 2, 3, 4}; createRegression().newSampleData(data, 1, 3); } @Test(expected=IllegalArgumentException.class) public void testXSampleDataNull() { createRegression().newXSampleData(null); } @Test(expected=IllegalArgumentException.class) public void testYSampleDataNull() { createRegression().newYSampleData(null); } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegressionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegressi100644 1750 1750 52411 11532241243 32506 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import static org.junit.Assert.assertEquals; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.DefaultRealMatrixChangingVisitor; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.stat.StatUtils; import org.junit.Before; import org.junit.Test; public class OLSMultipleLinearRegressionTest extends MultipleLinearRegressionAbstractTest { private double[] y; private double[][] x; @Before @Override public void setUp(){ y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; x = new double[6][]; x[0] = new double[]{0, 0, 0, 0, 0}; x[1] = new double[]{2.0, 0, 0, 0, 0}; x[2] = new double[]{0, 3.0, 0, 0, 0}; x[3] = new double[]{0, 0, 4.0, 0, 0}; x[4] = new double[]{0, 0, 0, 5.0, 0}; x[5] = new double[]{0, 0, 0, 0, 6.0}; super.setUp(); } @Override protected OLSMultipleLinearRegression createRegression() { OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression(); regression.newSampleData(y, x); return regression; } @Override protected int getNumberOfRegressors() { return x[0].length + 1; } @Override protected int getSampleSize() { return y.length; } @Test(expected=IllegalArgumentException.class) public void cannotAddSampleDataWithSizeMismatch() { double[] y = new double[]{1.0, 2.0}; double[][] x = new double[1][]; x[0] = new double[]{1.0, 0}; createRegression().newSampleData(y, x); } @Test public void testPerfectFit() throws Exception { double[] betaHat = regression.estimateRegressionParameters(); TestUtils.assertEquals(betaHat, new double[]{ 11.0, 1.0 / 2.0, 2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0, 5.0 / 6.0 }, 1e-14); double[] residuals = regression.estimateResiduals(); TestUtils.assertEquals(residuals, new double[]{0d,0d,0d,0d,0d,0d}, 1e-14); RealMatrix errors = new Array2DRowRealMatrix(regression.estimateRegressionParametersVariance(), false); final double[] s = { 1.0, -1.0 / 2.0, -1.0 / 3.0, -1.0 / 4.0, -1.0 / 5.0, -1.0 / 6.0 }; RealMatrix referenceVariance = new Array2DRowRealMatrix(s.length, s.length); referenceVariance.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() { @Override public double visit(int row, int column, double value) { if (row == 0) { return s[column]; } double x = s[row] * s[column]; return (row == column) ? 2 * x : x; } }); assertEquals(0.0, errors.subtract(referenceVariance).getNorm(), 5.0e-16 * referenceVariance.getNorm()); assertEquals(1, ((OLSMultipleLinearRegression) regression).calculateRSquared(), 1E-12); } /** * Test Longley dataset against certified values provided by NIST. * Data Source: J. Longley (1967) "An Appraisal of Least Squares * Programs for the Electronic Computer from the Point of View of the User" * Journal of the American Statistical Association, vol. 62. September, * pp. 819-841. * * Certified values (and data) are from NIST: * http://www.itl.nist.gov/div898/strd/lls/data/LINKS/DATA/Longley.dat */ @Test public void testLongly() throws Exception { // Y values are first, then independent vars // Each row is one observation double[] design = new double[] { 60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962 }; final int nobs = 16; final int nvars = 6; // Estimate the model OLSMultipleLinearRegression model = new OLSMultipleLinearRegression(); model.newSampleData(design, nobs, nvars); // Check expected beta values from NIST double[] betaHat = model.estimateRegressionParameters(); TestUtils.assertEquals(betaHat, new double[]{-3482258.63459582, 15.0618722713733, -0.358191792925910E-01,-2.02022980381683, -1.03322686717359,-0.511041056535807E-01, 1829.15146461355}, 2E-8); // // Check expected residuals from R double[] residuals = model.estimateResiduals(); TestUtils.assertEquals(residuals, new double[]{ 267.340029759711,-94.0139423988359,46.28716775752924, -410.114621930906,309.7145907602313,-249.3112153297231, -164.0489563956039,-13.18035686637081,14.30477260005235, 455.394094551857,-17.26892711483297,-39.0550425226967, -155.5499735953195,-85.6713080421283,341.9315139607727, -206.7578251937366}, 1E-8); // Check standard errors from NIST double[] errors = model.estimateRegressionParametersStandardErrors(); TestUtils.assertEquals(new double[] {890420.383607373, 84.9149257747669, 0.334910077722432E-01, 0.488399681651699, 0.214274163161675, 0.226073200069370, 455.478499142212}, errors, 1E-6); // Check regression standard error against R assertEquals(304.8540735619638, model.estimateRegressionStandardError(), 1E-10); // Check R-Square statistics against R assertEquals(0.995479004577296, model.calculateRSquared(), 1E-12); assertEquals(0.992465007628826, model.calculateAdjustedRSquared(), 1E-12); checkVarianceConsistency(model); // Estimate model without intercept model.setNoIntercept(true); model.newSampleData(design, nobs, nvars); // Check expected beta values from R betaHat = model.estimateRegressionParameters(); TestUtils.assertEquals(betaHat, new double[]{-52.99357013868291, 0.07107319907358, -0.42346585566399,-0.57256866841929, -0.41420358884978, 48.41786562001326}, 1E-11); // Check standard errors from R errors = model.estimateRegressionParametersStandardErrors(); TestUtils.assertEquals(new double[] {129.54486693117232, 0.03016640003786, 0.41773654056612, 0.27899087467676, 0.32128496193363, 17.68948737819961}, errors, 1E-11); // Check expected residuals from R residuals = model.estimateResiduals(); TestUtils.assertEquals(residuals, new double[]{ 279.90274927293092, -130.32465380836874, 90.73228661967445, -401.31252201634948, -440.46768772620027, -543.54512853774793, 201.32111639536299, 215.90889365977932, 73.09368242049943, 913.21694494481869, 424.82484953610174, -8.56475876776709, -361.32974610842876, 27.34560497213464, 151.28955976355002, -492.49937355336846}, 1E-10); // Check regression standard error against R assertEquals(475.1655079819517, model.estimateRegressionStandardError(), 1E-10); // Check R-Square statistics against R assertEquals(0.9999670130706, model.calculateRSquared(), 1E-12); assertEquals(0.999947220913, model.calculateAdjustedRSquared(), 1E-12); } /** * Test R Swiss fertility dataset against R. * Data Source: R datasets package */ @Test public void testSwissFertility() throws Exception { double[] design = new double[] { 80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33 }; final int nobs = 47; final int nvars = 4; // Estimate the model OLSMultipleLinearRegression model = new OLSMultipleLinearRegression(); model.newSampleData(design, nobs, nvars); // Check expected beta values from R double[] betaHat = model.estimateRegressionParameters(); TestUtils.assertEquals(betaHat, new double[]{91.05542390271397, -0.22064551045715, -0.26058239824328, -0.96161238456030, 0.12441843147162}, 1E-12); // Check expected residuals from R double[] residuals = model.estimateResiduals(); TestUtils.assertEquals(residuals, new double[]{ 7.1044267859730512,1.6580347433531366, 4.6944952770029644,8.4548022690166160,13.6547432343186212, -9.3586864458500774,7.5822446330520386,15.5568995563859289, 0.8113090736598980,7.1186762732484308,7.4251378771228724, 2.6761316873234109,0.8351584810309354,7.1769991119615177, -3.8746753206299553,-3.1337779476387251,-0.1412575244091504, 1.1186809170469780,-6.3588097346816594,3.4039270429434074, 2.3374058329820175,-7.9272368576900503,-7.8361010968497959, -11.2597369269357070,0.9445333697827101,6.6544245101380328, -0.9146136301118665,-4.3152449403848570,-4.3536932047009183, -3.8907885169304661,-6.3027643926302188,-7.8308982189289091, -3.1792280015332750,-6.7167298771158226,-4.8469946718041754, -10.6335664353633685,11.1031134362036958,6.0084032641811733, 5.4326230830188482,-7.2375578629692230,2.1671550814448222, 15.0147574652763112,4.8625103516321015,-7.1597256413907706, -0.4515205619767598,-10.2916870903837587,-15.7812984571900063}, 1E-12); // Check standard errors from R double[] errors = model.estimateRegressionParametersStandardErrors(); TestUtils.assertEquals(new double[] {6.94881329475087, 0.07360008972340, 0.27410957467466, 0.19454551679325, 0.03726654773803}, errors, 1E-10); // Check regression standard error against R assertEquals(7.73642194433223, model.estimateRegressionStandardError(), 1E-12); // Check R-Square statistics against R assertEquals(0.649789742860228, model.calculateRSquared(), 1E-12); assertEquals(0.6164363850373927, model.calculateAdjustedRSquared(), 1E-12); checkVarianceConsistency(model); // Estimate the model with no intercept model = new OLSMultipleLinearRegression(); model.setNoIntercept(true); model.newSampleData(design, nobs, nvars); // Check expected beta values from R betaHat = model.estimateRegressionParameters(); TestUtils.assertEquals(betaHat, new double[]{0.52191832900513, 2.36588087917963, -0.94770353802795, 0.30851985863609}, 1E-12); // Check expected residuals from R residuals = model.estimateResiduals(); TestUtils.assertEquals(residuals, new double[]{ 44.138759883538249, 27.720705122356215, 35.873200836126799, 34.574619581211977, 26.600168342080213, 15.074636243026923, -12.704904871199814, 1.497443824078134, 2.691972687079431, 5.582798774291231, -4.422986561283165, -9.198581600334345, 4.481765170730647, 2.273520207553216, -22.649827853221336, -17.747900013943308, 20.298314638496436, 6.861405135329779, -8.684712790954924, -10.298639278062371, -9.896618896845819, 4.568568616351242, -15.313570491727944, -13.762961360873966, 7.156100301980509, 16.722282219843990, 26.716200609071898, -1.991466398777079, -2.523342564719335, 9.776486693095093, -5.297535127628603, -16.639070567471094, -10.302057295211819, -23.549487860816846, 1.506624392156384, -17.939174438345930, 13.105792202765040, -1.943329906928462, -1.516005841666695, -0.759066561832886, 20.793137744128977, -2.485236153005426, 27.588238710486976, 2.658333257106881, -15.998337823623046, -5.550742066720694, -14.219077806826615}, 1E-12); // Check standard errors from R errors = model.estimateRegressionParametersStandardErrors(); TestUtils.assertEquals(new double[] {0.10470063765677, 0.41684100584290, 0.43370143099691, 0.07694953606522}, errors, 1E-10); // Check regression standard error against R assertEquals(17.24710630547, model.estimateRegressionStandardError(), 1E-10); // Check R-Square statistics against R assertEquals(0.946350722085, model.calculateRSquared(), 1E-12); assertEquals(0.9413600915813, model.calculateAdjustedRSquared(), 1E-12); } /** * Test hat matrix computation * * @throws Exception */ @Test public void testHat() throws Exception { /* * This example is from "The Hat Matrix in Regression and ANOVA", * David C. Hoaglin and Roy E. Welsch, * The American Statistician, Vol. 32, No. 1 (Feb., 1978), pp. 17-22. * */ double[] design = new double[] { 11.14, .499, 11.1, 12.74, .558, 8.9, 13.13, .604, 8.8, 11.51, .441, 8.9, 12.38, .550, 8.8, 12.60, .528, 9.9, 11.13, .418, 10.7, 11.7, .480, 10.5, 11.02, .406, 10.5, 11.41, .467, 10.7 }; int nobs = 10; int nvars = 2; // Estimate the model OLSMultipleLinearRegression model = new OLSMultipleLinearRegression(); model.newSampleData(design, nobs, nvars); RealMatrix hat = model.calculateHat(); // Reference data is upper half of symmetric hat matrix double[] referenceData = new double[] { .418, -.002, .079, -.274, -.046, .181, .128, .222, .050, .242, .242, .292, .136, .243, .128, -.041, .033, -.035, .004, .417, -.019, .273, .187, -.126, .044, -.153, .004, .604, .197, -.038, .168, -.022, .275, -.028, .252, .111, -.030, .019, -.010, -.010, .148, .042, .117, .012, .111, .262, .145, .277, .174, .154, .120, .168, .315, .148, .187 }; // Check against reference data and verify symmetry int k = 0; for (int i = 0; i < 10; i++) { for (int j = i; j < 10; j++) { assertEquals(referenceData[k], hat.getEntry(i, j), 10e-3); assertEquals(hat.getEntry(i, j), hat.getEntry(j, i), 10e-12); k++; } } /* * Verify that residuals computed using the hat matrix are close to * what we get from direct computation, i.e. r = (I - H) y */ double[] residuals = model.estimateResiduals(); RealMatrix I = MatrixUtils.createRealIdentityMatrix(10); double[] hatResiduals = I.subtract(hat).operate(model.Y).getData(); TestUtils.assertEquals(residuals, hatResiduals, 10e-12); } /** * test calculateYVariance */ @Test public void testYVariance() { // assumes: y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; OLSMultipleLinearRegression model = new OLSMultipleLinearRegression(); model.newSampleData(y, x); TestUtils.assertEquals(model.calculateYVariance(), 3.5, 0); } /** * Verifies that calculateYVariance and calculateResidualVariance return consistent * values with direct variance computation from Y, residuals, respectively. */ protected void checkVarianceConsistency(OLSMultipleLinearRegression model) throws Exception { // Check Y variance consistency TestUtils.assertEquals(StatUtils.variance(model.Y.getData()), model.calculateYVariance(), 0); // Check residual variance consistency double[] residuals = model.calculateResiduals().getData(); RealMatrix X = model.X; TestUtils.assertEquals( StatUtils.variance(model.calculateResiduals().getData()) * (residuals.length - 1), model.calculateErrorVariance() * (X.getRowDimension() - X.getColumnDimension()), 1E-20); } /** * Verifies that setting X and Y separately has the same effect as newSample(X,Y). */ @Test public void testNewSample2() throws Exception { double[] y = new double[] {1, 2, 3, 4}; double[][] x = new double[][] { {19, 22, 33}, {20, 30, 40}, {25, 35, 45}, {27, 37, 47} }; OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression(); regression.newSampleData(y, x); RealMatrix combinedX = regression.X.copy(); RealVector combinedY = regression.Y.copy(); regression.newXSampleData(x); regression.newYSampleData(y); assertEquals(combinedX, regression.X); assertEquals(combinedY, regression.Y); // No intercept regression.setNoIntercept(true); regression.newSampleData(y, x); combinedX = regression.X.copy(); combinedY = regression.Y.copy(); regression.newXSampleData(x); regression.newYSampleData(y); assertEquals(combinedX, regression.X); assertEquals(combinedY, regression.Y); } @Test(expected=IllegalArgumentException.class) public void testNewSampleDataYNull() { createRegression().newSampleData(null, new double[][] {}); } @Test(expected=IllegalArgumentException.class) public void testNewSampleDataXNull() { createRegression().newSampleData(new double[] {}, null); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/SimpleRegressionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/regression/SimpleRegressionTest.java100644 1750 1750 37571 11532241243 32562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import java.util.Random; import junit.framework.TestCase; /** * Test cases for the TestStatistic class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public final class SimpleRegressionTest extends TestCase { /* * NIST "Norris" refernce data set from * http://www.itl.nist.gov/div898/strd/lls/data/LINKS/DATA/Norris.dat * Strangely, order is {y,x} */ private double[][] data = { { 0.1, 0.2 }, {338.8, 337.4 }, {118.1, 118.2 }, {888.0, 884.6 }, {9.2, 10.1 }, {228.1, 226.5 }, {668.5, 666.3 }, {998.5, 996.3 }, {449.1, 448.6 }, {778.9, 777.0 }, {559.2, 558.2 }, {0.3, 0.4 }, {0.1, 0.6 }, {778.1, 775.5 }, {668.8, 666.9 }, {339.3, 338.0 }, {448.9, 447.5 }, {10.8, 11.6 }, {557.7, 556.0 }, {228.3, 228.1 }, {998.0, 995.8 }, {888.8, 887.6 }, {119.6, 120.2 }, {0.3, 0.3 }, {0.6, 0.3 }, {557.6, 556.8 }, {339.3, 339.1 }, {888.0, 887.2 }, {998.5, 999.0 }, {778.9, 779.0 }, {10.2, 11.1 }, {117.6, 118.3 }, {228.9, 229.2 }, {668.4, 669.1 }, {449.2, 448.9 }, {0.2, 0.5 } }; /* * Correlation example from * http://www.xycoon.com/correlation.htm */ private double[][] corrData = { { 101.0, 99.2 }, {100.1, 99.0 }, {100.0, 100.0 }, {90.6, 111.6 }, {86.5, 122.2 }, {89.7, 117.6 }, {90.6, 121.1 }, {82.8, 136.0 }, {70.1, 154.2 }, {65.4, 153.6 }, {61.3, 158.5 }, {62.5, 140.6 }, {63.6, 136.2 }, {52.6, 168.0 }, {59.7, 154.3 }, {59.5, 149.0 }, {61.3, 165.5 } }; /* * From Moore and Mcabe, "Introduction to the Practice of Statistics" * Example 10.3 */ private double[][] infData = { { 15.6, 5.2 }, {26.8, 6.1 }, {37.8, 8.7 }, {36.4, 8.5 }, {35.5, 8.8 }, {18.6, 4.9 }, {15.3, 4.5 }, {7.9, 2.5 }, {0.0, 1.1 } }; /* * Points to remove in the remove tests */ private double[][] removeSingle = {infData[1]}; private double[][] removeMultiple = { infData[1], infData[2] }; private double removeX = infData[0][0]; private double removeY = infData[0][1]; /* * Data with bad linear fit */ private double[][] infData2 = { { 1, 1 }, {2, 0 }, {3, 5 }, {4, 2 }, {5, -1 }, {6, 12 } }; public SimpleRegressionTest(String name) { super(name); } public void testNorris() { SimpleRegression regression = new SimpleRegression(); for (int i = 0; i < data.length; i++) { regression.addData(data[i][1], data[i][0]); } // Tests against certified values from // http://www.itl.nist.gov/div898/strd/lls/data/LINKS/DATA/Norris.dat assertEquals("slope", 1.00211681802045, regression.getSlope(), 10E-12); assertEquals("slope std err", 0.429796848199937E-03, regression.getSlopeStdErr(),10E-12); assertEquals("number of observations", 36, regression.getN()); assertEquals( "intercept", -0.262323073774029, regression.getIntercept(),10E-12); assertEquals("std err intercept", 0.232818234301152, regression.getInterceptStdErr(),10E-12); assertEquals("r-square", 0.999993745883712, regression.getRSquare(), 10E-12); assertEquals("SSR", 4255954.13232369, regression.getRegressionSumSquares(), 10E-9); assertEquals("MSE", 0.782864662630069, regression.getMeanSquareError(), 10E-10); assertEquals("SSE", 26.6173985294224, regression.getSumSquaredErrors(),10E-9); // ------------ End certified data tests assertEquals( "predict(0)", -0.262323073774029, regression.predict(0), 10E-12); assertEquals("predict(1)", 1.00211681802045 - 0.262323073774029, regression.predict(1), 10E-12); } public void testCorr() { SimpleRegression regression = new SimpleRegression(); regression.addData(corrData); assertEquals("number of observations", 17, regression.getN()); assertEquals("r-square", .896123, regression.getRSquare(), 10E-6); assertEquals("r", -0.94663767742, regression.getR(), 1E-10); } public void testNaNs() { SimpleRegression regression = new SimpleRegression(); assertTrue("intercept not NaN", Double.isNaN(regression.getIntercept())); assertTrue("slope not NaN", Double.isNaN(regression.getSlope())); assertTrue("slope std err not NaN", Double.isNaN(regression.getSlopeStdErr())); assertTrue("intercept std err not NaN", Double.isNaN(regression.getInterceptStdErr())); assertTrue("MSE not NaN", Double.isNaN(regression.getMeanSquareError())); assertTrue("e not NaN", Double.isNaN(regression.getR())); assertTrue("r-square not NaN", Double.isNaN(regression.getRSquare())); assertTrue( "RSS not NaN", Double.isNaN(regression.getRegressionSumSquares())); assertTrue("SSE not NaN",Double.isNaN(regression.getSumSquaredErrors())); assertTrue("SSTO not NaN", Double.isNaN(regression.getTotalSumSquares())); assertTrue("predict not NaN", Double.isNaN(regression.predict(0))); regression.addData(1, 2); regression.addData(1, 3); // No x variation, so these should still blow... assertTrue("intercept not NaN", Double.isNaN(regression.getIntercept())); assertTrue("slope not NaN", Double.isNaN(regression.getSlope())); assertTrue("slope std err not NaN", Double.isNaN(regression.getSlopeStdErr())); assertTrue("intercept std err not NaN", Double.isNaN(regression.getInterceptStdErr())); assertTrue("MSE not NaN", Double.isNaN(regression.getMeanSquareError())); assertTrue("e not NaN", Double.isNaN(regression.getR())); assertTrue("r-square not NaN", Double.isNaN(regression.getRSquare())); assertTrue("RSS not NaN", Double.isNaN(regression.getRegressionSumSquares())); assertTrue("SSE not NaN", Double.isNaN(regression.getSumSquaredErrors())); assertTrue("predict not NaN", Double.isNaN(regression.predict(0))); // but SSTO should be OK assertTrue("SSTO NaN", !Double.isNaN(regression.getTotalSumSquares())); regression = new SimpleRegression(); regression.addData(1, 2); regression.addData(3, 3); // All should be OK except MSE, s(b0), s(b1) which need one more df assertTrue("interceptNaN", !Double.isNaN(regression.getIntercept())); assertTrue("slope NaN", !Double.isNaN(regression.getSlope())); assertTrue ("slope std err not NaN", Double.isNaN(regression.getSlopeStdErr())); assertTrue("intercept std err not NaN", Double.isNaN(regression.getInterceptStdErr())); assertTrue("MSE not NaN", Double.isNaN(regression.getMeanSquareError())); assertTrue("r NaN", !Double.isNaN(regression.getR())); assertTrue("r-square NaN", !Double.isNaN(regression.getRSquare())); assertTrue("RSS NaN", !Double.isNaN(regression.getRegressionSumSquares())); assertTrue("SSE NaN", !Double.isNaN(regression.getSumSquaredErrors())); assertTrue("SSTO NaN", !Double.isNaN(regression.getTotalSumSquares())); assertTrue("predict NaN", !Double.isNaN(regression.predict(0))); regression.addData(1, 4); // MSE, MSE, s(b0), s(b1) should all be OK now assertTrue("MSE NaN", !Double.isNaN(regression.getMeanSquareError())); assertTrue("slope std err NaN", !Double.isNaN(regression.getSlopeStdErr())); assertTrue("intercept std err NaN", !Double.isNaN(regression.getInterceptStdErr())); } public void testClear() { SimpleRegression regression = new SimpleRegression(); regression.addData(corrData); assertEquals("number of observations", 17, regression.getN()); regression.clear(); assertEquals("number of observations", 0, regression.getN()); regression.addData(corrData); assertEquals("r-square", .896123, regression.getRSquare(), 10E-6); regression.addData(data); assertEquals("number of observations", 53, regression.getN()); } public void testInference() throws Exception { //---------- verified against R, version 1.8.1 ----- // infData SimpleRegression regression = new SimpleRegression(); regression.addData(infData); assertEquals("slope std err", 0.011448491, regression.getSlopeStdErr(), 1E-10); assertEquals("std err intercept", 0.286036932, regression.getInterceptStdErr(),1E-8); assertEquals("significance", 4.596e-07, regression.getSignificance(),1E-8); assertEquals("slope conf interval half-width", 0.0270713794287, regression.getSlopeConfidenceInterval(),1E-8); // infData2 regression = new SimpleRegression(); regression.addData(infData2); assertEquals("slope std err", 1.07260253, regression.getSlopeStdErr(), 1E-8); assertEquals("std err intercept",4.17718672, regression.getInterceptStdErr(),1E-8); assertEquals("significance", 0.261829133982, regression.getSignificance(),1E-11); assertEquals("slope conf interval half-width", 2.97802204827, regression.getSlopeConfidenceInterval(),1E-8); //------------- End R-verified tests ------------------------------- //FIXME: get a real example to test against with alpha = .01 assertTrue("tighter means wider", regression.getSlopeConfidenceInterval() < regression.getSlopeConfidenceInterval(0.01)); try { regression.getSlopeConfidenceInterval(1); fail("expecting IllegalArgumentException for alpha = 1"); } catch (IllegalArgumentException ex) { // ignored } } public void testPerfect() throws Exception { SimpleRegression regression = new SimpleRegression(); int n = 100; for (int i = 0; i < n; i++) { regression.addData(((double) i) / (n - 1), i); } assertEquals(0.0, regression.getSignificance(), 1.0e-5); assertTrue(regression.getSlope() > 0.0); assertTrue(regression.getSumSquaredErrors() >= 0.0); } public void testPerfectNegative() throws Exception { SimpleRegression regression = new SimpleRegression(); int n = 100; for (int i = 0; i < n; i++) { regression.addData(- ((double) i) / (n - 1), i); } assertEquals(0.0, regression.getSignificance(), 1.0e-5); assertTrue(regression.getSlope() < 0.0); } public void testRandom() throws Exception { SimpleRegression regression = new SimpleRegression(); Random random = new Random(1); int n = 100; for (int i = 0; i < n; i++) { regression.addData(((double) i) / (n - 1), random.nextDouble()); } assertTrue( 0.0 < regression.getSignificance() && regression.getSignificance() < 1.0); } // Jira MATH-85 = Bugzilla 39432 public void testSSENonNegative() { double[] y = { 8915.102, 8919.302, 8923.502 }; double[] x = { 1.107178495E2, 1.107264895E2, 1.107351295E2 }; SimpleRegression reg = new SimpleRegression(); for (int i = 0; i < x.length; i++) { reg.addData(x[i], y[i]); } assertTrue(reg.getSumSquaredErrors() >= 0.0); } // Test remove X,Y (single observation) public void testRemoveXY() throws Exception { // Create regression with inference data then remove to test SimpleRegression regression = new SimpleRegression(); regression.addData(infData); regression.removeData(removeX, removeY); regression.addData(removeX, removeY); // Use the inference assertions to make sure that everything worked assertEquals("slope std err", 0.011448491, regression.getSlopeStdErr(), 1E-10); assertEquals("std err intercept", 0.286036932, regression.getInterceptStdErr(),1E-8); assertEquals("significance", 4.596e-07, regression.getSignificance(),1E-8); assertEquals("slope conf interval half-width", 0.0270713794287, regression.getSlopeConfidenceInterval(),1E-8); } // Test remove single observation in array public void testRemoveSingle() throws Exception { // Create regression with inference data then remove to test SimpleRegression regression = new SimpleRegression(); regression.addData(infData); regression.removeData(removeSingle); regression.addData(removeSingle); // Use the inference assertions to make sure that everything worked assertEquals("slope std err", 0.011448491, regression.getSlopeStdErr(), 1E-10); assertEquals("std err intercept", 0.286036932, regression.getInterceptStdErr(),1E-8); assertEquals("significance", 4.596e-07, regression.getSignificance(),1E-8); assertEquals("slope conf interval half-width", 0.0270713794287, regression.getSlopeConfidenceInterval(),1E-8); } // Test remove multiple observations public void testRemoveMultiple() throws Exception { // Create regression with inference data then remove to test SimpleRegression regression = new SimpleRegression(); regression.addData(infData); regression.removeData(removeMultiple); regression.addData(removeMultiple); // Use the inference assertions to make sure that everything worked assertEquals("slope std err", 0.011448491, regression.getSlopeStdErr(), 1E-10); assertEquals("std err intercept", 0.286036932, regression.getInterceptStdErr(),1E-8); assertEquals("significance", 4.596e-07, regression.getSignificance(),1E-8); assertEquals("slope conf interval half-width", 0.0270713794287, regression.getSlopeConfidenceInterval(),1E-8); } // Remove observation when empty public void testRemoveObsFromEmpty() { SimpleRegression regression = new SimpleRegression(); regression.removeData(removeX, removeY); assertEquals(regression.getN(), 0); } // Remove single observation to empty public void testRemoveObsFromSingle() { SimpleRegression regression = new SimpleRegression(); regression.addData(removeX, removeY); regression.removeData(removeX, removeY); assertEquals(regression.getN(), 0); } // Remove multiple observations to empty public void testRemoveMultipleToEmpty() { SimpleRegression regression = new SimpleRegression(); regression.addData(removeMultiple); regression.removeData(removeMultiple); assertEquals(regression.getN(), 0); } // Remove multiple observations past empty (i.e. size of array > n) public void testRemoveMultiplePastEmpty() { SimpleRegression regression = new SimpleRegression(); regression.addData(removeX, removeY); regression.removeData(removeMultiple); assertEquals(regression.getN(), 0); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/PearsonsCorrelationTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/PearsonsCorrelationTest.100644 1750 1750 33347 11532241243 32560 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.TestUtils; import org.apache.commons.math.distribution.TDistribution; import org.apache.commons.math.distribution.TDistributionImpl; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public class PearsonsCorrelationTest extends TestCase { protected final double[] longleyData = new double[] { 60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962 }; protected final double[] swissData = new double[] { 80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33 }; /** * Test Longley dataset against R. */ public void testLongly() throws Exception { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); PearsonsCorrelation corrInstance = new PearsonsCorrelation(matrix); RealMatrix correlationMatrix = corrInstance.getCorrelationMatrix(); double[] rData = new double[] { 1.000000000000000, 0.9708985250610560, 0.9835516111796693, 0.5024980838759942, 0.4573073999764817, 0.960390571594376, 0.9713294591921188, 0.970898525061056, 1.0000000000000000, 0.9915891780247822, 0.6206333925590966, 0.4647441876006747, 0.979163432977498, 0.9911491900672053, 0.983551611179669, 0.9915891780247822, 1.0000000000000000, 0.6042609398895580, 0.4464367918926265, 0.991090069458478, 0.9952734837647849, 0.502498083875994, 0.6206333925590966, 0.6042609398895580, 1.0000000000000000, -0.1774206295018783, 0.686551516365312, 0.6682566045621746, 0.457307399976482, 0.4647441876006747, 0.4464367918926265, -0.1774206295018783, 1.0000000000000000, 0.364416267189032, 0.4172451498349454, 0.960390571594376, 0.9791634329774981, 0.9910900694584777, 0.6865515163653120, 0.3644162671890320, 1.000000000000000, 0.9939528462329257, 0.971329459192119, 0.9911491900672053, 0.9952734837647849, 0.6682566045621746, 0.4172451498349454, 0.993952846232926, 1.0000000000000000 }; TestUtils.assertEquals("correlation matrix", createRealMatrix(rData, 7, 7), correlationMatrix, 10E-15); double[] rPvalues = new double[] { 4.38904690369668e-10, 8.36353208910623e-12, 7.8159700933611e-14, 0.0472894097790304, 0.01030636128354301, 0.01316878049026582, 0.0749178049642416, 0.06971758330341182, 0.0830166169296545, 0.510948586323452, 3.693245043123738e-09, 4.327782576751815e-11, 1.167954621905665e-13, 0.00331028281967516, 0.1652293725106684, 3.95834476307755e-10, 1.114663916723657e-13, 1.332267629550188e-15, 0.00466039138541463, 0.1078477071581498, 7.771561172376096e-15 }; RealMatrix rPMatrix = createLowerTriangularRealMatrix(rPvalues, 7); fillUpper(rPMatrix, 0d); TestUtils.assertEquals("correlation p values", rPMatrix, corrInstance.getCorrelationPValues(), 10E-15); } /** * Test R Swiss fertility dataset against R. */ public void testSwissFertility() throws Exception { RealMatrix matrix = createRealMatrix(swissData, 47, 5); PearsonsCorrelation corrInstance = new PearsonsCorrelation(matrix); RealMatrix correlationMatrix = corrInstance.getCorrelationMatrix(); double[] rData = new double[] { 1.0000000000000000, 0.3530791836199747, -0.6458827064572875, -0.6637888570350691, 0.4636847006517939, 0.3530791836199747, 1.0000000000000000,-0.6865422086171366, -0.6395225189483201, 0.4010950530487398, -0.6458827064572875, -0.6865422086171366, 1.0000000000000000, 0.6984152962884830, -0.5727418060641666, -0.6637888570350691, -0.6395225189483201, 0.6984152962884830, 1.0000000000000000, -0.1538589170909148, 0.4636847006517939, 0.4010950530487398, -0.5727418060641666, -0.1538589170909148, 1.0000000000000000 }; TestUtils.assertEquals("correlation matrix", createRealMatrix(rData, 5, 5), correlationMatrix, 10E-15); double[] rPvalues = new double[] { 0.01491720061472623, 9.45043734069043e-07, 9.95151527133974e-08, 3.658616965962355e-07, 1.304590105694471e-06, 4.811397236181847e-08, 0.001028523190118147, 0.005204433539191644, 2.588307925380906e-05, 0.301807756132683 }; RealMatrix rPMatrix = createLowerTriangularRealMatrix(rPvalues, 5); fillUpper(rPMatrix, 0d); TestUtils.assertEquals("correlation p values", rPMatrix, corrInstance.getCorrelationPValues(), 10E-15); } /** * Test p-value near 0. JIRA: MATH-371 */ public void testPValueNearZero() throws Exception { /* * Create a dataset that has r -> 1, p -> 0 as dimension increases. * Prior to the fix for MATH-371, p vanished for dimension >= 14. * Post fix, p-values diminish smoothly, vanishing at dimension = 127. * Tested value is ~1E-303. */ int dimension = 120; double[][] data = new double[dimension][2]; for (int i = 0; i < dimension; i++) { data[i][0] = i; data[i][1] = i + 1/((double)i + 1); } PearsonsCorrelation corrInstance = new PearsonsCorrelation(data); assertTrue(corrInstance.getCorrelationPValues().getEntry(0, 1) > 0); } /** * Constant column */ public void testConstant() { double[] noVariance = new double[] {1, 1, 1, 1}; double[] values = new double[] {1, 2, 3, 4}; assertTrue(Double.isNaN(new PearsonsCorrelation().correlation(noVariance, values))); } /** * Insufficient data */ public void testInsufficientData() { double[] one = new double[] {1}; double[] two = new double[] {2}; try { new PearsonsCorrelation().correlation(one, two); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } RealMatrix matrix = new BlockRealMatrix(new double[][] {{0},{1}}); try { new PearsonsCorrelation(matrix); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } } /** * Verify that direct t-tests using standard error estimates are consistent * with reported p-values */ public void testStdErrorConsistency() throws Exception { TDistribution tDistribution = new TDistributionImpl(45); RealMatrix matrix = createRealMatrix(swissData, 47, 5); PearsonsCorrelation corrInstance = new PearsonsCorrelation(matrix); RealMatrix rValues = corrInstance.getCorrelationMatrix(); RealMatrix pValues = corrInstance.getCorrelationPValues(); RealMatrix stdErrors = corrInstance.getCorrelationStandardErrors(); for (int i = 0; i < 5; i++) { for (int j = 0; j < i; j++) { double t = FastMath.abs(rValues.getEntry(i, j)) / stdErrors.getEntry(i, j); double p = 2 * (1 - tDistribution.cumulativeProbability(t)); assertEquals(p, pValues.getEntry(i, j), 10E-15); } } } /** * Verify that creating correlation from covariance gives same results as * direct computation from the original matrix */ public void testCovarianceConsistency() throws Exception { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); PearsonsCorrelation corrInstance = new PearsonsCorrelation(matrix); Covariance covInstance = new Covariance(matrix); PearsonsCorrelation corrFromCovInstance = new PearsonsCorrelation(covInstance); TestUtils.assertEquals("correlation values", corrInstance.getCorrelationMatrix(), corrFromCovInstance.getCorrelationMatrix(), 10E-15); TestUtils.assertEquals("p values", corrInstance.getCorrelationPValues(), corrFromCovInstance.getCorrelationPValues(), 10E-15); TestUtils.assertEquals("standard errors", corrInstance.getCorrelationStandardErrors(), corrFromCovInstance.getCorrelationStandardErrors(), 10E-15); PearsonsCorrelation corrFromCovInstance2 = new PearsonsCorrelation(covInstance.getCovarianceMatrix(), 16); TestUtils.assertEquals("correlation values", corrInstance.getCorrelationMatrix(), corrFromCovInstance2.getCorrelationMatrix(), 10E-15); TestUtils.assertEquals("p values", corrInstance.getCorrelationPValues(), corrFromCovInstance2.getCorrelationPValues(), 10E-15); TestUtils.assertEquals("standard errors", corrInstance.getCorrelationStandardErrors(), corrFromCovInstance2.getCorrelationStandardErrors(), 10E-15); } public void testConsistency() { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); PearsonsCorrelation corrInstance = new PearsonsCorrelation(matrix); double[][] data = matrix.getData(); double[] x = matrix.getColumn(0); double[] y = matrix.getColumn(1); assertEquals(new PearsonsCorrelation().correlation(x, y), corrInstance.getCorrelationMatrix().getEntry(0, 1), Double.MIN_VALUE); TestUtils.assertEquals("Correlation matrix", corrInstance.getCorrelationMatrix(), new PearsonsCorrelation().computeCorrelationMatrix(data), Double.MIN_VALUE); } protected RealMatrix createRealMatrix(double[] data, int nRows, int nCols) { double[][] matrixData = new double[nRows][nCols]; int ptr = 0; for (int i = 0; i < nRows; i++) { System.arraycopy(data, ptr, matrixData[i], 0, nCols); ptr += nCols; } return new BlockRealMatrix(matrixData); } protected RealMatrix createLowerTriangularRealMatrix(double[] data, int dimension) { int ptr = 0; RealMatrix result = new BlockRealMatrix(dimension, dimension); for (int i = 1; i < dimension; i++) { for (int j = 0; j < i; j++) { result.setEntry(i, j, data[ptr]); ptr++; } } return result; } protected void fillUpper(RealMatrix matrix, double diagonalValue) { int dimension = matrix.getColumnDimension(); for (int i = 0; i < dimension; i++) { matrix.setEntry(i, i, diagonalValue); for (int j = i+1; j < dimension; j++) { matrix.setEntry(i, j, matrix.getEntry(j, i)); } } } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/SpearmansRankCorrelationTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/SpearmansRankCorrelation100644 1750 1750 13067 11532241243 32612 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; /** * Test cases for Spearman's rank correlation * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SpearmansRankCorrelationTest extends PearsonsCorrelationTest { @Override protected void setUp() throws Exception { super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); } /** * Test Longley dataset against R. */ @Override public void testLongly() throws Exception { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); SpearmansCorrelation corrInstance = new SpearmansCorrelation(matrix); RealMatrix correlationMatrix = corrInstance.getCorrelationMatrix(); double[] rData = new double[] { 1, 0.982352941176471, 0.985294117647059, 0.564705882352941, 0.2264705882352941, 0.976470588235294, 0.976470588235294, 0.982352941176471, 1, 0.997058823529412, 0.664705882352941, 0.2205882352941176, 0.997058823529412, 0.997058823529412, 0.985294117647059, 0.997058823529412, 1, 0.638235294117647, 0.2235294117647059, 0.9941176470588236, 0.9941176470588236, 0.564705882352941, 0.664705882352941, 0.638235294117647, 1, -0.3411764705882353, 0.685294117647059, 0.685294117647059, 0.2264705882352941, 0.2205882352941176, 0.2235294117647059, -0.3411764705882353, 1, 0.2264705882352941, 0.2264705882352941, 0.976470588235294, 0.997058823529412, 0.9941176470588236, 0.685294117647059, 0.2264705882352941, 1, 1, 0.976470588235294, 0.997058823529412, 0.9941176470588236, 0.685294117647059, 0.2264705882352941, 1, 1 }; TestUtils.assertEquals("Spearman's correlation matrix", createRealMatrix(rData, 7, 7), correlationMatrix, 10E-15); } /** * Test R swiss fertility dataset. */ public void testSwiss() throws Exception { RealMatrix matrix = createRealMatrix(swissData, 47, 5); SpearmansCorrelation corrInstance = new SpearmansCorrelation(matrix); RealMatrix correlationMatrix = corrInstance.getCorrelationMatrix(); double[] rData = new double[] { 1, 0.2426642769364176, -0.660902996352354, -0.443257690360988, 0.4136455623012432, 0.2426642769364176, 1, -0.598859938748963, -0.650463814145816, 0.2886878090882852, -0.660902996352354, -0.598859938748963, 1, 0.674603831406147, -0.4750575257171745, -0.443257690360988, -0.650463814145816, 0.674603831406147, 1, -0.1444163088302244, 0.4136455623012432, 0.2886878090882852, -0.4750575257171745, -0.1444163088302244, 1 }; TestUtils.assertEquals("Spearman's correlation matrix", createRealMatrix(rData, 5, 5), correlationMatrix, 10E-15); } /** * Constant column */ @Override public void testConstant() { double[] noVariance = new double[] {1, 1, 1, 1}; double[] values = new double[] {1, 2, 3, 4}; assertTrue(Double.isNaN(new SpearmansCorrelation().correlation(noVariance, values))); } /** * Insufficient data */ @Override public void testInsufficientData() { double[] one = new double[] {1}; double[] two = new double[] {2}; try { new SpearmansCorrelation().correlation(one, two); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } RealMatrix matrix = new BlockRealMatrix(new double[][] {{0},{1}}); try { new SpearmansCorrelation(matrix); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } } @Override public void testConsistency() { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); SpearmansCorrelation corrInstance = new SpearmansCorrelation(matrix); double[][] data = matrix.getData(); double[] x = matrix.getColumn(0); double[] y = matrix.getColumn(1); assertEquals(new SpearmansCorrelation().correlation(x, y), corrInstance.getCorrelationMatrix().getEntry(0, 1), Double.MIN_VALUE); TestUtils.assertEquals("Correlation matrix", corrInstance.getCorrelationMatrix(), new SpearmansCorrelation().computeCorrelationMatrix(data), Double.MIN_VALUE); } // Not relevant here @Override public void testStdErrorConsistency() throws Exception {} @Override public void testCovarianceConsistency() throws Exception {} } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/correlation/CovarianceTest.java100644 1750 1750 23644 11532241243 31477 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.TestUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.stat.descriptive.moment.Variance; import junit.framework.TestCase; public class CovarianceTest extends TestCase { protected final double[] longleyData = new double[] { 60323,83.0,234289,2356,1590,107608,1947, 61122,88.5,259426,2325,1456,108632,1948, 60171,88.2,258054,3682,1616,109773,1949, 61187,89.5,284599,3351,1650,110929,1950, 63221,96.2,328975,2099,3099,112075,1951, 63639,98.1,346999,1932,3594,113270,1952, 64989,99.0,365385,1870,3547,115094,1953, 63761,100.0,363112,3578,3350,116219,1954, 66019,101.2,397469,2904,3048,117388,1955, 67857,104.6,419180,2822,2857,118734,1956, 68169,108.4,442769,2936,2798,120445,1957, 66513,110.8,444546,4681,2637,121950,1958, 68655,112.6,482704,3813,2552,123366,1959, 69564,114.2,502601,3931,2514,125368,1960, 69331,115.7,518173,4806,2572,127852,1961, 70551,116.9,554894,4007,2827,130081,1962 }; protected final double[] swissData = new double[] { 80.2,17.0,15,12,9.96, 83.1,45.1,6,9,84.84, 92.5,39.7,5,5,93.40, 85.8,36.5,12,7,33.77, 76.9,43.5,17,15,5.16, 76.1,35.3,9,7,90.57, 83.8,70.2,16,7,92.85, 92.4,67.8,14,8,97.16, 82.4,53.3,12,7,97.67, 82.9,45.2,16,13,91.38, 87.1,64.5,14,6,98.61, 64.1,62.0,21,12,8.52, 66.9,67.5,14,7,2.27, 68.9,60.7,19,12,4.43, 61.7,69.3,22,5,2.82, 68.3,72.6,18,2,24.20, 71.7,34.0,17,8,3.30, 55.7,19.4,26,28,12.11, 54.3,15.2,31,20,2.15, 65.1,73.0,19,9,2.84, 65.5,59.8,22,10,5.23, 65.0,55.1,14,3,4.52, 56.6,50.9,22,12,15.14, 57.4,54.1,20,6,4.20, 72.5,71.2,12,1,2.40, 74.2,58.1,14,8,5.23, 72.0,63.5,6,3,2.56, 60.5,60.8,16,10,7.72, 58.3,26.8,25,19,18.46, 65.4,49.5,15,8,6.10, 75.5,85.9,3,2,99.71, 69.3,84.9,7,6,99.68, 77.3,89.7,5,2,100.00, 70.5,78.2,12,6,98.96, 79.4,64.9,7,3,98.22, 65.0,75.9,9,9,99.06, 92.2,84.6,3,3,99.46, 79.3,63.1,13,13,96.83, 70.4,38.4,26,12,5.62, 65.7,7.7,29,11,13.79, 72.7,16.7,22,13,11.22, 64.4,17.6,35,32,16.92, 77.6,37.6,15,7,4.97, 67.6,18.7,25,7,8.65, 35.0,1.2,37,53,42.34, 44.7,46.6,16,29,50.43, 42.8,27.7,22,29,58.33 }; /** * Test Longley dataset against R. * Data Source: J. Longley (1967) "An Appraisal of Least Squares * Programs for the Electronic Computer from the Point of View of the User" * Journal of the American Statistical Association, vol. 62. September, * pp. 819-841. * * Data are from NIST: * http://www.itl.nist.gov/div898/strd/lls/data/LINKS/DATA/Longley.dat */ public void testLongly() { RealMatrix matrix = createRealMatrix(longleyData, 16, 7); RealMatrix covarianceMatrix = new Covariance(matrix).getCovarianceMatrix(); double[] rData = new double[] { 12333921.73333333246, 3.679666000000000e+04, 343330206.333333313, 1649102.666666666744, 1117681.066666666651, 23461965.733333334, 16240.93333333333248, 36796.66000000000, 1.164576250000000e+02, 1063604.115416667, 6258.666250000000, 3490.253750000000, 73503.000000000, 50.92333333333334, 343330206.33333331347, 1.063604115416667e+06, 9879353659.329166412, 56124369.854166664183, 30880428.345833335072, 685240944.600000024, 470977.90000000002328, 1649102.66666666674, 6.258666250000000e+03, 56124369.854166664, 873223.429166666698, -115378.762499999997, 4462741.533333333, 2973.03333333333330, 1117681.06666666665, 3.490253750000000e+03, 30880428.345833335, -115378.762499999997, 484304.095833333326, 1764098.133333333, 1382.43333333333339, 23461965.73333333433, 7.350300000000000e+04, 685240944.600000024, 4462741.533333333209, 1764098.133333333302, 48387348.933333330, 32917.40000000000146, 16240.93333333333, 5.092333333333334e+01, 470977.900000000, 2973.033333333333, 1382.433333333333, 32917.40000000, 22.66666666666667 }; TestUtils.assertEquals("covariance matrix", createRealMatrix(rData, 7, 7), covarianceMatrix, 10E-9); } /** * Test R Swiss fertility dataset against R. * Data Source: R datasets package */ public void testSwissFertility() { RealMatrix matrix = createRealMatrix(swissData, 47, 5); RealMatrix covarianceMatrix = new Covariance(matrix).getCovarianceMatrix(); double[] rData = new double[] { 156.0424976873265, 100.1691489361702, -64.36692876965772, -79.7295097132285, 241.5632030527289, 100.169148936170251, 515.7994172062905, -124.39283071230344, -139.6574005550416, 379.9043755781684, -64.3669287696577, -124.3928307123034, 63.64662349676226, 53.5758556891767, -190.5606105457909, -79.7295097132285, -139.6574005550416, 53.57585568917669, 92.4560592044403, -61.6988297872340, 241.5632030527289, 379.9043755781684, -190.56061054579092, -61.6988297872340, 1739.2945371877890 }; TestUtils.assertEquals("covariance matrix", createRealMatrix(rData, 5, 5), covarianceMatrix, 10E-13); } /** * Constant column */ public void testConstant() { double[] noVariance = new double[] {1, 1, 1, 1}; double[] values = new double[] {1, 2, 3, 4}; assertEquals(0d, new Covariance().covariance(noVariance, values, true), Double.MIN_VALUE); assertEquals(0d, new Covariance().covariance(noVariance, noVariance, true), Double.MIN_VALUE); } /** * Insufficient data */ public void testInsufficientData() { double[] one = new double[] {1}; double[] two = new double[] {2}; try { new Covariance().covariance(one, two, false); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } RealMatrix matrix = new Array2DRowRealMatrix(new double[][] {{0},{1}}); try { new Covariance(matrix); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // Expected } } /** * Verify that diagonal entries are consistent with Variance computation and matrix matches * column-by-column covariances */ public void testConsistency() { final RealMatrix matrix = createRealMatrix(swissData, 47, 5); final RealMatrix covarianceMatrix = new Covariance(matrix).getCovarianceMatrix(); // Variances on the diagonal Variance variance = new Variance(); for (int i = 0; i < 5; i++) { assertEquals(variance.evaluate(matrix.getColumn(i)), covarianceMatrix.getEntry(i,i), 10E-14); } // Symmetry, column-consistency assertEquals(covarianceMatrix.getEntry(2, 3), new Covariance().covariance(matrix.getColumn(2), matrix.getColumn(3), true), 10E-14); assertEquals(covarianceMatrix.getEntry(2, 3), covarianceMatrix.getEntry(3, 2), Double.MIN_VALUE); // All columns same -> all entries = column variance RealMatrix repeatedColumns = new Array2DRowRealMatrix(47, 3); for (int i = 0; i < 3; i++) { repeatedColumns.setColumnMatrix(i, matrix.getColumnMatrix(0)); } RealMatrix repeatedCovarianceMatrix = new Covariance(repeatedColumns).getCovarianceMatrix(); double columnVariance = variance.evaluate(matrix.getColumn(0)); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { assertEquals(columnVariance, repeatedCovarianceMatrix.getEntry(i, j), 10E-14); } } // Check bias-correction defaults double[][] data = matrix.getData(); TestUtils.assertEquals("Covariances", covarianceMatrix, new Covariance().computeCovarianceMatrix(data),Double.MIN_VALUE); TestUtils.assertEquals("Covariances", covarianceMatrix, new Covariance().computeCovarianceMatrix(data, true),Double.MIN_VALUE); double[] x = data[0]; double[] y = data[1]; assertEquals(new Covariance().covariance(x, y), new Covariance().covariance(x, y, true), Double.MIN_VALUE); } protected RealMatrix createRealMatrix(double[] data, int nRows, int nCols) { double[][] matrixData = new double[nRows][nCols]; int ptr = 0; for (int i = 0; i < nRows; i++) { System.arraycopy(data, ptr, matrixData[i], 0, nCols); ptr += nCols; } return new Array2DRowRealMatrix(matrixData); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/ranking/NaturalRankingTest.java100644 1750 1750 22010 11532241243 31437 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.ranking; import org.apache.commons.math.TestUtils; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.random.RandomGenerator; import junit.framework.TestCase; /** * Test cases for NaturalRanking class * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class NaturalRankingTest extends TestCase { private final double[] exampleData = { 20, 17, 30, 42.3, 17, 50, Double.NaN, Double.NEGATIVE_INFINITY, 17 }; private final double[] tiesFirst = { 0, 0, 2, 1, 4 }; private final double[] tiesLast = { 4, 4, 1, 0 }; private final double[] multipleNaNs = { 0, 1, Double.NaN, Double.NaN }; private final double[] multipleTies = { 3, 2, 5, 5, 6, 6, 1 }; private final double[] allSame = { 0, 0, 0, 0 }; public NaturalRankingTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); } public void testDefault() { // Ties averaged, NaNs maximal NaturalRanking ranking = new NaturalRanking(); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 3, 6, 7, 3, 8, 9, 1, 3 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3.5, 3.5, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2, 3.5, 3.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsMaximalTiesMinimum() { NaturalRanking ranking = new NaturalRanking(TiesStrategy.MINIMUM); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 2, 6, 7, 2, 8, 9, 1, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 1, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 3, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2, 3, 3 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4, 4, 6, 6, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 1, 1, 1, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsRemovedTiesSequential() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.REMOVED, TiesStrategy.SEQUENTIAL); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 2, 6, 7, 3, 8, 1, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 2, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 4, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4, 5, 6, 7, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 1, 2, 3, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsMinimalTiesMaximum() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL, TiesStrategy.MAXIMUM); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 6, 5, 7, 8, 5, 9, 2, 2, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 2, 2, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 4, 4, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 3, 4, 2, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 5, 5, 7, 7, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 4, 4, 4, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsMinimalTiesAverage() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 6, 4, 7, 8, 4, 9, 1.5, 1.5, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3.5, 3.5, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 3, 4, 1.5, 1.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsFixedTiesRandom() { RandomGenerator randomGenerator = new JDKRandomGenerator(); randomGenerator.setSeed(1000); NaturalRanking ranking = new NaturalRanking(NaNStrategy.FIXED, randomGenerator); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 4, 6, 7, 3, 8, Double.NaN, 1, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 1, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 4, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2, Double.NaN, Double.NaN }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 5, 5, 7, 6, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 1, 3, 4, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } public void testNaNsAndInfs() { double[] data = { 0, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY }; NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL); double[] ranks = ranking.rank(data); double[] correctRanks = new double[] { 2, 3.5, 3.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranking = new NaturalRanking(NaNStrategy.MINIMAL); ranks = ranking.rank(data); correctRanks = new double[] { 3, 4, 1.5, 1.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/ChiSquareTestTest.java100644 1750 1750 24045 11532241243 31562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import junit.framework.TestCase; /** * Test cases for the ChiSquareTestImpl class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class ChiSquareTestTest extends TestCase { protected UnknownDistributionChiSquareTest testStatistic = new ChiSquareTestImpl(); public ChiSquareTestTest(String name) { super(name); } public void testChiSquare() throws Exception { // Target values computed using R version 1.8.1 // Some assembly required ;-) // Use sum((obs - exp)^2/exp) for the chi-square statistic and // 1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value long[] observed = {10, 9, 11}; double[] expected = {10, 10, 10}; assertEquals("chi-square statistic", 0.2, testStatistic.chiSquare(expected, observed), 10E-12); assertEquals("chi-square p-value", 0.904837418036, testStatistic.chiSquareTest(expected, observed), 1E-10); long[] observed1 = { 500, 623, 72, 70, 31 }; double[] expected1 = { 485, 541, 82, 61, 37 }; assertEquals( "chi-square test statistic", 9.023307936427388, testStatistic.chiSquare(expected1, observed1), 1E-10); assertEquals("chi-square p-value", 0.06051952647453607, testStatistic.chiSquareTest(expected1, observed1), 1E-9); assertTrue("chi-square test reject", testStatistic.chiSquareTest(expected1, observed1, 0.08)); assertTrue("chi-square test accept", !testStatistic.chiSquareTest(expected1, observed1, 0.05)); try { testStatistic.chiSquareTest(expected1, observed1, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } long[] tooShortObs = { 0 }; double[] tooShortEx = { 1 }; try { testStatistic.chiSquare(tooShortEx, tooShortObs); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // unmatched arrays long[] unMatchedObs = { 0, 1, 2, 3 }; double[] unMatchedEx = { 1, 1, 2 }; try { testStatistic.chiSquare(unMatchedEx, unMatchedObs); fail("arrays have different lengths, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // 0 expected count expected[0] = 0; try { testStatistic.chiSquareTest(expected, observed, .01); fail("bad expected count, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // negative observed count expected[0] = 1; observed[0] = -1; try { testStatistic.chiSquareTest(expected, observed, .01); fail("bad expected count, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testChiSquareIndependence() throws Exception { // Target values computed using R version 1.8.1 long[][] counts = { {40, 22, 43}, {91, 21, 28}, {60, 10, 22}}; assertEquals( "chi-square test statistic", 22.709027688, testStatistic.chiSquare(counts), 1E-9); assertEquals("chi-square p-value", 0.000144751460134, testStatistic.chiSquareTest(counts), 1E-9); assertTrue("chi-square test reject", testStatistic.chiSquareTest(counts, 0.0002)); assertTrue("chi-square test accept", !testStatistic.chiSquareTest(counts, 0.0001)); long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} }; assertEquals( "chi-square test statistic", 0.168965517241, testStatistic.chiSquare(counts2), 1E-9); assertEquals("chi-square p-value",0.918987499852, testStatistic.chiSquareTest(counts2), 1E-9); assertTrue("chi-square test accept", !testStatistic.chiSquareTest(counts2, 0.1)); // ragged input array long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}}; try { testStatistic.chiSquare(counts3); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // insufficient data long[][] counts4 = {{40, 22, 43}}; try { testStatistic.chiSquare(counts4); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } long[][] counts5 = {{40}, {40}, {30}, {10}}; try { testStatistic.chiSquare(counts5); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // negative counts long[][] counts6 = {{10, -2}, {30, 40}, {60, 90} }; try { testStatistic.chiSquare(counts6); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // bad alpha try { testStatistic.chiSquareTest(counts, 0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testChiSquareLargeTestStatistic() throws Exception { double[] exp = new double[] { 3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0, 232921.0, 437665.75 }; long[] obs = new long[] { 2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899 }; org.apache.commons.math.stat.inference.ChiSquareTestImpl csti = new org.apache.commons.math.stat.inference.ChiSquareTestImpl(); double cst = csti.chiSquareTest(exp, obs); assertEquals("chi-square p-value", 0.0, cst, 1E-3); assertEquals( "chi-square test statistic", 114875.90421929007, testStatistic.chiSquare(exp, obs), 1E-9); } /** Contingency table containing zeros - PR # 32531 */ public void testChiSquareZeroCount() throws Exception { // Target values computed using R version 1.8.1 long[][] counts = { {40, 0, 4}, {91, 1, 2}, {60, 2, 0}}; assertEquals( "chi-square test statistic", 9.67444662263, testStatistic.chiSquare(counts), 1E-9); assertEquals("chi-square p-value", 0.0462835770603, testStatistic.chiSquareTest(counts), 1E-9); } /** Target values verified using DATAPLOT version 2006.3 */ public void testChiSquareDataSetsComparisonEqualCounts() throws Exception { long[] observed1 = {10, 12, 12, 10}; long[] observed2 = {5, 15, 14, 10}; assertEquals("chi-square p value", 0.541096, testStatistic.chiSquareTestDataSetsComparison( observed1, observed2), 1E-6); assertEquals("chi-square test statistic", 2.153846, testStatistic.chiSquareDataSetsComparison( observed1, observed2), 1E-6); assertFalse("chi-square test result", testStatistic.chiSquareTestDataSetsComparison( observed1, observed2, 0.4)); } /** Target values verified using DATAPLOT version 2006.3 */ public void testChiSquareDataSetsComparisonUnEqualCounts() throws Exception { long[] observed1 = {10, 12, 12, 10, 15}; long[] observed2 = {15, 10, 10, 15, 5}; assertEquals("chi-square p value", 0.124115, testStatistic.chiSquareTestDataSetsComparison( observed1, observed2), 1E-6); assertEquals("chi-square test statistic", 7.232189, testStatistic.chiSquareDataSetsComparison( observed1, observed2), 1E-6); assertTrue("chi-square test result", testStatistic.chiSquareTestDataSetsComparison( observed1, observed2, 0.13)); assertFalse("chi-square test result", testStatistic.chiSquareTestDataSetsComparison( observed1, observed2, 0.12)); } public void testChiSquareDataSetsComparisonBadCounts() throws Exception { long[] observed1 = {10, -1, 12, 10, 15}; long[] observed2 = {15, 10, 10, 15, 5}; try { testStatistic.chiSquareTestDataSetsComparison( observed1, observed2); fail("Expecting IllegalArgumentException - negative count"); } catch (IllegalArgumentException ex) { // expected } long[] observed3 = {10, 0, 12, 10, 15}; long[] observed4 = {15, 0, 10, 15, 5}; try { testStatistic.chiSquareTestDataSetsComparison( observed3, observed4); fail("Expecting IllegalArgumentException - double 0's"); } catch (IllegalArgumentException ex) { // expected } long[] observed5 = {10, 10, 12, 10, 15}; long[] observed6 = {0, 0, 0, 0, 0}; try { testStatistic.chiSquareTestDataSetsComparison( observed5, observed6); fail("Expecting IllegalArgumentException - vanishing counts"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/TTestTest.java100644 1750 1750 27307 11532241243 30105 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import junit.framework.TestCase; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Test cases for the TTestImpl class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class TTestTest extends TestCase { protected TTest testStatistic = new TTestImpl(); private double[] tooShortObs = { 1.0 }; private double[] emptyObs = {}; private SummaryStatistics emptyStats = new SummaryStatistics(); SummaryStatistics tooShortStats = null; public TTestTest(String name) { super(name); } @Override public void setUp() { tooShortStats = new SummaryStatistics(); tooShortStats.addValue(0d); } public void testOneSampleT() throws Exception { double[] observed = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0, 88.0, 98.0, 94.0, 101.0, 92.0, 95.0 }; double mu = 100.0; SummaryStatistics sampleStats = null; sampleStats = new SummaryStatistics(); for (int i = 0; i < observed.length; i++) { sampleStats.addValue(observed[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("t statistic", -2.81976445346, testStatistic.t(mu, observed), 10E-10); assertEquals("t statistic", -2.81976445346, testStatistic.t(mu, sampleStats), 10E-10); assertEquals("p value", 0.0136390585873, testStatistic.tTest(mu, observed), 10E-10); assertEquals("p value", 0.0136390585873, testStatistic.tTest(mu, sampleStats), 10E-10); try { testStatistic.t(mu, (double[]) null); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(mu, (SummaryStatistics) null); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(mu, emptyObs); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(mu, emptyStats); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(mu, tooShortObs); fail("insufficient data to compute t statistic, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(mu, tooShortObs); fail("insufficient data to perform t test, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(mu, tooShortStats); fail("insufficient data to compute t statistic, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(mu, tooShortStats); fail("insufficient data to perform t test, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testOneSampleTTest() throws Exception { double[] oneSidedP = {2d, 0d, 6d, 6d, 3d, 3d, 2d, 3d, -6d, 6d, 6d, 6d, 3d, 0d, 1d, 1d, 0d, 2d, 3d, 3d }; SummaryStatistics oneSidedPStats = new SummaryStatistics(); for (int i = 0; i < oneSidedP.length; i++) { oneSidedPStats.addValue(oneSidedP[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("one sample t stat", 3.86485535541, testStatistic.t(0d, oneSidedP), 10E-10); assertEquals("one sample t stat", 3.86485535541, testStatistic.t(0d, oneSidedPStats),1E-10); assertEquals("one sample p value", 0.000521637019637, testStatistic.tTest(0d, oneSidedP) / 2d, 10E-10); assertEquals("one sample p value", 0.000521637019637, testStatistic.tTest(0d, oneSidedPStats) / 2d, 10E-5); assertTrue("one sample t-test reject", testStatistic.tTest(0d, oneSidedP, 0.01)); assertTrue("one sample t-test reject", testStatistic.tTest(0d, oneSidedPStats, 0.01)); assertTrue("one sample t-test accept", !testStatistic.tTest(0d, oneSidedP, 0.0001)); assertTrue("one sample t-test accept", !testStatistic.tTest(0d, oneSidedPStats, 0.0001)); try { testStatistic.tTest(0d, oneSidedP, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(0d, oneSidedPStats, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testTwoSampleTHeterscedastic() throws Exception { double[] sample1 = { 7d, -4d, 18d, 17d, -3d, -5d, 1d, 10d, 11d, -2d }; double[] sample2 = { -1d, 12d, -1d, -3d, 3d, -5d, 5d, 2d, -11d, -1d, -3d }; SummaryStatistics sampleStats1 = new SummaryStatistics(); for (int i = 0; i < sample1.length; i++) { sampleStats1.addValue(sample1[i]); } SummaryStatistics sampleStats2 = new SummaryStatistics(); for (int i = 0; i < sample2.length; i++) { sampleStats2.addValue(sample2[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("two sample heteroscedastic t stat", 1.60371728768, testStatistic.t(sample1, sample2), 1E-10); assertEquals("two sample heteroscedastic t stat", 1.60371728768, testStatistic.t(sampleStats1, sampleStats2), 1E-10); assertEquals("two sample heteroscedastic p value", 0.128839369622, testStatistic.tTest(sample1, sample2), 1E-10); assertEquals("two sample heteroscedastic p value", 0.128839369622, testStatistic.tTest(sampleStats1, sampleStats2), 1E-10); assertTrue("two sample heteroscedastic t-test reject", testStatistic.tTest(sample1, sample2, 0.2)); assertTrue("two sample heteroscedastic t-test reject", testStatistic.tTest(sampleStats1, sampleStats2, 0.2)); assertTrue("two sample heteroscedastic t-test accept", !testStatistic.tTest(sample1, sample2, 0.1)); assertTrue("two sample heteroscedastic t-test accept", !testStatistic.tTest(sampleStats1, sampleStats2, 0.1)); try { testStatistic.tTest(sample1, sample2, .95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(sampleStats1, sampleStats2, .95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(sample1, tooShortObs, .01); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(sampleStats1, tooShortStats, .01); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(sample1, tooShortObs); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.tTest(sampleStats1, tooShortStats); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(sample1, tooShortObs); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { testStatistic.t(sampleStats1, tooShortStats); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testTwoSampleTHomoscedastic() throws Exception { double[] sample1 ={2, 4, 6, 8, 10, 97}; double[] sample2 = {4, 6, 8, 10, 16}; SummaryStatistics sampleStats1 = new SummaryStatistics(); for (int i = 0; i < sample1.length; i++) { sampleStats1.addValue(sample1[i]); } SummaryStatistics sampleStats2 = new SummaryStatistics(); for (int i = 0; i < sample2.length; i++) { sampleStats2.addValue(sample2[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("two sample homoscedastic t stat", 0.73096310086, testStatistic.homoscedasticT(sample1, sample2), 10E-11); assertEquals("two sample homoscedastic p value", 0.4833963785, testStatistic.homoscedasticTTest(sampleStats1, sampleStats2), 1E-10); assertTrue("two sample homoscedastic t-test reject", testStatistic.homoscedasticTTest(sample1, sample2, 0.49)); assertTrue("two sample homoscedastic t-test accept", !testStatistic.homoscedasticTTest(sample1, sample2, 0.48)); } public void testSmallSamples() throws Exception { double[] sample1 = {1d, 3d}; double[] sample2 = {4d, 5d}; // Target values computed using R, version 1.8.1 (linux version) assertEquals(-2.2360679775, testStatistic.t(sample1, sample2), 1E-10); assertEquals(0.198727388935, testStatistic.tTest(sample1, sample2), 1E-10); } public void testPaired() throws Exception { double[] sample1 = {1d, 3d, 5d, 7d}; double[] sample2 = {0d, 6d, 11d, 2d}; double[] sample3 = {5d, 7d, 8d, 10d}; // Target values computed using R, version 1.8.1 (linux version) assertEquals(-0.3133, testStatistic.pairedT(sample1, sample2), 1E-4); assertEquals(0.774544295819, testStatistic.pairedTTest(sample1, sample2), 1E-10); assertEquals(0.001208, testStatistic.pairedTTest(sample1, sample3), 1E-6); assertFalse(testStatistic.pairedTTest(sample1, sample3, .001)); assertTrue(testStatistic.pairedTTest(sample1, sample3, .002)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/TTestFactoryTest.java100644 1750 1750 2320 11532241243 31401 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; /** * Test cases for the TTestTestFactory. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class TTestFactoryTest extends TTestTest { public TTestFactoryTest(String name) { super(name); } @Override public void setUp() { super.setUp(); testStatistic = TestUtils.getTTest(); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/OneWayAnovaTest.java100644 1750 1750 10217 11532241243 31221 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; /** * Test cases for the OneWayAnovaImpl class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class OneWayAnovaTest extends TestCase { protected OneWayAnova testStatistic = new OneWayAnovaImpl(); private double[] emptyArray = {}; private double[] classA = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0 }; private double[] classB = {99.0, 92.0, 102.0, 100.0, 102.0, 89.0 }; private double[] classC = {110.0, 115.0, 111.0, 117.0, 128.0, 117.0 }; public OneWayAnovaTest(String name) { super(name); } public void testAnovaFValue() throws Exception { // Target comparison values computed using R version 2.6.0 (Linux version) List threeClasses = new ArrayList(); threeClasses.add(classA); threeClasses.add(classB); threeClasses.add(classC); assertEquals("ANOVA F-value", 24.67361709460624, testStatistic.anovaFValue(threeClasses), 1E-12); List twoClasses = new ArrayList(); twoClasses.add(classA); twoClasses.add(classB); assertEquals("ANOVA F-value", 0.0150579150579, testStatistic.anovaFValue(twoClasses), 1E-12); List emptyContents = new ArrayList(); emptyContents.add(emptyArray); emptyContents.add(classC); try { testStatistic.anovaFValue(emptyContents); fail("empty array for key classX, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } List tooFew = new ArrayList(); tooFew.add(classA); try { testStatistic.anovaFValue(tooFew); fail("less than two classes, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testAnovaPValue() throws Exception { // Target comparison values computed using R version 2.6.0 (Linux version) List threeClasses = new ArrayList(); threeClasses.add(classA); threeClasses.add(classB); threeClasses.add(classC); assertEquals("ANOVA P-value", 6.959446E-06, testStatistic.anovaPValue(threeClasses), 1E-12); List twoClasses = new ArrayList(); twoClasses.add(classA); twoClasses.add(classB); assertEquals("ANOVA P-value", 0.904212960464, testStatistic.anovaPValue(twoClasses), 1E-12); } public void testAnovaTest() throws Exception { // Target comparison values computed using R version 2.3.1 (Linux version) List threeClasses = new ArrayList(); threeClasses.add(classA); threeClasses.add(classB); threeClasses.add(classC); assertTrue("ANOVA Test P<0.01", testStatistic.anovaTest(threeClasses, 0.01)); List twoClasses = new ArrayList(); twoClasses.add(classA); twoClasses.add(classB); assertFalse("ANOVA Test P>0.01", testStatistic.anovaTest(twoClasses, 0.01)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/TestUtilsTest.java100644 1750 1750 44332 11532241243 30777 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Test cases for the TestUtils class. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class TestUtilsTest extends TestCase { public TestUtilsTest(String name) { super(name); } public void testChiSquare() throws Exception { // Target values computed using R version 1.8.1 // Some assembly required ;-) // Use sum((obs - exp)^2/exp) for the chi-square statistic and // 1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value long[] observed = {10, 9, 11}; double[] expected = {10, 10, 10}; assertEquals("chi-square statistic", 0.2, TestUtils.chiSquare(expected, observed), 10E-12); assertEquals("chi-square p-value", 0.904837418036, TestUtils.chiSquareTest(expected, observed), 1E-10); long[] observed1 = { 500, 623, 72, 70, 31 }; double[] expected1 = { 485, 541, 82, 61, 37 }; assertEquals( "chi-square test statistic", 9.023307936427388, TestUtils.chiSquare(expected1, observed1), 1E-10); assertEquals("chi-square p-value", 0.06051952647453607, TestUtils.chiSquareTest(expected1, observed1), 1E-9); assertTrue("chi-square test reject", TestUtils.chiSquareTest(expected1, observed1, 0.07)); assertTrue("chi-square test accept", !TestUtils.chiSquareTest(expected1, observed1, 0.05)); try { TestUtils.chiSquareTest(expected1, observed1, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } long[] tooShortObs = { 0 }; double[] tooShortEx = { 1 }; try { TestUtils.chiSquare(tooShortEx, tooShortObs); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // unmatched arrays long[] unMatchedObs = { 0, 1, 2, 3 }; double[] unMatchedEx = { 1, 1, 2 }; try { TestUtils.chiSquare(unMatchedEx, unMatchedObs); fail("arrays have different lengths, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // 0 expected count expected[0] = 0; try { TestUtils.chiSquareTest(expected, observed, .01); fail("bad expected count, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } // negative observed count expected[0] = 1; observed[0] = -1; try { TestUtils.chiSquareTest(expected, observed, .01); fail("bad expected count, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testChiSquareIndependence() throws Exception { // Target values computed using R version 1.8.1 long[][] counts = { {40, 22, 43}, {91, 21, 28}, {60, 10, 22}}; assertEquals( "chi-square test statistic", 22.709027688, TestUtils.chiSquare(counts), 1E-9); assertEquals("chi-square p-value", 0.000144751460134, TestUtils.chiSquareTest(counts), 1E-9); assertTrue("chi-square test reject", TestUtils.chiSquareTest(counts, 0.0002)); assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts, 0.0001)); long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} }; assertEquals( "chi-square test statistic", 0.168965517241, TestUtils.chiSquare(counts2), 1E-9); assertEquals("chi-square p-value",0.918987499852, TestUtils.chiSquareTest(counts2), 1E-9); assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts2, 0.1)); // ragged input array long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}}; try { TestUtils.chiSquare(counts3); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // insufficient data long[][] counts4 = {{40, 22, 43}}; try { TestUtils.chiSquare(counts4); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } long[][] counts5 = {{40}, {40}, {30}, {10}}; try { TestUtils.chiSquare(counts5); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // negative counts long[][] counts6 = {{10, -2}, {30, 40}, {60, 90} }; try { TestUtils.chiSquare(counts6); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // bad alpha try { TestUtils.chiSquareTest(counts, 0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testChiSquareLargeTestStatistic() throws Exception { double[] exp = new double[] { 3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0, 232921.0, 437665.75 }; long[] obs = new long[] { 2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899 }; org.apache.commons.math.stat.inference.ChiSquareTestImpl csti = new org.apache.commons.math.stat.inference.ChiSquareTestImpl(); double cst = csti.chiSquareTest(exp, obs); assertEquals("chi-square p-value", 0.0, cst, 1E-3); assertEquals( "chi-square test statistic", 114875.90421929007, TestUtils.chiSquare(exp, obs), 1E-9); } /** Contingency table containing zeros - PR # 32531 */ public void testChiSquareZeroCount() throws Exception { // Target values computed using R version 1.8.1 long[][] counts = { {40, 0, 4}, {91, 1, 2}, {60, 2, 0}}; assertEquals( "chi-square test statistic", 9.67444662263, TestUtils.chiSquare(counts), 1E-9); assertEquals("chi-square p-value", 0.0462835770603, TestUtils.chiSquareTest(counts), 1E-9); } private double[] tooShortObs = { 1.0 }; private double[] emptyObs = {}; private SummaryStatistics emptyStats = new SummaryStatistics(); public void testOneSampleT() throws Exception { double[] observed = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0, 88.0, 98.0, 94.0, 101.0, 92.0, 95.0 }; double mu = 100.0; SummaryStatistics sampleStats = null; sampleStats = new SummaryStatistics(); for (int i = 0; i < observed.length; i++) { sampleStats.addValue(observed[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("t statistic", -2.81976445346, TestUtils.t(mu, observed), 10E-10); assertEquals("t statistic", -2.81976445346, TestUtils.t(mu, sampleStats), 10E-10); assertEquals("p value", 0.0136390585873, TestUtils.tTest(mu, observed), 10E-10); assertEquals("p value", 0.0136390585873, TestUtils.tTest(mu, sampleStats), 10E-10); try { TestUtils.t(mu, (double[]) null); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(mu, (SummaryStatistics) null); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(mu, emptyObs); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(mu, emptyStats); fail("arguments too short, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(mu, tooShortObs); fail("insufficient data to compute t statistic, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(mu, tooShortObs); fail("insufficient data to perform t test, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(mu, (SummaryStatistics) null); fail("insufficient data to compute t statistic, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(mu, (SummaryStatistics) null); fail("insufficient data to perform t test, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testOneSampleTTest() throws Exception { double[] oneSidedP = {2d, 0d, 6d, 6d, 3d, 3d, 2d, 3d, -6d, 6d, 6d, 6d, 3d, 0d, 1d, 1d, 0d, 2d, 3d, 3d }; SummaryStatistics oneSidedPStats = new SummaryStatistics(); for (int i = 0; i < oneSidedP.length; i++) { oneSidedPStats.addValue(oneSidedP[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("one sample t stat", 3.86485535541, TestUtils.t(0d, oneSidedP), 10E-10); assertEquals("one sample t stat", 3.86485535541, TestUtils.t(0d, oneSidedPStats),1E-10); assertEquals("one sample p value", 0.000521637019637, TestUtils.tTest(0d, oneSidedP) / 2d, 10E-10); assertEquals("one sample p value", 0.000521637019637, TestUtils.tTest(0d, oneSidedPStats) / 2d, 10E-5); assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedP, 0.01)); assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedPStats, 0.01)); assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedP, 0.0001)); assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedPStats, 0.0001)); try { TestUtils.tTest(0d, oneSidedP, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(0d, oneSidedPStats, 95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testTwoSampleTHeterscedastic() throws Exception { double[] sample1 = { 7d, -4d, 18d, 17d, -3d, -5d, 1d, 10d, 11d, -2d }; double[] sample2 = { -1d, 12d, -1d, -3d, 3d, -5d, 5d, 2d, -11d, -1d, -3d }; SummaryStatistics sampleStats1 = new SummaryStatistics(); for (int i = 0; i < sample1.length; i++) { sampleStats1.addValue(sample1[i]); } SummaryStatistics sampleStats2 = new SummaryStatistics(); for (int i = 0; i < sample2.length; i++) { sampleStats2.addValue(sample2[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("two sample heteroscedastic t stat", 1.60371728768, TestUtils.t(sample1, sample2), 1E-10); assertEquals("two sample heteroscedastic t stat", 1.60371728768, TestUtils.t(sampleStats1, sampleStats2), 1E-10); assertEquals("two sample heteroscedastic p value", 0.128839369622, TestUtils.tTest(sample1, sample2), 1E-10); assertEquals("two sample heteroscedastic p value", 0.128839369622, TestUtils.tTest(sampleStats1, sampleStats2), 1E-10); assertTrue("two sample heteroscedastic t-test reject", TestUtils.tTest(sample1, sample2, 0.2)); assertTrue("two sample heteroscedastic t-test reject", TestUtils.tTest(sampleStats1, sampleStats2, 0.2)); assertTrue("two sample heteroscedastic t-test accept", !TestUtils.tTest(sample1, sample2, 0.1)); assertTrue("two sample heteroscedastic t-test accept", !TestUtils.tTest(sampleStats1, sampleStats2, 0.1)); try { TestUtils.tTest(sample1, sample2, .95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(sampleStats1, sampleStats2, .95); fail("alpha out of range, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(sample1, tooShortObs, .01); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(sampleStats1, (SummaryStatistics) null, .01); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(sample1, tooShortObs); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.tTest(sampleStats1, (SummaryStatistics) null); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(sample1, tooShortObs); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } try { TestUtils.t(sampleStats1, (SummaryStatistics) null); fail("insufficient data, IllegalArgumentException expected"); } catch (IllegalArgumentException ex) { // expected } } public void testTwoSampleTHomoscedastic() throws Exception { double[] sample1 ={2, 4, 6, 8, 10, 97}; double[] sample2 = {4, 6, 8, 10, 16}; SummaryStatistics sampleStats1 = new SummaryStatistics(); for (int i = 0; i < sample1.length; i++) { sampleStats1.addValue(sample1[i]); } SummaryStatistics sampleStats2 = new SummaryStatistics(); for (int i = 0; i < sample2.length; i++) { sampleStats2.addValue(sample2[i]); } // Target comparison values computed using R version 1.8.1 (Linux version) assertEquals("two sample homoscedastic t stat", 0.73096310086, TestUtils.homoscedasticT(sample1, sample2), 10E-11); assertEquals("two sample homoscedastic p value", 0.4833963785, TestUtils.homoscedasticTTest(sampleStats1, sampleStats2), 1E-10); assertTrue("two sample homoscedastic t-test reject", TestUtils.homoscedasticTTest(sample1, sample2, 0.49)); assertTrue("two sample homoscedastic t-test accept", !TestUtils.homoscedasticTTest(sample1, sample2, 0.48)); } public void testSmallSamples() throws Exception { double[] sample1 = {1d, 3d}; double[] sample2 = {4d, 5d}; // Target values computed using R, version 1.8.1 (linux version) assertEquals(-2.2360679775, TestUtils.t(sample1, sample2), 1E-10); assertEquals(0.198727388935, TestUtils.tTest(sample1, sample2), 1E-10); } public void testPaired() throws Exception { double[] sample1 = {1d, 3d, 5d, 7d}; double[] sample2 = {0d, 6d, 11d, 2d}; double[] sample3 = {5d, 7d, 8d, 10d}; // Target values computed using R, version 1.8.1 (linux version) assertEquals(-0.3133, TestUtils.pairedT(sample1, sample2), 1E-4); assertEquals(0.774544295819, TestUtils.pairedTTest(sample1, sample2), 1E-10); assertEquals(0.001208, TestUtils.pairedTTest(sample1, sample3), 1E-6); assertFalse(TestUtils.pairedTTest(sample1, sample3, .001)); assertTrue(TestUtils.pairedTTest(sample1, sample3, .002)); } private double[] classA = {93.0, 103.0, 95.0, 101.0}; private double[] classB = {99.0, 92.0, 102.0, 100.0, 102.0}; private double[] classC = {110.0, 115.0, 111.0, 117.0, 128.0}; private List classes = new ArrayList(); private OneWayAnova oneWayAnova = new OneWayAnovaImpl(); public void testOneWayAnovaUtils() throws Exception { classes.add(classA); classes.add(classB); classes.add(classC); assertEquals(oneWayAnova.anovaFValue(classes), TestUtils.oneWayAnovaFValue(classes), 10E-12); assertEquals(oneWayAnova.anovaPValue(classes), TestUtils.oneWayAnovaPValue(classes), 10E-12); assertEquals(oneWayAnova.anovaTest(classes, 0.01), TestUtils.oneWayAnovaTest(classes, 0.01)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/stat/inference/ChiSquareFactoryTest.java100644 1750 1750 2420 11532241243 32223 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; /** * Test cases for the ChiSquareTestFactory. * * @version $Revision: 902201 $ $Date: 2010-01-22 19:18:16 +0100 (ven. 22 janv. 2010) $ */ public class ChiSquareFactoryTest extends ChiSquareTestTest { public ChiSquareFactoryTest(String name) { super(name); } @Override public void setUp() throws Exception { super.setUp(); testStatistic = TestUtils.getUnknownDistributionChiSquareTest(); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/RotationTest.java100644 1750 1750 41770 11532241242 27562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import org.apache.commons.math.geometry.CardanEulerSingularityException; import org.apache.commons.math.geometry.NotARotationMatrixException; import org.apache.commons.math.geometry.Rotation; import org.apache.commons.math.geometry.RotationOrder; import org.apache.commons.math.geometry.Vector3D; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; import junit.framework.*; public class RotationTest extends TestCase { public RotationTest(String name) { super(name); } public void testIdentity() { Rotation r = Rotation.IDENTITY; checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_I); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.PLUS_J); checkVector(r.applyTo(Vector3D.PLUS_K), Vector3D.PLUS_K); checkAngle(r.getAngle(), 0); r = new Rotation(-1, 0, 0, 0, false); checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_I); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.PLUS_J); checkVector(r.applyTo(Vector3D.PLUS_K), Vector3D.PLUS_K); checkAngle(r.getAngle(), 0); r = new Rotation(42, 0, 0, 0, true); checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_I); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.PLUS_J); checkVector(r.applyTo(Vector3D.PLUS_K), Vector3D.PLUS_K); checkAngle(r.getAngle(), 0); } public void testAxisAngle() { Rotation r = new Rotation(new Vector3D(10, 10, 10), 2 * FastMath.PI / 3); checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_J); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.PLUS_K); checkVector(r.applyTo(Vector3D.PLUS_K), Vector3D.PLUS_I); double s = 1 / FastMath.sqrt(3); checkVector(r.getAxis(), new Vector3D(s, s, s)); checkAngle(r.getAngle(), 2 * FastMath.PI / 3); try { new Rotation(new Vector3D(0, 0, 0), 2 * FastMath.PI / 3); fail("an exception should have been thrown"); } catch (ArithmeticException e) { } r = new Rotation(Vector3D.PLUS_K, 1.5 * FastMath.PI); checkVector(r.getAxis(), new Vector3D(0, 0, -1)); checkAngle(r.getAngle(), 0.5 * FastMath.PI); r = new Rotation(Vector3D.PLUS_J, FastMath.PI); checkVector(r.getAxis(), Vector3D.PLUS_J); checkAngle(r.getAngle(), FastMath.PI); checkVector(Rotation.IDENTITY.getAxis(), Vector3D.PLUS_I); } public void testRevert() { Rotation r = new Rotation(0.001, 0.36, 0.48, 0.8, true); Rotation reverted = r.revert(); checkRotation(r.applyTo(reverted), 1, 0, 0, 0); checkRotation(reverted.applyTo(r), 1, 0, 0, 0); assertEquals(r.getAngle(), reverted.getAngle(), 1.0e-12); assertEquals(-1, Vector3D.dotProduct(r.getAxis(), reverted.getAxis()), 1.0e-12); } public void testVectorOnePair() { Vector3D u = new Vector3D(3, 2, 1); Vector3D v = new Vector3D(-4, 2, 2); Rotation r = new Rotation(u, v); checkVector(r.applyTo(u.scalarMultiply(v.getNorm())), v.scalarMultiply(u.getNorm())); checkAngle(new Rotation(u, u.negate()).getAngle(), FastMath.PI); try { new Rotation(u, Vector3D.ZERO); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // expected behavior } } public void testVectorTwoPairs() { Vector3D u1 = new Vector3D(3, 0, 0); Vector3D u2 = new Vector3D(0, 5, 0); Vector3D v1 = new Vector3D(0, 0, 2); Vector3D v2 = new Vector3D(-2, 0, 2); Rotation r = new Rotation(u1, u2, v1, v2); checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_K); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.MINUS_I); r = new Rotation(u1, u2, u1.negate(), u2.negate()); Vector3D axis = r.getAxis(); if (Vector3D.dotProduct(axis, Vector3D.PLUS_K) > 0) { checkVector(axis, Vector3D.PLUS_K); } else { checkVector(axis, Vector3D.MINUS_K); } checkAngle(r.getAngle(), FastMath.PI); double sqrt = FastMath.sqrt(2) / 2; r = new Rotation(Vector3D.PLUS_I, Vector3D.PLUS_J, new Vector3D(0.5, 0.5, sqrt), new Vector3D(0.5, 0.5, -sqrt)); checkRotation(r, sqrt, 0.5, 0.5, 0); r = new Rotation(u1, u2, u1, Vector3D.crossProduct(u1, u2)); checkRotation(r, sqrt, -sqrt, 0, 0); checkRotation(new Rotation(u1, u2, u1, u2), 1, 0, 0, 0); try { new Rotation(u1, u2, Vector3D.ZERO, v2); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // expected behavior } } public void testMatrix() throws NotARotationMatrixException { try { new Rotation(new double[][] { { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 } }, 1.0e-7); fail("Expecting NotARotationMatrixException"); } catch (NotARotationMatrixException nrme) { // expected behavior } try { new Rotation(new double[][] { { 0.445888, 0.797184, -0.407040 }, { 0.821760, -0.184320, 0.539200 }, { -0.354816, 0.574912, 0.737280 } }, 1.0e-7); fail("Expecting NotARotationMatrixException"); } catch (NotARotationMatrixException nrme) { // expected behavior } try { new Rotation(new double[][] { { 0.4, 0.8, -0.4 }, { -0.4, 0.6, 0.7 }, { 0.8, -0.2, 0.5 } }, 1.0e-15); fail("Expecting NotARotationMatrixException"); } catch (NotARotationMatrixException nrme) { // expected behavior } checkRotation(new Rotation(new double[][] { { 0.445888, 0.797184, -0.407040 }, { -0.354816, 0.574912, 0.737280 }, { 0.821760, -0.184320, 0.539200 } }, 1.0e-10), 0.8, 0.288, 0.384, 0.36); checkRotation(new Rotation(new double[][] { { 0.539200, 0.737280, 0.407040 }, { 0.184320, -0.574912, 0.797184 }, { 0.821760, -0.354816, -0.445888 } }, 1.0e-10), 0.36, 0.8, 0.288, 0.384); checkRotation(new Rotation(new double[][] { { -0.445888, 0.797184, -0.407040 }, { 0.354816, 0.574912, 0.737280 }, { 0.821760, 0.184320, -0.539200 } }, 1.0e-10), 0.384, 0.36, 0.8, 0.288); checkRotation(new Rotation(new double[][] { { -0.539200, 0.737280, 0.407040 }, { -0.184320, -0.574912, 0.797184 }, { 0.821760, 0.354816, 0.445888 } }, 1.0e-10), 0.288, 0.384, 0.36, 0.8); double[][] m1 = { { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 1.0, 0.0, 0.0 } }; Rotation r = new Rotation(m1, 1.0e-7); checkVector(r.applyTo(Vector3D.PLUS_I), Vector3D.PLUS_K); checkVector(r.applyTo(Vector3D.PLUS_J), Vector3D.PLUS_I); checkVector(r.applyTo(Vector3D.PLUS_K), Vector3D.PLUS_J); double[][] m2 = { { 0.83203, -0.55012, -0.07139 }, { 0.48293, 0.78164, -0.39474 }, { 0.27296, 0.29396, 0.91602 } }; r = new Rotation(m2, 1.0e-12); double[][] m3 = r.getMatrix(); double d00 = m2[0][0] - m3[0][0]; double d01 = m2[0][1] - m3[0][1]; double d02 = m2[0][2] - m3[0][2]; double d10 = m2[1][0] - m3[1][0]; double d11 = m2[1][1] - m3[1][1]; double d12 = m2[1][2] - m3[1][2]; double d20 = m2[2][0] - m3[2][0]; double d21 = m2[2][1] - m3[2][1]; double d22 = m2[2][2] - m3[2][2]; assertTrue(FastMath.abs(d00) < 6.0e-6); assertTrue(FastMath.abs(d01) < 6.0e-6); assertTrue(FastMath.abs(d02) < 6.0e-6); assertTrue(FastMath.abs(d10) < 6.0e-6); assertTrue(FastMath.abs(d11) < 6.0e-6); assertTrue(FastMath.abs(d12) < 6.0e-6); assertTrue(FastMath.abs(d20) < 6.0e-6); assertTrue(FastMath.abs(d21) < 6.0e-6); assertTrue(FastMath.abs(d22) < 6.0e-6); assertTrue(FastMath.abs(d00) > 4.0e-7); assertTrue(FastMath.abs(d01) > 4.0e-7); assertTrue(FastMath.abs(d02) > 4.0e-7); assertTrue(FastMath.abs(d10) > 4.0e-7); assertTrue(FastMath.abs(d11) > 4.0e-7); assertTrue(FastMath.abs(d12) > 4.0e-7); assertTrue(FastMath.abs(d20) > 4.0e-7); assertTrue(FastMath.abs(d21) > 4.0e-7); assertTrue(FastMath.abs(d22) > 4.0e-7); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { double m3tm3 = m3[i][0] * m3[j][0] + m3[i][1] * m3[j][1] + m3[i][2] * m3[j][2]; if (i == j) { assertTrue(FastMath.abs(m3tm3 - 1.0) < 1.0e-10); } else { assertTrue(FastMath.abs(m3tm3) < 1.0e-10); } } } checkVector(r.applyTo(Vector3D.PLUS_I), new Vector3D(m3[0][0], m3[1][0], m3[2][0])); checkVector(r.applyTo(Vector3D.PLUS_J), new Vector3D(m3[0][1], m3[1][1], m3[2][1])); checkVector(r.applyTo(Vector3D.PLUS_K), new Vector3D(m3[0][2], m3[1][2], m3[2][2])); double[][] m4 = { { 1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 0.0, -1.0 } }; r = new Rotation(m4, 1.0e-7); checkAngle(r.getAngle(), FastMath.PI); try { double[][] m5 = { { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 } }; r = new Rotation(m5, 1.0e-7); fail("got " + r + ", should have caught an exception"); } catch (NotARotationMatrixException e) { // expected } } public void testAngles() throws CardanEulerSingularityException { RotationOrder[] CardanOrders = { RotationOrder.XYZ, RotationOrder.XZY, RotationOrder.YXZ, RotationOrder.YZX, RotationOrder.ZXY, RotationOrder.ZYX }; for (int i = 0; i < CardanOrders.length; ++i) { for (double alpha1 = 0.1; alpha1 < 6.2; alpha1 += 0.3) { for (double alpha2 = -1.55; alpha2 < 1.55; alpha2 += 0.3) { for (double alpha3 = 0.1; alpha3 < 6.2; alpha3 += 0.3) { Rotation r = new Rotation(CardanOrders[i], alpha1, alpha2, alpha3); double[] angles = r.getAngles(CardanOrders[i]); checkAngle(angles[0], alpha1); checkAngle(angles[1], alpha2); checkAngle(angles[2], alpha3); } } } } RotationOrder[] EulerOrders = { RotationOrder.XYX, RotationOrder.XZX, RotationOrder.YXY, RotationOrder.YZY, RotationOrder.ZXZ, RotationOrder.ZYZ }; for (int i = 0; i < EulerOrders.length; ++i) { for (double alpha1 = 0.1; alpha1 < 6.2; alpha1 += 0.3) { for (double alpha2 = 0.05; alpha2 < 3.1; alpha2 += 0.3) { for (double alpha3 = 0.1; alpha3 < 6.2; alpha3 += 0.3) { Rotation r = new Rotation(EulerOrders[i], alpha1, alpha2, alpha3); double[] angles = r.getAngles(EulerOrders[i]); checkAngle(angles[0], alpha1); checkAngle(angles[1], alpha2); checkAngle(angles[2], alpha3); } } } } } public void testSingularities() { RotationOrder[] CardanOrders = { RotationOrder.XYZ, RotationOrder.XZY, RotationOrder.YXZ, RotationOrder.YZX, RotationOrder.ZXY, RotationOrder.ZYX }; double[] singularCardanAngle = { FastMath.PI / 2, -FastMath.PI / 2 }; for (int i = 0; i < CardanOrders.length; ++i) { for (int j = 0; j < singularCardanAngle.length; ++j) { Rotation r = new Rotation(CardanOrders[i], 0.1, singularCardanAngle[j], 0.3); try { r.getAngles(CardanOrders[i]); fail("an exception should have been caught"); } catch (CardanEulerSingularityException cese) { // expected behavior } } } RotationOrder[] EulerOrders = { RotationOrder.XYX, RotationOrder.XZX, RotationOrder.YXY, RotationOrder.YZY, RotationOrder.ZXZ, RotationOrder.ZYZ }; double[] singularEulerAngle = { 0, FastMath.PI }; for (int i = 0; i < EulerOrders.length; ++i) { for (int j = 0; j < singularEulerAngle.length; ++j) { Rotation r = new Rotation(EulerOrders[i], 0.1, singularEulerAngle[j], 0.3); try { r.getAngles(EulerOrders[i]); fail("an exception should have been caught"); } catch (CardanEulerSingularityException cese) { // expected behavior } } } } public void testQuaternion() { Rotation r1 = new Rotation(new Vector3D(2, -3, 5), 1.7); double n = 23.5; Rotation r2 = new Rotation(n * r1.getQ0(), n * r1.getQ1(), n * r1.getQ2(), n * r1.getQ3(), true); for (double x = -0.9; x < 0.9; x += 0.2) { for (double y = -0.9; y < 0.9; y += 0.2) { for (double z = -0.9; z < 0.9; z += 0.2) { Vector3D u = new Vector3D(x, y, z); checkVector(r2.applyTo(u), r1.applyTo(u)); } } } r1 = new Rotation( 0.288, 0.384, 0.36, 0.8, false); checkRotation(r1, -r1.getQ0(), -r1.getQ1(), -r1.getQ2(), -r1.getQ3()); } public void testCompose() { Rotation r1 = new Rotation(new Vector3D(2, -3, 5), 1.7); Rotation r2 = new Rotation(new Vector3D(-1, 3, 2), 0.3); Rotation r3 = r2.applyTo(r1); for (double x = -0.9; x < 0.9; x += 0.2) { for (double y = -0.9; y < 0.9; y += 0.2) { for (double z = -0.9; z < 0.9; z += 0.2) { Vector3D u = new Vector3D(x, y, z); checkVector(r2.applyTo(r1.applyTo(u)), r3.applyTo(u)); } } } } public void testComposeInverse() { Rotation r1 = new Rotation(new Vector3D(2, -3, 5), 1.7); Rotation r2 = new Rotation(new Vector3D(-1, 3, 2), 0.3); Rotation r3 = r2.applyInverseTo(r1); for (double x = -0.9; x < 0.9; x += 0.2) { for (double y = -0.9; y < 0.9; y += 0.2) { for (double z = -0.9; z < 0.9; z += 0.2) { Vector3D u = new Vector3D(x, y, z); checkVector(r2.applyInverseTo(r1.applyTo(u)), r3.applyTo(u)); } } } } public void testApplyInverseTo() { Rotation r = new Rotation(new Vector3D(2, -3, 5), 1.7); for (double lambda = 0; lambda < 6.2; lambda += 0.2) { for (double phi = -1.55; phi < 1.55; phi += 0.2) { Vector3D u = new Vector3D(FastMath.cos(lambda) * FastMath.cos(phi), FastMath.sin(lambda) * FastMath.cos(phi), FastMath.sin(phi)); r.applyInverseTo(r.applyTo(u)); checkVector(u, r.applyInverseTo(r.applyTo(u))); checkVector(u, r.applyTo(r.applyInverseTo(u))); } } r = Rotation.IDENTITY; for (double lambda = 0; lambda < 6.2; lambda += 0.2) { for (double phi = -1.55; phi < 1.55; phi += 0.2) { Vector3D u = new Vector3D(FastMath.cos(lambda) * FastMath.cos(phi), FastMath.sin(lambda) * FastMath.cos(phi), FastMath.sin(phi)); checkVector(u, r.applyInverseTo(r.applyTo(u))); checkVector(u, r.applyTo(r.applyInverseTo(u))); } } r = new Rotation(Vector3D.PLUS_K, FastMath.PI); for (double lambda = 0; lambda < 6.2; lambda += 0.2) { for (double phi = -1.55; phi < 1.55; phi += 0.2) { Vector3D u = new Vector3D(FastMath.cos(lambda) * FastMath.cos(phi), FastMath.sin(lambda) * FastMath.cos(phi), FastMath.sin(phi)); checkVector(u, r.applyInverseTo(r.applyTo(u))); checkVector(u, r.applyTo(r.applyInverseTo(u))); } } } private void checkVector(Vector3D v1, Vector3D v2) { assertTrue(v1.subtract(v2).getNorm() < 1.0e-10); } private void checkAngle(double a1, double a2) { assertEquals(a1, MathUtils.normalizeAngle(a2, a1), 1.0e-10); } private void checkRotation(Rotation r, double q0, double q1, double q2, double q3) { assertEquals(0, Rotation.distance(r, new Rotation(q0, q1, q2, q3, false)), 1.0e-12); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/RotationOrderTest.java100644 1750 1750 3535 11532241242 30533 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.lang.reflect.Field; import org.apache.commons.math.geometry.RotationOrder; import junit.framework.*; public class RotationOrderTest extends TestCase { public RotationOrderTest(String name) { super(name); } public void testName() { RotationOrder[] orders = { RotationOrder.XYZ, RotationOrder.XZY, RotationOrder.YXZ, RotationOrder.YZX, RotationOrder.ZXY, RotationOrder.ZYX, RotationOrder.XYX, RotationOrder.XZX, RotationOrder.YXY, RotationOrder.YZY, RotationOrder.ZXZ, RotationOrder.ZYZ }; for (int i = 0; i < orders.length; ++i) { assertEquals(getFieldName(orders[i]), orders[i].toString()); } } private String getFieldName(RotationOrder order) { try { Field[] fields = RotationOrder.class.getFields(); for (int i = 0; i < fields.length; ++i) { if (fields[i].get(null) == order) { return fields[i].getName(); } } } catch (IllegalAccessException iae) { // ignored } return "unknown"; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/Vector3DTest.java100644 1750 1750 17445 11532241242 27416 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import org.apache.commons.math.geometry.Vector3D; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class Vector3DTest extends TestCase { public Vector3DTest(String name) { super(name); } public void testConstructors() { double r = FastMath.sqrt(2) /2; checkVector(new Vector3D(2, new Vector3D(FastMath.PI / 3, -FastMath.PI / 4)), r, r * FastMath.sqrt(3), -2 * r); checkVector(new Vector3D(2, Vector3D.PLUS_I, -3, Vector3D.MINUS_K), 2, 0, 3); checkVector(new Vector3D(2, Vector3D.PLUS_I, 5, Vector3D.PLUS_J, -3, Vector3D.MINUS_K), 2, 5, 3); checkVector(new Vector3D(2, Vector3D.PLUS_I, 5, Vector3D.PLUS_J, 5, Vector3D.MINUS_J, -3, Vector3D.MINUS_K), 2, 0, 3); } public void testCoordinates() { Vector3D v = new Vector3D(1, 2, 3); assertTrue(FastMath.abs(v.getX() - 1) < 1.0e-12); assertTrue(FastMath.abs(v.getY() - 2) < 1.0e-12); assertTrue(FastMath.abs(v.getZ() - 3) < 1.0e-12); } public void testNorm1() { assertEquals(0.0, Vector3D.ZERO.getNorm1()); assertEquals(6.0, new Vector3D(1, -2, 3).getNorm1(), 0); } public void testNorm() { assertEquals(0.0, Vector3D.ZERO.getNorm()); assertEquals(FastMath.sqrt(14), new Vector3D(1, 2, 3).getNorm(), 1.0e-12); } public void testNormInf() { assertEquals(0.0, Vector3D.ZERO.getNormInf()); assertEquals(3.0, new Vector3D(1, -2, 3).getNormInf(), 0); } public void testDistance1() { Vector3D v1 = new Vector3D(1, -2, 3); Vector3D v2 = new Vector3D(-4, 2, 0); assertEquals(0.0, Vector3D.distance1(Vector3D.MINUS_I, Vector3D.MINUS_I), 0); assertEquals(12.0, Vector3D.distance1(v1, v2), 1.0e-12); assertEquals(v1.subtract(v2).getNorm1(), Vector3D.distance1(v1, v2), 1.0e-12); } public void testDistance() { Vector3D v1 = new Vector3D(1, -2, 3); Vector3D v2 = new Vector3D(-4, 2, 0); assertEquals(0.0, Vector3D.distance(Vector3D.MINUS_I, Vector3D.MINUS_I), 0); assertEquals(FastMath.sqrt(50), Vector3D.distance(v1, v2), 1.0e-12); assertEquals(v1.subtract(v2).getNorm(), Vector3D.distance(v1, v2), 1.0e-12); } public void testDistanceSq() { Vector3D v1 = new Vector3D(1, -2, 3); Vector3D v2 = new Vector3D(-4, 2, 0); assertEquals(0.0, Vector3D.distanceSq(Vector3D.MINUS_I, Vector3D.MINUS_I), 0); assertEquals(50.0, Vector3D.distanceSq(v1, v2), 1.0e-12); assertEquals(Vector3D.distance(v1, v2) * Vector3D.distance(v1, v2), Vector3D.distanceSq(v1, v2), 1.0e-12); } public void testDistanceInf() { Vector3D v1 = new Vector3D(1, -2, 3); Vector3D v2 = new Vector3D(-4, 2, 0); assertEquals(0.0, Vector3D.distanceInf(Vector3D.MINUS_I, Vector3D.MINUS_I), 0); assertEquals(5.0, Vector3D.distanceInf(v1, v2), 1.0e-12); assertEquals(v1.subtract(v2).getNormInf(), Vector3D.distanceInf(v1, v2), 1.0e-12); } public void testSubtract() { Vector3D v1 = new Vector3D(1, 2, 3); Vector3D v2 = new Vector3D(-3, -2, -1); v1 = v1.subtract(v2); checkVector(v1, 4, 4, 4); checkVector(v2.subtract(v1), -7, -6, -5); checkVector(v2.subtract(3, v1), -15, -14, -13); } public void testAdd() { Vector3D v1 = new Vector3D(1, 2, 3); Vector3D v2 = new Vector3D(-3, -2, -1); v1 = v1.add(v2); checkVector(v1, -2, 0, 2); checkVector(v2.add(v1), -5, -2, 1); checkVector(v2.add(3, v1), -9, -2, 5); } public void testScalarProduct() { Vector3D v = new Vector3D(1, 2, 3); v = v.scalarMultiply(3); checkVector(v, 3, 6, 9); checkVector(v.scalarMultiply(0.5), 1.5, 3, 4.5); } public void testVectorialProducts() { Vector3D v1 = new Vector3D(2, 1, -4); Vector3D v2 = new Vector3D(3, 1, -1); assertTrue(FastMath.abs(Vector3D.dotProduct(v1, v2) - 11) < 1.0e-12); Vector3D v3 = Vector3D.crossProduct(v1, v2); checkVector(v3, 3, -10, -1); assertTrue(FastMath.abs(Vector3D.dotProduct(v1, v3)) < 1.0e-12); assertTrue(FastMath.abs(Vector3D.dotProduct(v2, v3)) < 1.0e-12); } public void testAngular() { assertEquals(0, Vector3D.PLUS_I.getAlpha(), 1.0e-10); assertEquals(0, Vector3D.PLUS_I.getDelta(), 1.0e-10); assertEquals(FastMath.PI / 2, Vector3D.PLUS_J.getAlpha(), 1.0e-10); assertEquals(0, Vector3D.PLUS_J.getDelta(), 1.0e-10); assertEquals(0, Vector3D.PLUS_K.getAlpha(), 1.0e-10); assertEquals(FastMath.PI / 2, Vector3D.PLUS_K.getDelta(), 1.0e-10); Vector3D u = new Vector3D(-1, 1, -1); assertEquals(3 * FastMath.PI /4, u.getAlpha(), 1.0e-10); assertEquals(-1.0 / FastMath.sqrt(3), FastMath.sin(u.getDelta()), 1.0e-10); } public void testAngularSeparation() { Vector3D v1 = new Vector3D(2, -1, 4); Vector3D k = v1.normalize(); Vector3D i = k.orthogonal(); Vector3D v2 = k.scalarMultiply(FastMath.cos(1.2)).add(i.scalarMultiply(FastMath.sin(1.2))); assertTrue(FastMath.abs(Vector3D.angle(v1, v2) - 1.2) < 1.0e-12); } public void testNormalize() { assertEquals(1.0, new Vector3D(5, -4, 2).normalize().getNorm(), 1.0e-12); try { Vector3D.ZERO.normalize(); fail("an exception should have been thrown"); } catch (ArithmeticException ae) { // expected behavior } } public void testOrthogonal() { Vector3D v1 = new Vector3D(0.1, 2.5, 1.3); assertEquals(0.0, Vector3D.dotProduct(v1, v1.orthogonal()), 1.0e-12); Vector3D v2 = new Vector3D(2.3, -0.003, 7.6); assertEquals(0.0, Vector3D.dotProduct(v2, v2.orthogonal()), 1.0e-12); Vector3D v3 = new Vector3D(-1.7, 1.4, 0.2); assertEquals(0.0, Vector3D.dotProduct(v3, v3.orthogonal()), 1.0e-12); try { new Vector3D(0, 0, 0).orthogonal(); fail("an exception should have been thrown"); } catch (ArithmeticException ae) { // expected behavior } } public void testAngle() { assertEquals(0.22572612855273393616, Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(4, 5, 6)), 1.0e-12); assertEquals(7.98595620686106654517199e-8, Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(2, 4, 6.000001)), 1.0e-12); assertEquals(3.14159257373023116985197793156, Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(-2, -4, -6.000001)), 1.0e-12); try { Vector3D.angle(Vector3D.ZERO, Vector3D.PLUS_I); fail("an exception should have been thrown"); } catch (ArithmeticException ae) { // expected behavior } } private void checkVector(Vector3D v, double x, double y, double z) { assertEquals(x, v.getX(), 1.0e-12); assertEquals(y, v.getY(), 1.0e-12); assertEquals(z, v.getZ(), 1.0e-12); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/Vector3DFormatAbstractTest.java100644 1750 1750 30237 11532241242 32245 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import junit.framework.TestCase; import org.apache.commons.math.util.CompositeFormat; public abstract class Vector3DFormatAbstractTest extends TestCase { Vector3DFormat vector3DFormat = null; Vector3DFormat vector3DFormatSquare = null; protected abstract Locale getLocale(); protected abstract char getDecimalCharacter(); @Override protected void setUp() throws Exception { vector3DFormat = Vector3DFormat.getInstance(getLocale()); final NumberFormat nf = NumberFormat.getInstance(getLocale()); nf.setMaximumFractionDigits(2); vector3DFormatSquare = new Vector3DFormat("[", "]", " : ", nf); } public void testSimpleNoDecimals() { Vector3D c = new Vector3D(1, 1, 1); String expected = "{1; 1; 1}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testSimpleWithDecimals() { Vector3D c = new Vector3D(1.23, 1.43, 1.63); String expected = "{1" + getDecimalCharacter() + "23; 1" + getDecimalCharacter() + "43; 1" + getDecimalCharacter() + "63}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testSimpleWithDecimalsTrunc() { Vector3D c = new Vector3D(1.2323, 1.4343, 1.6333); String expected = "{1" + getDecimalCharacter() + "23; 1" + getDecimalCharacter() + "43; 1" + getDecimalCharacter() + "63}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testNegativeX() { Vector3D c = new Vector3D(-1.2323, 1.4343, 1.6333); String expected = "{-1" + getDecimalCharacter() + "23; 1" + getDecimalCharacter() + "43; 1" + getDecimalCharacter() + "63}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testNegativeY() { Vector3D c = new Vector3D(1.2323, -1.4343, 1.6333); String expected = "{1" + getDecimalCharacter() + "23; -1" + getDecimalCharacter() + "43; 1" + getDecimalCharacter() + "63}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testNegativeZ() { Vector3D c = new Vector3D(1.2323, 1.4343, -1.6333); String expected = "{1" + getDecimalCharacter() + "23; 1" + getDecimalCharacter() + "43; -1" + getDecimalCharacter() + "63}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testNonDefaultSetting() { Vector3D c = new Vector3D(1, 1, 1); String expected = "[1 : 1 : 1]"; String actual = vector3DFormatSquare.format(c); assertEquals(expected, actual); } public void testStaticFormatVector3D() { Locale defaultLocal = Locale.getDefault(); Locale.setDefault(getLocale()); Vector3D c = new Vector3D(232.222, -342.33, 432.444); String expected = "{232" + getDecimalCharacter() + "22; -342" + getDecimalCharacter() + "33; 432" + getDecimalCharacter() + "44}"; String actual = Vector3DFormat.formatVector3D(c); assertEquals(expected, actual); Locale.setDefault(defaultLocal); } public void testNan() { Vector3D c = Vector3D.NaN; String expected = "{(NaN); (NaN); (NaN)}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testPositiveInfinity() { Vector3D c = Vector3D.POSITIVE_INFINITY; String expected = "{(Infinity); (Infinity); (Infinity)}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void tesNegativeInfinity() { Vector3D c = Vector3D.NEGATIVE_INFINITY; String expected = "{(-Infinity); (-Infinity); (-Infinity)}"; String actual = vector3DFormat.format(c); assertEquals(expected, actual); } public void testParseSimpleNoDecimals() { String source = "{1; 1; 1}"; Vector3D expected = new Vector3D(1, 1, 1); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseIgnoredWhitespace() { Vector3D expected = new Vector3D(1, 1, 1); ParsePosition pos1 = new ParsePosition(0); String source1 = "{1;1;1}"; assertEquals(expected, vector3DFormat.parseObject(source1, pos1)); assertEquals(source1.length(), pos1.getIndex()); ParsePosition pos2 = new ParsePosition(0); String source2 = " { 1 ; 1 ; 1 } "; assertEquals(expected, vector3DFormat.parseObject(source2, pos2)); assertEquals(source2.length() - 1, pos2.getIndex()); } public void testParseSimpleWithDecimals() { String source = "{1" + getDecimalCharacter() + "23; 1" + getDecimalCharacter() + "43; 1" + getDecimalCharacter() + "63}"; Vector3D expected = new Vector3D(1.23, 1.43, 1.63); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseSimpleWithDecimalsTrunc() { String source = "{1" + getDecimalCharacter() + "2323; 1" + getDecimalCharacter() + "4343; 1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(1.2323, 1.4343, 1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeX() { String source = "{-1" + getDecimalCharacter() + "2323; 1" + getDecimalCharacter() + "4343; 1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(-1.2323, 1.4343, 1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeY() { String source = "{1" + getDecimalCharacter() + "2323; -1" + getDecimalCharacter() + "4343; 1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(1.2323, -1.4343, 1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeZ() { String source = "{1" + getDecimalCharacter() + "2323; 1" + getDecimalCharacter() + "4343; -1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(1.2323, 1.4343, -1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeAll() { String source = "{-1" + getDecimalCharacter() + "2323; -1" + getDecimalCharacter() + "4343; -1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(-1.2323, -1.4343, -1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseZeroX() { String source = "{0" + getDecimalCharacter() + "0; -1" + getDecimalCharacter() + "4343; 1" + getDecimalCharacter() + "6333}"; Vector3D expected = new Vector3D(0.0, -1.4343, 1.6333); try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNonDefaultSetting() { String source = "[1" + getDecimalCharacter() + "2323 : 1" + getDecimalCharacter() + "4343 : 1" + getDecimalCharacter() + "6333]"; Vector3D expected = new Vector3D(1.2323, 1.4343, 1.6333); try { Vector3D actual = (Vector3D) vector3DFormatSquare.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNan() { String source = "{(NaN); (NaN); (NaN)}"; try { Vector3D actual = (Vector3D) vector3DFormat.parseObject(source); assertEquals(Vector3D.NaN, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParsePositiveInfinity() { String source = "{(Infinity); (Infinity); (Infinity)}"; try { Vector3D actual = (Vector3D)vector3DFormat.parseObject(source); assertEquals(Vector3D.POSITIVE_INFINITY, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeInfinity() { String source = "{(-Infinity); (-Infinity); (-Infinity)}"; try { Vector3D actual = (Vector3D)vector3DFormat.parseObject(source); assertEquals(Vector3D.NEGATIVE_INFINITY, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testConstructorSingleFormat() { NumberFormat nf = NumberFormat.getInstance(); Vector3DFormat cf = new Vector3DFormat(nf); assertNotNull(cf); assertEquals(nf, cf.getFormat()); } public void testFormatObject() { try { CompositeFormat cf = new Vector3DFormat(); Object object = new Object(); cf.format(object); fail(); } catch (IllegalArgumentException ex) { // success } } public void testForgottenPrefix() { ParsePosition pos = new ParsePosition(0); assertNull(new Vector3DFormat().parse("1; 1; 1}", pos)); assertEquals(0, pos.getErrorIndex()); } public void testForgottenSeparator() { ParsePosition pos = new ParsePosition(0); assertNull(new Vector3DFormat().parse("{1; 1 1}", pos)); assertEquals(6, pos.getErrorIndex()); } public void testForgottenSuffix() { ParsePosition pos = new ParsePosition(0); assertNull(new Vector3DFormat().parse("{1; 1; 1 ", pos)); assertEquals(8, pos.getErrorIndex()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/FrenchVector3DFormatTest.java100644 1750 1750 2141 11532241242 31660 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.util.Locale; public class FrenchVector3DFormatTest extends Vector3DFormatAbstractTest { @Override protected char getDecimalCharacter() { return ','; } @Override protected Locale getLocale() { return Locale.FRENCH; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/geometry/Vector3DFormatTest.java100644 1750 1750 2127 11532241242 30536 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.util.Locale; public class Vector3DFormatTest extends Vector3DFormatAbstractTest { @Override protected char getDecimalCharacter() { return '.'; } @Override protected Locale getLocale() { return Locale.US; } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/univariate/BracketFinderTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/univariate/BracketFinderTest100644 1750 1750 5175 11532241241 32566 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.univariate; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.optimization.GoalType; import org.junit.Assert; import org.junit.Test; public class BracketFinderTest { @Test public void testCubicMin() throws MathException { final BracketFinder bFind = new BracketFinder(); final UnivariateRealFunction func = new UnivariateRealFunction() { public double value(double x) { if (x < -2) { return value(-2); } else { return (x - 1) * (x + 2) * (x + 3); } } }; bFind.search(func, GoalType.MINIMIZE, -2 , -1); final double tol = 1e-15; // Comparing with results computed in Python. Assert.assertEquals(-2, bFind.getLo(), tol); Assert.assertEquals(-1, bFind.getMid(), tol); Assert.assertEquals(0.61803399999999997, bFind.getHi(), tol); } @Test public void testCubicMax() throws MathException { final BracketFinder bFind = new BracketFinder(); final UnivariateRealFunction func = new UnivariateRealFunction() { public double value(double x) { if (x < -2) { return value(-2); } else { return -(x - 1) * (x + 2) * (x + 3); } } }; bFind.search(func, GoalType.MAXIMIZE, -2 , -1); final double tol = 1e-15; Assert.assertEquals(-2, bFind.getLo(), tol); Assert.assertEquals(-1, bFind.getMid(), tol); Assert.assertEquals(0.61803399999999997, bFind.getHi(), tol); } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/univariate/BrentOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/univariate/BrentOptimizerTes100644 1750 1750 14520 11532241241 32666 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.univariate; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.UnivariateRealOptimizer; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.util.FastMath; import org.junit.Test; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (Sat, 05 Sep 2009) $ */ public final class BrentOptimizerTest { @Test public void testSinMin() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealOptimizer minimizer = new BrentOptimizer(); minimizer.setMaxEvaluations(200); assertEquals(200, minimizer.getMaxEvaluations()); try { minimizer.getResult(); fail("an exception should have been thrown"); } catch (NoDataException ise) { // expected } assertEquals(3 * FastMath.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 4, 5), 10 * minimizer.getRelativeAccuracy()); assertTrue(minimizer.getIterationCount() <= 50); assertEquals(3 * FastMath.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 1, 5), 10 * minimizer.getRelativeAccuracy()); assertTrue(minimizer.getIterationCount() <= 50); assertTrue(minimizer.getEvaluations() <= 100); assertTrue(minimizer.getEvaluations() >= 15); minimizer.setMaxEvaluations(10); try { minimizer.optimize(f, GoalType.MINIMIZE, 4, 5); fail("an exception should have been thrown"); } catch (FunctionEvaluationException mue) { // expected } catch (Exception e) { fail("wrong exception caught"); } } @Test public void testQuinticMin() throws MathException { // The function has local minima at -0.27195613 and 0.82221643. UnivariateRealFunction f = new QuinticFunction(); UnivariateRealOptimizer minimizer = new BrentOptimizer(); assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -0.3, -0.2), 1.0e-8); assertEquals( 0.82221643, minimizer.optimize(f, GoalType.MINIMIZE, 0.3, 0.9), 1.0e-8); assertTrue(minimizer.getIterationCount() <= 50); // search in a large interval assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -1.0, 0.2), 1.0e-8); assertTrue(minimizer.getIterationCount() <= 50); } @Test public void testQuinticMinStatistics() throws MathException { // The function has local minima at -0.27195613 and 0.82221643. UnivariateRealFunction f = new QuinticFunction(); UnivariateRealOptimizer minimizer = new BrentOptimizer(); minimizer.setRelativeAccuracy(1e-10); minimizer.setAbsoluteAccuracy(1e-11); final DescriptiveStatistics[] stat = new DescriptiveStatistics[3]; for (int i = 0; i < stat.length; i++) { stat[i] = new DescriptiveStatistics(); } final double min = -0.75; final double max = 0.25; final int nSamples = 200; final double delta = (max - min) / nSamples; for (int i = 0; i < nSamples; i++) { final double start = min + i * delta; stat[0].addValue(minimizer.optimize(f, GoalType.MINIMIZE, min, max, start)); stat[1].addValue(minimizer.getIterationCount()); stat[2].addValue(minimizer.getEvaluations()); } final double meanOptValue = stat[0].getMean(); final double medianIter = stat[1].getPercentile(50); final double medianEval = stat[2].getPercentile(50); assertTrue(meanOptValue > -0.27195612812 && meanOptValue < -0.27195612811); assertEquals(medianIter, 17, FastMath.ulp(1d)); assertEquals(medianEval, 18, FastMath.ulp(1d)); } @Test public void testQuinticMax() throws MathException { // The quintic function has zeros at 0, +-0.5 and +-1. // The function has a local maximum at 0.27195613. UnivariateRealFunction f = new QuinticFunction(); UnivariateRealOptimizer minimizer = new BrentOptimizer(); assertEquals(0.27195613, minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3), 1.0e-8); minimizer.setMaximalIterationCount(5); try { minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3); fail("an exception should have been thrown"); } catch (MaxIterationsExceededException miee) { // expected } } @Test public void testMinEndpoints() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealOptimizer solver = new BrentOptimizer(); solver.setRelativeAccuracy(1e-8); // endpoint is minimum double result = solver.optimize(f, GoalType.MINIMIZE, 3 * FastMath.PI / 2, 5); assertEquals(3 * FastMath.PI / 2, result, 10 * solver.getRelativeAccuracy()); result = solver.optimize(f, GoalType.MINIMIZE, 4, 3 * FastMath.PI / 2); assertEquals(3 * FastMath.PI / 2, result, 10 * solver.getRelativeAccuracy()); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.java100644 1750 1750 13573 11532241241 32563 0ustarlucluc 0 0 // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; public class CurveFitterTest { @Test public void testMath303() throws OptimizationException, FunctionEvaluationException { LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); CurveFitter fitter = new CurveFitter(optimizer); fitter.addObservedPoint(2.805d, 0.6934785852953367d); fitter.addObservedPoint(2.74333333333333d, 0.6306772025518496d); fitter.addObservedPoint(1.655d, 0.9474675497289684); fitter.addObservedPoint(1.725d, 0.9013594835804194d); ParametricRealFunction sif = new SimpleInverseFunction(); double[] initialguess1 = new double[1]; initialguess1[0] = 1.0d; Assert.assertEquals(1, fitter.fit(sif, initialguess1).length); double[] initialguess2 = new double[2]; initialguess2[0] = 1.0d; initialguess2[1] = .5d; Assert.assertEquals(2, fitter.fit(sif, initialguess2).length); } @Test public void testMath304() throws OptimizationException, FunctionEvaluationException { LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); CurveFitter fitter = new CurveFitter(optimizer); fitter.addObservedPoint(2.805d, 0.6934785852953367d); fitter.addObservedPoint(2.74333333333333d, 0.6306772025518496d); fitter.addObservedPoint(1.655d, 0.9474675497289684); fitter.addObservedPoint(1.725d, 0.9013594835804194d); ParametricRealFunction sif = new SimpleInverseFunction(); double[] initialguess1 = new double[1]; initialguess1[0] = 1.0d; Assert.assertEquals(1.6357215104109237, fitter.fit(sif, initialguess1)[0], 1.0e-14); double[] initialguess2 = new double[1]; initialguess2[0] = 10.0d; Assert.assertEquals(1.6357215104109237, fitter.fit(sif, initialguess1)[0], 1.0e-14); } @Test public void testMath372() throws OptimizationException, FunctionEvaluationException { LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); CurveFitter curveFitter = new CurveFitter(optimizer); curveFitter.addObservedPoint( 15, 4443); curveFitter.addObservedPoint( 31, 8493); curveFitter.addObservedPoint( 62, 17586); curveFitter.addObservedPoint(125, 30582); curveFitter.addObservedPoint(250, 45087); curveFitter.addObservedPoint(500, 50683); ParametricRealFunction f = new ParametricRealFunction() { public double value(double x, double[] parameters) { double a = parameters[0]; double b = parameters[1]; double c = parameters[2]; double d = parameters[3]; return d + ((a - d) / (1 + FastMath.pow(x / c, b))); } public double[] gradient(double x, double[] parameters) { double a = parameters[0]; double b = parameters[1]; double c = parameters[2]; double d = parameters[3]; double[] gradients = new double[4]; double den = 1 + FastMath.pow(x / c, b); // derivative with respect to a gradients[0] = 1 / den; // derivative with respect to b // in the reported (invalid) issue, there was a sign error here gradients[1] = -((a - d) * FastMath.pow(x / c, b) * FastMath.log(x / c)) / (den * den); // derivative with respect to c gradients[2] = (b * FastMath.pow(x / c, b - 1) * (x / (c * c)) * (a - d)) / (den * den); // derivative with respect to d gradients[3] = 1 - (1 / den); return gradients; } }; double[] initialGuess = new double[] { 1500, 0.95, 65, 35000 }; double[] estimatedParameters = curveFitter.fit(f, initialGuess); Assert.assertEquals( 2411.00, estimatedParameters[0], 500.00); Assert.assertEquals( 1.62, estimatedParameters[1], 0.04); Assert.assertEquals( 111.22, estimatedParameters[2], 0.30); Assert.assertEquals(55347.47, estimatedParameters[3], 300.00); Assert.assertTrue(optimizer.getRMS() < 600.0); } private static class SimpleInverseFunction implements ParametricRealFunction { public double value(double x, double[] parameters) { return parameters[0] / x + (parameters.length < 2 ? 0 : parameters[1]); } public double[] gradient(double x, double[] doubles) { double[] gradientVector = new double[doubles.length]; gradientVector[0] = 1 / x; if (doubles.length >= 2) { gradientVector[1] = 1; } return gradientVector; } } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/GaussianFitterTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/GaussianFitterTest.j100644 1750 1750 26526 11532241241 32563 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import static org.junit.Assert.assertEquals; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.general. LevenbergMarquardtOptimizer; import org.junit.Test; /** * Tests {@link GaussianFitter}. * * @since 2.2 * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class GaussianFitterTest { /** Good data. */ protected static final double[][] DATASET1 = new double[][] { {4.0254623, 531026.0}, {4.02804905, 664002.0}, {4.02934242, 787079.0}, {4.03128248, 984167.0}, {4.03386923, 1294546.0}, {4.03580929, 1560230.0}, {4.03839603, 1887233.0}, {4.0396894, 2113240.0}, {4.04162946, 2375211.0}, {4.04421621, 2687152.0}, {4.04550958, 2862644.0}, {4.04744964, 3078898.0}, {4.05003639, 3327238.0}, {4.05132976, 3461228.0}, {4.05326982, 3580526.0}, {4.05585657, 3576946.0}, {4.05779662, 3439750.0}, {4.06038337, 3220296.0}, {4.06167674, 3070073.0}, {4.0636168, 2877648.0}, {4.06620355, 2595848.0}, {4.06749692, 2390157.0}, {4.06943698, 2175960.0}, {4.07202373, 1895104.0}, {4.0733171, 1687576.0}, {4.07525716, 1447024.0}, {4.0778439, 1130879.0}, {4.07978396, 904900.0}, {4.08237071, 717104.0}, {4.08366408, 620014.0} }; /** Poor data: right of peak not symmetric with left of peak. */ protected static final double[][] DATASET2 = new double[][] { {-20.15, 1523.0}, {-19.65, 1566.0}, {-19.15, 1592.0}, {-18.65, 1927.0}, {-18.15, 3089.0}, {-17.65, 6068.0}, {-17.15, 14239.0}, {-16.65, 34124.0}, {-16.15, 64097.0}, {-15.65, 110352.0}, {-15.15, 164742.0}, {-14.65, 209499.0}, {-14.15, 267274.0}, {-13.65, 283290.0}, {-13.15, 275363.0}, {-12.65, 258014.0}, {-12.15, 225000.0}, {-11.65, 200000.0}, {-11.15, 190000.0}, {-10.65, 185000.0}, {-10.15, 180000.0}, { -9.65, 179000.0}, { -9.15, 178000.0}, { -8.65, 177000.0}, { -8.15, 176000.0}, { -7.65, 175000.0}, { -7.15, 174000.0}, { -6.65, 173000.0}, { -6.15, 172000.0}, { -5.65, 171000.0}, { -5.15, 170000.0} }; /** Poor data: long tails. */ protected static final double[][] DATASET3 = new double[][] { {-90.15, 1513.0}, {-80.15, 1514.0}, {-70.15, 1513.0}, {-60.15, 1514.0}, {-50.15, 1513.0}, {-40.15, 1514.0}, {-30.15, 1513.0}, {-20.15, 1523.0}, {-19.65, 1566.0}, {-19.15, 1592.0}, {-18.65, 1927.0}, {-18.15, 3089.0}, {-17.65, 6068.0}, {-17.15, 14239.0}, {-16.65, 34124.0}, {-16.15, 64097.0}, {-15.65, 110352.0}, {-15.15, 164742.0}, {-14.65, 209499.0}, {-14.15, 267274.0}, {-13.65, 283290.0}, {-13.15, 275363.0}, {-12.65, 258014.0}, {-12.15, 214073.0}, {-11.65, 182244.0}, {-11.15, 136419.0}, {-10.65, 97823.0}, {-10.15, 58930.0}, { -9.65, 35404.0}, { -9.15, 16120.0}, { -8.65, 9823.0}, { -8.15, 5064.0}, { -7.65, 2575.0}, { -7.15, 1642.0}, { -6.65, 1101.0}, { -6.15, 812.0}, { -5.65, 690.0}, { -5.15, 565.0}, { 5.15, 564.0}, { 15.15, 565.0}, { 25.15, 564.0}, { 35.15, 565.0}, { 45.15, 564.0}, { 55.15, 565.0}, { 65.15, 564.0}, { 75.15, 565.0} }; /** Poor data: right of peak is missing. */ protected static final double[][] DATASET4 = new double[][] { {-20.15, 1523.0}, {-19.65, 1566.0}, {-19.15, 1592.0}, {-18.65, 1927.0}, {-18.15, 3089.0}, {-17.65, 6068.0}, {-17.15, 14239.0}, {-16.65, 34124.0}, {-16.15, 64097.0}, {-15.65, 110352.0}, {-15.15, 164742.0}, {-14.65, 209499.0}, {-14.15, 267274.0}, {-13.65, 283290.0} }; /** Good data, but few points. */ protected static final double[][] DATASET5 = new double[][] { {4.0254623, 531026.0}, {4.03128248, 984167.0}, {4.03839603, 1887233.0}, {4.04421621, 2687152.0}, {4.05132976, 3461228.0}, {4.05326982, 3580526.0}, {4.05779662, 3439750.0}, {4.0636168, 2877648.0}, {4.06943698, 2175960.0}, {4.07525716, 1447024.0}, {4.08237071, 717104.0}, {4.08366408, 620014.0} }; /** * Basic. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit01() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(DATASET1, fitter); GaussianFunction fitFunction = fitter.fit(); assertEquals(99200.86969833552, fitFunction.getA(), 1e-4); assertEquals(3410515.285208688, fitFunction.getB(), 1e-4); assertEquals(4.054928275302832, fitFunction.getC(), 1e-4); assertEquals(0.014609868872574, fitFunction.getD(), 1e-4); } /** * Zero points is not enough observed points. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test(expected=IllegalArgumentException.class) public void testFit02() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); fitter.fit(); } /** * Two points is not enough observed points. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test(expected=IllegalArgumentException.class) public void testFit03() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(new double[][] { {4.0254623, 531026.0}, {4.02804905, 664002.0}}, fitter); fitter.fit(); } /** * Poor data: right of peak not symmetric with left of peak. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit04() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(DATASET2, fitter); GaussianFunction fitFunction = fitter.fit(); assertEquals(-256534.689445631, fitFunction.getA(), 1e-4); assertEquals(481328.2181530679, fitFunction.getB(), 1e-4); assertEquals(-10.5217226891099, fitFunction.getC(), 1e-4); assertEquals(-7.64248239366800, fitFunction.getD(), 1e-4); } /** * Poor data: long tails. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit05() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(DATASET3, fitter); GaussianFunction fitFunction = fitter.fit(); assertEquals(491.6310079258938, fitFunction.getA(), 1e-4); assertEquals(283508.6800413632, fitFunction.getB(), 1e-4); assertEquals(-13.2966857238057, fitFunction.getC(), 1e-4); assertEquals(1.725590356962981, fitFunction.getD(), 1e-4); } /** * Poor data: right of peak is missing. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit06() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(DATASET4, fitter); GaussianFunction fitFunction = fitter.fit(); assertEquals(530.3649792355617, fitFunction.getA(), 1e-4); assertEquals(284517.0835567514, fitFunction.getB(), 1e-4); assertEquals(-13.5355534565105, fitFunction.getC(), 1e-4); assertEquals(1.512353018625465, fitFunction.getD(), 1e-4); } /** * Basic with smaller dataset. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit07() throws OptimizationException, FunctionEvaluationException { GaussianFitter fitter = new GaussianFitter(new LevenbergMarquardtOptimizer()); addDatasetToGaussianFitter(DATASET5, fitter); GaussianFunction fitFunction = fitter.fit(); assertEquals(176748.1400947575, fitFunction.getA(), 1e-4); assertEquals(3361537.018813906, fitFunction.getB(), 1e-4); assertEquals(4.054949992747176, fitFunction.getC(), 1e-4); assertEquals(0.014192380137002, fitFunction.getD(), 1e-4); } /** * Adds the specified points to specified GaussianFitter * instance. * * @param points data points where first dimension is a point index and * second dimension is an array of length two representing the point * with the first value corresponding to X and the second value * corresponding to Y * @param fitter fitter to which the points in points should be * added as observed points */ protected static void addDatasetToGaussianFitter(double[][] points, GaussianFitter fitter) { for (int i = 0; i < points.length; i++) { fitter.addObservedPoint(points[i][0], points[i][1]); } } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/PolynomialFitterTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/PolynomialFitterTest100644 1750 1750 12136 11532241241 32674 0ustarlucluc 0 0 // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package org.apache.commons.math.optimization.fitting; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Random; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class PolynomialFitterTest { @Test public void testNoError() throws OptimizationException { Random randomizer = new Random(64925784252l); for (int degree = 1; degree < 10; ++degree) { PolynomialFunction p = buildRandomPolynomial(degree, randomizer); PolynomialFitter fitter = new PolynomialFitter(degree, new LevenbergMarquardtOptimizer()); for (int i = 0; i <= degree; ++i) { fitter.addObservedPoint(1.0, i, p.value(i)); } PolynomialFunction fitted = fitter.fit(); for (double x = -1.0; x < 1.0; x += 0.01) { double error = FastMath.abs(p.value(x) - fitted.value(x)) / (1.0 + FastMath.abs(p.value(x))); assertEquals(0.0, error, 1.0e-6); } } } @Test public void testSmallError() throws OptimizationException { Random randomizer = new Random(53882150042l); double maxError = 0; for (int degree = 0; degree < 10; ++degree) { PolynomialFunction p = buildRandomPolynomial(degree, randomizer); PolynomialFitter fitter = new PolynomialFitter(degree, new LevenbergMarquardtOptimizer()); for (double x = -1.0; x < 1.0; x += 0.01) { fitter.addObservedPoint(1.0, x, p.value(x) + 0.1 * randomizer.nextGaussian()); } PolynomialFunction fitted = fitter.fit(); for (double x = -1.0; x < 1.0; x += 0.01) { double error = FastMath.abs(p.value(x) - fitted.value(x)) / (1.0 + FastMath.abs(p.value(x))); maxError = FastMath.max(maxError, error); assertTrue(FastMath.abs(error) < 0.1); } } assertTrue(maxError > 0.01); } @Test public void testRedundantSolvable() { // Levenberg-Marquardt should handle redundant information gracefully checkUnsolvableProblem(new LevenbergMarquardtOptimizer(), true); } @Test public void testRedundantUnsolvable() { // Gauss-Newton should not be able to solve redundant information DifferentiableMultivariateVectorialOptimizer optimizer = new GaussNewtonOptimizer(true); checkUnsolvableProblem(optimizer, false); } private void checkUnsolvableProblem(DifferentiableMultivariateVectorialOptimizer optimizer, boolean solvable) { Random randomizer = new Random(1248788532l); for (int degree = 0; degree < 10; ++degree) { PolynomialFunction p = buildRandomPolynomial(degree, randomizer); PolynomialFitter fitter = new PolynomialFitter(degree, optimizer); // reusing the same point over and over again does not bring // information, the problem cannot be solved in this case for // degrees greater than 1 (but one point is sufficient for // degree 0) for (double x = -1.0; x < 1.0; x += 0.01) { fitter.addObservedPoint(1.0, 0.0, p.value(0.0)); } try { fitter.fit(); assertTrue(solvable || (degree == 0)); } catch(OptimizationException e) { assertTrue((! solvable) && (degree > 0)); } } } private PolynomialFunction buildRandomPolynomial(int degree, Random randomizer) { final double[] coefficients = new double[degree + 1]; for (int i = 0; i <= degree; ++i) { coefficients[i] = randomizer.nextGaussian(); } return new PolynomialFunction(coefficients); } } ././@LongLink100644 0 0 164 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunctionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFu100644 1750 1750 14132 11532241241 32606 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.fitting.CurveFitter; import org.apache.commons.math.optimization.general. LevenbergMarquardtOptimizer; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests {@link ParametricGaussianFunction}. * * @since 2.2 * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class ParametricGaussianFunctionTest { /** Dataset 1 used by some test cases. */ protected static final double[][] DATASET1 = new double[][] { {4.0254623, 531026.0}, {4.02804905, 664002.0}, {4.02934242, 787079.0}, {4.03128248, 984167.0}, {4.03386923, 1294546.0}, {4.03580929, 1560230.0}, {4.03839603, 1887233.0}, {4.0396894, 2113240.0}, {4.04162946, 2375211.0}, {4.04421621, 2687152.0}, {4.04550958, 2862644.0}, {4.04744964, 3078898.0}, {4.05003639, 3327238.0}, {4.05132976, 3461228.0}, {4.05326982, 3580526.0}, {4.05585657, 3576946.0}, {4.05779662, 3439750.0}, {4.06038337, 3220296.0}, {4.06167674, 3070073.0}, {4.0636168, 2877648.0}, {4.06620355, 2595848.0}, {4.06749692, 2390157.0}, {4.06943698, 2175960.0}, {4.07202373, 1895104.0}, {4.0733171, 1687576.0}, {4.07525716, 1447024.0}, {4.0778439, 1130879.0}, {4.07978396, 904900.0}, {4.08237071, 717104.0}, {4.08366408, 620014.0} }; /** * Using not-so-good initial parameters. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit01() throws OptimizationException, FunctionEvaluationException { CurveFitter fitter = new CurveFitter(new LevenbergMarquardtOptimizer()); addDatasetToCurveFitter(DATASET1, fitter); double[] parameters = fitter.fit(new ParametricGaussianFunction(), new double[] {8.64753e3, 3.483323e6, 4.06322, 1.946857e-2}); assertEquals(99200.94715858076, parameters[0], 1e-4); assertEquals(3410515.221897707, parameters[1], 1e-4); assertEquals(4.054928275257894, parameters[2], 1e-4); assertEquals(0.014609868499860, parameters[3], 1e-4); } /** * Using eye-balled guesses for initial parameters. * * @throws OptimizationException in the event of a test case error * @throws FunctionEvaluationException in the event of a test case error */ @Test public void testFit02() throws OptimizationException, FunctionEvaluationException { CurveFitter fitter = new CurveFitter(new LevenbergMarquardtOptimizer()); addDatasetToCurveFitter(DATASET1, fitter); double[] parameters = fitter.fit(new ParametricGaussianFunction(), new double[] {500000.0, 3500000.0, 4.055, 0.025479654}); assertEquals(99200.81836264656, parameters[0], 1e-4); assertEquals(3410515.327151986, parameters[1], 1e-4); assertEquals(4.054928275377392, parameters[2], 1e-4); assertEquals(0.014609869119806, parameters[3], 1e-4); } /** * The parameters array is null. * * @throws FunctionEvaluationException in the event of a test case error */ @Test(expected=IllegalArgumentException.class) public void testValue01() throws FunctionEvaluationException { ParametricGaussianFunction f = new ParametricGaussianFunction(); f.value(0.0, null); } /** * The parameters array length is not 4. * * @throws FunctionEvaluationException in the event of a test case error */ @Test(expected=IllegalArgumentException.class) public void testValue02() throws FunctionEvaluationException { ParametricGaussianFunction f = new ParametricGaussianFunction(); f.value(0.0, new double[] {0.0, 1.0}); } /** * The parameters d is 0. * * @throws FunctionEvaluationException in the event of a test case error */ @Test(expected=ZeroException.class) public void testValue03() throws FunctionEvaluationException { ParametricGaussianFunction f = new ParametricGaussianFunction(); f.value(0.0, new double[] {0.0, 1.0, 1.0, 0.0}); } /** * Adds the specified points to specified CurveFitter instance. * * @param points data points where first dimension is a point index and * second dimension is an array of length two representing the point * with the first value corresponding to X and the second value * corresponding to Y * @param fitter fitter to which the points in points should be * added as observed points */ protected static void addDatasetToCurveFitter(double[][] points, CurveFitter fitter) { for (int i = 0; i < points.length; i++) { fitter.addObservedPoint(points[i][0], points[i][1]); } } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/HarmonicFitterTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/fitting/HarmonicFitterTest.j100644 1750 1750 11777 11532241241 32553 0ustarlucluc 0 0 // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package org.apache.commons.math.optimization.fitting; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Random; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; import org.junit.Test; public class HarmonicFitterTest { @Test public void testNoError() throws OptimizationException { HarmonicFunction f = new HarmonicFunction(0.2, 3.4, 4.1); HarmonicFitter fitter = new HarmonicFitter(new LevenbergMarquardtOptimizer()); for (double x = 0.0; x < 1.3; x += 0.01) { fitter.addObservedPoint(1.0, x, f.value(x)); } HarmonicFunction fitted = fitter.fit(); assertEquals(f.getAmplitude(), fitted.getAmplitude(), 1.0e-13); assertEquals(f.getPulsation(), fitted.getPulsation(), 1.0e-13); assertEquals(f.getPhase(), MathUtils.normalizeAngle(fitted.getPhase(), f.getPhase()), 1.0e-13); for (double x = -1.0; x < 1.0; x += 0.01) { assertTrue(FastMath.abs(f.value(x) - fitted.value(x)) < 1.0e-13); } } @Test public void test1PercentError() throws OptimizationException { Random randomizer = new Random(64925784252l); HarmonicFunction f = new HarmonicFunction(0.2, 3.4, 4.1); HarmonicFitter fitter = new HarmonicFitter(new LevenbergMarquardtOptimizer()); for (double x = 0.0; x < 10.0; x += 0.1) { fitter.addObservedPoint(1.0, x, f.value(x) + 0.01 * randomizer.nextGaussian()); } HarmonicFunction fitted = fitter.fit(); assertEquals(f.getAmplitude(), fitted.getAmplitude(), 7.6e-4); assertEquals(f.getPulsation(), fitted.getPulsation(), 2.7e-3); assertEquals(f.getPhase(), MathUtils.normalizeAngle(fitted.getPhase(), f.getPhase()), 1.3e-2); } @Test public void testInitialGuess() throws OptimizationException { Random randomizer = new Random(45314242l); HarmonicFunction f = new HarmonicFunction(0.2, 3.4, 4.1); HarmonicFitter fitter = new HarmonicFitter(new LevenbergMarquardtOptimizer(), new double[] { 0.15, 3.6, 4.5 }); for (double x = 0.0; x < 10.0; x += 0.1) { fitter.addObservedPoint(1.0, x, f.value(x) + 0.01 * randomizer.nextGaussian()); } HarmonicFunction fitted = fitter.fit(); assertEquals(f.getAmplitude(), fitted.getAmplitude(), 1.2e-3); assertEquals(f.getPulsation(), fitted.getPulsation(), 3.3e-3); assertEquals(f.getPhase(), MathUtils.normalizeAngle(fitted.getPhase(), f.getPhase()), 1.7e-2); } @Test public void testUnsorted() throws OptimizationException { Random randomizer = new Random(64925784252l); HarmonicFunction f = new HarmonicFunction(0.2, 3.4, 4.1); HarmonicFitter fitter = new HarmonicFitter(new LevenbergMarquardtOptimizer()); // build a regularly spaced array of measurements int size = 100; double[] xTab = new double[size]; double[] yTab = new double[size]; for (int i = 0; i < size; ++i) { xTab[i] = 0.1 * i; yTab[i] = f.value(xTab[i]) + 0.01 * randomizer.nextGaussian(); } // shake it for (int i = 0; i < size; ++i) { int i1 = randomizer.nextInt(size); int i2 = randomizer.nextInt(size); double xTmp = xTab[i1]; double yTmp = yTab[i1]; xTab[i1] = xTab[i2]; yTab[i1] = yTab[i2]; xTab[i2] = xTmp; yTab[i2] = yTmp; } // pass it to the fitter for (int i = 0; i < size; ++i) { fitter.addObservedPoint(1.0, xTab[i], yTab[i]); } HarmonicFunction fitted = fitter.fit(); assertEquals(f.getAmplitude(), fitted.getAmplitude(), 7.6e-4); assertEquals(f.getPulsation(), fitted.getPulsation(), 3.5e-3); assertEquals(f.getPhase(), MathUtils.normalizeAngle(fitted.getPhase(), f.getPhase()), 1.5e-2); } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOp100644 1750 1750 5721 11532241241 32653 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.direct.NelderMead; import org.apache.commons.math.random.GaussianRandomGenerator; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.random.RandomVectorGenerator; import org.apache.commons.math.random.UncorrelatedRandomVectorGenerator; import org.junit.Test; public class MultiStartMultivariateRealOptimizerTest { @Test public void testRosenbrock() throws Exception { Rosenbrock rosenbrock = new Rosenbrock(); NelderMead underlying = new NelderMead(); underlying.setStartConfiguration(new double[][] { { -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 } }); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(16069223052l); RandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(2, new GaussianRandomGenerator(g)); MultiStartMultivariateRealOptimizer optimizer = new MultiStartMultivariateRealOptimizer(underlying, 10, generator); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3)); optimizer.setMaxIterations(100); RealPointValuePair optimum = optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 }); assertEquals(rosenbrock.getCount(), optimizer.getEvaluations()); assertTrue(optimizer.getEvaluations() > 20); assertTrue(optimizer.getEvaluations() < 250); assertTrue(optimum.getValue() < 8.0e-4); } private static class Rosenbrock implements MultivariateRealFunction { private int count; public Rosenbrock() { count = 0; } public double value(double[] x) throws FunctionEvaluationException { ++count; double a = x[1] - x[0] * x[0]; double b = 1.0 - x[0]; return 100 * a * a + b * b; } public int getCount() { return count; } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/linear/SimplexSolverTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/linear/SimplexSolverTest.jav100644 1750 1750 72120 11532241241 32573 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import org.junit.Assert; import java.util.ArrayList; import java.util.Collection; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.junit.Test; public class SimplexSolverTest { @Test public void testMath272() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 2, 1 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 1, 0 }, Relationship.GEQ, 1)); constraints.add(new LinearConstraint(new double[] { 1, 0, 1 }, Relationship.GEQ, 1)); constraints.add(new LinearConstraint(new double[] { 0, 1, 0 }, Relationship.GEQ, 1)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MINIMIZE, true); Assert.assertEquals(0.0, solution.getPoint()[0], .0000001); Assert.assertEquals(1.0, solution.getPoint()[1], .0000001); Assert.assertEquals(1.0, solution.getPoint()[2], .0000001); Assert.assertEquals(3.0, solution.getValue(), .0000001); } @Test public void testMath286() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.6, 0.4 }, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 23.0)); constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 23.0)); constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0, 0, 0 }, Relationship.GEQ, 10.0)); constraints.add(new LinearConstraint(new double[] { 0, 0, 1, 0, 0, 0 }, Relationship.GEQ, 8.0)); constraints.add(new LinearConstraint(new double[] { 0, 0, 0, 0, 1, 0 }, Relationship.GEQ, 5.0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(25.8, solution.getValue(), .0000001); Assert.assertEquals(23.0, solution.getPoint()[0] + solution.getPoint()[2] + solution.getPoint()[4], 0.0000001); Assert.assertEquals(23.0, solution.getPoint()[1] + solution.getPoint()[3] + solution.getPoint()[5], 0.0000001); Assert.assertTrue(solution.getPoint()[0] >= 10.0 - 0.0000001); Assert.assertTrue(solution.getPoint()[2] >= 8.0 - 0.0000001); Assert.assertTrue(solution.getPoint()[4] >= 5.0 - 0.0000001); } @Test public void testDegeneracy() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.7 }, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 18.0)); constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.GEQ, 10.0)); constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 8.0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(13.6, solution.getValue(), .0000001); } @Test public void testMath288() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 7, 3, 0, 0 }, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 3, 0, -5, 0 }, Relationship.LEQ, 0.0)); constraints.add(new LinearConstraint(new double[] { 2, 0, 0, -5 }, Relationship.LEQ, 0.0)); constraints.add(new LinearConstraint(new double[] { 0, 3, 0, -5 }, Relationship.LEQ, 0.0)); constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0 }, Relationship.LEQ, 1.0)); constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 0 }, Relationship.LEQ, 1.0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(10.0, solution.getValue(), .0000001); } @Test public void testMath290GEQ() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 5 }, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 2, 0 }, Relationship.GEQ, -1.0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MINIMIZE, true); Assert.assertEquals(0, solution.getValue(), .0000001); Assert.assertEquals(0, solution.getPoint()[0], .0000001); Assert.assertEquals(0, solution.getPoint()[1], .0000001); } @Test(expected=NoFeasibleSolutionException.class) public void testMath290LEQ() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 5 }, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 2, 0 }, Relationship.LEQ, -1.0)); SimplexSolver solver = new SimplexSolver(); solver.optimize(f, constraints, GoalType.MINIMIZE, true); } @Test public void testMath293() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 ); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0)); constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0)); constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, 10.0)); constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, 10.0)); constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, 10.0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution1 = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(15.7143, solution1.getPoint()[0], .0001); Assert.assertEquals(0.0, solution1.getPoint()[1], .0001); Assert.assertEquals(14.2857, solution1.getPoint()[2], .0001); Assert.assertEquals(0.0, solution1.getPoint()[3], .0001); Assert.assertEquals(0.0, solution1.getPoint()[4], .0001); Assert.assertEquals(30.0, solution1.getPoint()[5], .0001); Assert.assertEquals(40.57143, solution1.getValue(), .0001); double valA = 0.8 * solution1.getPoint()[0] + 0.2 * solution1.getPoint()[1]; double valB = 0.7 * solution1.getPoint()[2] + 0.3 * solution1.getPoint()[3]; double valC = 0.4 * solution1.getPoint()[4] + 0.6 * solution1.getPoint()[5]; f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 ); constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0)); constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0)); constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, valA)); constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, valB)); constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, valC)); RealPointValuePair solution2 = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(40.57143, solution2.getValue(), .0001); } @Test public void testSimplexSolver() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 7); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2)); constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3)); constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ, 4)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, false); Assert.assertEquals(2.0, solution.getPoint()[0], 0.0); Assert.assertEquals(2.0, solution.getPoint()[1], 0.0); Assert.assertEquals(57.0, solution.getValue(), 0.0); } @Test public void testSingleVariableAndConstraint() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 3 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.LEQ, 10)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, false); Assert.assertEquals(10.0, solution.getPoint()[0], 0.0); Assert.assertEquals(30.0, solution.getValue(), 0.0); } /** * With no artificial variables needed (no equals and no greater than * constraints) we can go straight to Phase 2. */ @Test public void testModelWithNoArtificialVars() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2)); constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3)); constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 4)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, false); Assert.assertEquals(2.0, solution.getPoint()[0], 0.0); Assert.assertEquals(2.0, solution.getPoint()[1], 0.0); Assert.assertEquals(50.0, solution.getValue(), 0.0); } @Test public void testMinimization() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, -5); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 6)); constraints.add(new LinearConstraint(new double[] { 3, 2 }, Relationship.LEQ, 12)); constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MINIMIZE, false); Assert.assertEquals(4.0, solution.getPoint()[0], 0.0); Assert.assertEquals(0.0, solution.getPoint()[1], 0.0); Assert.assertEquals(-13.0, solution.getValue(), 0.0); } @Test public void testSolutionWithNegativeDecisionVariable() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.GEQ, 6)); constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 14)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, false); Assert.assertEquals(-2.0, solution.getPoint()[0], 0.0); Assert.assertEquals(8.0, solution.getPoint()[1], 0.0); Assert.assertEquals(12.0, solution.getValue(), 0.0); } @Test(expected = NoFeasibleSolutionException.class) public void testInfeasibleSolution() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.LEQ, 1)); constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.GEQ, 3)); SimplexSolver solver = new SimplexSolver(); solver.optimize(f, constraints, GoalType.MAXIMIZE, false); } @Test(expected = UnboundedSolutionException.class) public void testUnboundedSolution() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.EQ, 2)); SimplexSolver solver = new SimplexSolver(); solver.optimize(f, constraints, GoalType.MAXIMIZE, false); } @Test public void testRestrictVariablesToNonNegative() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 409, 523, 70, 204, 339 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 43, 56, 345, 56, 5 }, Relationship.LEQ, 4567456)); constraints.add(new LinearConstraint(new double[] { 12, 45, 7, 56, 23 }, Relationship.LEQ, 56454)); constraints.add(new LinearConstraint(new double[] { 8, 768, 0, 34, 7456 }, Relationship.LEQ, 1923421)); constraints.add(new LinearConstraint(new double[] { 12342, 2342, 34, 678, 2342 }, Relationship.GEQ, 4356)); constraints.add(new LinearConstraint(new double[] { 45, 678, 76, 52, 23 }, Relationship.EQ, 456356)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(2902.92783505155, solution.getPoint()[0], .0000001); Assert.assertEquals(480.419243986254, solution.getPoint()[1], .0000001); Assert.assertEquals(0.0, solution.getPoint()[2], .0000001); Assert.assertEquals(0.0, solution.getPoint()[3], .0000001); Assert.assertEquals(0.0, solution.getPoint()[4], .0000001); Assert.assertEquals(1438556.7491409, solution.getValue(), .0000001); } @Test public void testEpsilon() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 10, 5, 1 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 9, 8, 0 }, Relationship.EQ, 17)); constraints.add(new LinearConstraint(new double[] { 0, 7, 8 }, Relationship.LEQ, 7)); constraints.add(new LinearConstraint(new double[] { 10, 0, 2 }, Relationship.LEQ, 10)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, false); Assert.assertEquals(1.0, solution.getPoint()[0], 0.0); Assert.assertEquals(1.0, solution.getPoint()[1], 0.0); Assert.assertEquals(0.0, solution.getPoint()[2], 0.0); Assert.assertEquals(15.0, solution.getValue(), 0.0); } @Test public void testTrivialModel() throws OptimizationException { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 1 }, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ, 0)); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MAXIMIZE, true); Assert.assertEquals(0, solution.getValue(), .0000001); } @Test public void testLargeModel() throws OptimizationException { double[] objective = new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; LinearObjectiveFunction f = new LinearObjectiveFunction(objective, 0); Collection constraints = new ArrayList(); constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 - x12 = 0")); constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 - x13 = 0")); constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 >= 49")); constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 >= 42")); constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x26 = 0")); constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x27 = 0")); constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x12 = 0")); constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x13 = 0")); constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 - x40 = 0")); constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 - x41 = 0")); constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 >= 49")); constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 >= 42")); constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x54 = 0")); constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x55 = 0")); constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x40 = 0")); constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x41 = 0")); constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 - x68 = 0")); constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 - x69 = 0")); constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 >= 51")); constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 >= 44")); constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x82 = 0")); constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x83 = 0")); constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x68 = 0")); constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x69 = 0")); constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 - x96 = 0")); constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 - x97 = 0")); constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 >= 51")); constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 >= 44")); constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x110 = 0")); constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x111 = 0")); constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x96 = 0")); constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x97 = 0")); constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 - x124 = 0")); constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 - x125 = 0")); constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 >= 49")); constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 >= 42")); constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x138 = 0")); constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x139 = 0")); constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x124 = 0")); constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x125 = 0")); constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 - x152 = 0")); constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 - x153 = 0")); constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 >= 59")); constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 >= 42")); constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x166 = 0")); constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x167 = 0")); constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x152 = 0")); constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x153 = 0")); constraints.add(equationFromString(objective.length, "x83 + x82 - x168 = 0")); constraints.add(equationFromString(objective.length, "x111 + x110 - x169 = 0")); constraints.add(equationFromString(objective.length, "x170 - x182 = 0")); constraints.add(equationFromString(objective.length, "x171 - x183 = 0")); constraints.add(equationFromString(objective.length, "x172 - x184 = 0")); constraints.add(equationFromString(objective.length, "x173 - x185 = 0")); constraints.add(equationFromString(objective.length, "x174 - x186 = 0")); constraints.add(equationFromString(objective.length, "x175 + x176 - x187 = 0")); constraints.add(equationFromString(objective.length, "x177 - x188 = 0")); constraints.add(equationFromString(objective.length, "x178 - x189 = 0")); constraints.add(equationFromString(objective.length, "x179 - x190 = 0")); constraints.add(equationFromString(objective.length, "x180 - x191 = 0")); constraints.add(equationFromString(objective.length, "x181 - x192 = 0")); constraints.add(equationFromString(objective.length, "x170 - x26 = 0")); constraints.add(equationFromString(objective.length, "x171 - x27 = 0")); constraints.add(equationFromString(objective.length, "x172 - x54 = 0")); constraints.add(equationFromString(objective.length, "x173 - x55 = 0")); constraints.add(equationFromString(objective.length, "x174 - x168 = 0")); constraints.add(equationFromString(objective.length, "x177 - x169 = 0")); constraints.add(equationFromString(objective.length, "x178 - x138 = 0")); constraints.add(equationFromString(objective.length, "x179 - x139 = 0")); constraints.add(equationFromString(objective.length, "x180 - x166 = 0")); constraints.add(equationFromString(objective.length, "x181 - x167 = 0")); constraints.add(equationFromString(objective.length, "x193 - x205 = 0")); constraints.add(equationFromString(objective.length, "x194 - x206 = 0")); constraints.add(equationFromString(objective.length, "x195 - x207 = 0")); constraints.add(equationFromString(objective.length, "x196 - x208 = 0")); constraints.add(equationFromString(objective.length, "x197 - x209 = 0")); constraints.add(equationFromString(objective.length, "x198 + x199 - x210 = 0")); constraints.add(equationFromString(objective.length, "x200 - x211 = 0")); constraints.add(equationFromString(objective.length, "x201 - x212 = 0")); constraints.add(equationFromString(objective.length, "x202 - x213 = 0")); constraints.add(equationFromString(objective.length, "x203 - x214 = 0")); constraints.add(equationFromString(objective.length, "x204 - x215 = 0")); constraints.add(equationFromString(objective.length, "x193 - x182 = 0")); constraints.add(equationFromString(objective.length, "x194 - x183 = 0")); constraints.add(equationFromString(objective.length, "x195 - x184 = 0")); constraints.add(equationFromString(objective.length, "x196 - x185 = 0")); constraints.add(equationFromString(objective.length, "x197 - x186 = 0")); constraints.add(equationFromString(objective.length, "x198 + x199 - x187 = 0")); constraints.add(equationFromString(objective.length, "x200 - x188 = 0")); constraints.add(equationFromString(objective.length, "x201 - x189 = 0")); constraints.add(equationFromString(objective.length, "x202 - x190 = 0")); constraints.add(equationFromString(objective.length, "x203 - x191 = 0")); constraints.add(equationFromString(objective.length, "x204 - x192 = 0")); SimplexSolver solver = new SimplexSolver(); RealPointValuePair solution = solver.optimize(f, constraints, GoalType.MINIMIZE, true); Assert.assertEquals(7518.0, solution.getValue(), .0000001); } /** * Converts a test string to a {@link LinearConstraint}. * Ex: x0 + x1 + x2 + x3 - x12 = 0 */ private LinearConstraint equationFromString(int numCoefficients, String s) { Relationship relationship; if (s.contains(">=")) { relationship = Relationship.GEQ; } else if (s.contains("<=")) { relationship = Relationship.LEQ; } else if (s.contains("=")) { relationship = Relationship.EQ; } else { throw new IllegalArgumentException(); } String[] equationParts = s.split("[>|<]?="); double rhs = Double.parseDouble(equationParts[1].trim()); double[] lhs = new double[numCoefficients]; String left = equationParts[0].replaceAll(" ?x", ""); String[] coefficients = left.split(" "); for (String coefficient : coefficients) { double value = coefficient.charAt(0) == '-' ? -1 : 1; int index = Integer.parseInt(coefficient.replaceFirst("[+|-]", "").trim()); lhs[index] = value; } return new LinearConstraint(lhs, relationship, rhs); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/linear/SimplexTableauTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/linear/SimplexTableauTest.ja100644 1750 1750 12017 11532241241 32507 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.util.ArrayList; import java.util.Collection; import org.apache.commons.math.TestUtils; import org.apache.commons.math.optimization.GoalType; import org.junit.Assert; import org.junit.Test; public class SimplexTableauTest { @Test public void testInitialization() { LinearObjectiveFunction f = createFunction(); Collection constraints = createConstraints(); SimplexTableau tableau = new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6); double[][] expectedInitialTableau = { {-1, 0, -1, -1, 2, 0, 0, 0, -4}, { 0, 1, -15, -10, 25, 0, 0, 0, 0}, { 0, 0, 1, 0, -1, 1, 0, 0, 2}, { 0, 0, 0, 1, -1, 0, 1, 0, 3}, { 0, 0, 1, 1, -2, 0, 0, 1, 4} }; assertMatrixEquals(expectedInitialTableau, tableau.getData()); } @Test public void testDropPhase1Objective() { LinearObjectiveFunction f = createFunction(); Collection constraints = createConstraints(); SimplexTableau tableau = new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6); double[][] expectedTableau = { { 1, -15, -10, 0, 0, 0, 0}, { 0, 1, 0, 1, 0, 0, 2}, { 0, 0, 1, 0, 1, 0, 3}, { 0, 1, 1, 0, 0, 1, 4} }; tableau.dropPhase1Objective(); assertMatrixEquals(expectedTableau, tableau.getData()); } @Test public void testTableauWithNoArtificialVars() { LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {15, 10}, 0); Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.LEQ, 2)); constraints.add(new LinearConstraint(new double[] {0, 1}, Relationship.LEQ, 3)); constraints.add(new LinearConstraint(new double[] {1, 1}, Relationship.LEQ, 4)); SimplexTableau tableau = new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6); double[][] initialTableau = { {1, -15, -10, 25, 0, 0, 0, 0}, {0, 1, 0, -1, 1, 0, 0, 2}, {0, 0, 1, -1, 0, 1, 0, 3}, {0, 1, 1, -2, 0, 0, 1, 4} }; assertMatrixEquals(initialTableau, tableau.getData()); } @Test public void testSerial() { LinearObjectiveFunction f = createFunction(); Collection constraints = createConstraints(); SimplexTableau tableau = new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6); Assert.assertEquals(tableau, TestUtils.serializeAndRecover(tableau)); } private LinearObjectiveFunction createFunction() { return new LinearObjectiveFunction(new double[] {15, 10}, 0); } private Collection createConstraints() { Collection constraints = new ArrayList(); constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.LEQ, 2)); constraints.add(new LinearConstraint(new double[] {0, 1}, Relationship.LEQ, 3)); constraints.add(new LinearConstraint(new double[] {1, 1}, Relationship.EQ, 4)); return constraints; } private void assertMatrixEquals(double[][] expected, double[][] result) { Assert.assertEquals("Wrong number of rows.", expected.length, result.length); for (int i = 0; i < expected.length; i++) { Assert.assertEquals("Wrong number of columns.", expected[i].length, result[i].length); for (int j = 0; j < expected[i].length; j++) { Assert.assertEquals("Wrong value at position [" + i + "," + j + "]", expected[i][j], result[i][j], 1.0e-15); } } } } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOpti100644 1750 1750 10677 11532241241 32677 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.optimization.univariate.BrentOptimizer; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class MultiStartUnivariateRealOptimizerTest { @Test public void testSinMin() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealOptimizer underlying = new BrentOptimizer(); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(44428400075l); MultiStartUnivariateRealOptimizer minimizer = new MultiStartUnivariateRealOptimizer(underlying, 10, g); minimizer.optimize(f, GoalType.MINIMIZE, -100.0, 100.0); double[] optima = minimizer.getOptima(); double[] optimaValues = minimizer.getOptimaValues(); for (int i = 1; i < optima.length; ++i) { double d = (optima[i] - optima[i-1]) / (2 * FastMath.PI); assertTrue (FastMath.abs(d - FastMath.rint(d)) < 1.0e-8); assertEquals(-1.0, f.value(optima[i]), 1.0e-10); assertEquals(f.value(optima[i]), optimaValues[i], 1.0e-10); } assertTrue(minimizer.getEvaluations() > 150); assertTrue(minimizer.getEvaluations() < 250); } @Test public void testQuinticMin() throws MathException { // The quintic function has zeros at 0, +-0.5 and +-1. // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643, UnivariateRealFunction f = new QuinticFunction(); UnivariateRealOptimizer underlying = new BrentOptimizer(); underlying.setRelativeAccuracy(1e-15); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(4312000053L); MultiStartUnivariateRealOptimizer minimizer = new MultiStartUnivariateRealOptimizer(underlying, 5, g); minimizer.setAbsoluteAccuracy(10 * minimizer.getAbsoluteAccuracy()); minimizer.setRelativeAccuracy(10 * minimizer.getRelativeAccuracy()); try { minimizer.getOptima(); fail("an exception should have been thrown"); } catch (IllegalStateException ise) { // expected } catch (Exception e) { fail("wrong exception caught"); } try { minimizer.getOptimaValues(); fail("an exception should have been thrown"); } catch (IllegalStateException ise) { // expected } catch (Exception e) { fail("wrong exception caught"); } double result = minimizer.optimize(f, GoalType.MINIMIZE, -0.3, -0.2); assertEquals(-0.2719561270319131, result, 1.0e-13); assertEquals(-0.2719561270319131, minimizer.getResult(), 1.0e-13); assertEquals(-0.04433426954946637, minimizer.getFunctionValue(), 1.0e-13); double[] optima = minimizer.getOptima(); double[] optimaValues = minimizer.getOptimaValues(); for (int i = 0; i < optima.length; ++i) { assertEquals(f.value(optima[i]), optimaValues[i], 1.0e-10); } assertTrue(minimizer.getEvaluations() >= 120); assertTrue(minimizer.getEvaluations() <= 170); assertTrue(minimizer.getIterationCount() >= 120); assertTrue(minimizer.getIterationCount() <= 170); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/MultiDirectionalTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/MultiDirectionalTest.100644 1750 1750 24274 11532241241 32535 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; public class MultiDirectionalTest { @Test public void testFunctionEvaluationException() throws OptimizationException, FunctionEvaluationException, IllegalArgumentException { MultivariateRealFunction wrong = new MultivariateRealFunction() { private static final long serialVersionUID = 4751314470965489371L; public double value(double[] x) throws FunctionEvaluationException { if (x[0] < 0) { throw new FunctionEvaluationException(x,LocalizedFormats.SIMPLE_MESSAGE, "oops"); } else if (x[0] > 1) { throw (new FunctionEvaluationException(new RuntimeException("oops"), x)); } else { return x[0] * (1 - x[0]); } } }; try { MultiDirectional optimizer = new MultiDirectional(0.9, 1.9); optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { -1.0 }); Assert.fail("an exception should have been thrown"); } catch (FunctionEvaluationException ce) { // expected behavior Assert.assertNull(ce.getCause()); } try { MultiDirectional optimizer = new MultiDirectional(0.9, 1.9); optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { +2.0 }); Assert.fail("an exception should have been thrown"); } catch (FunctionEvaluationException ce) { // expected behavior Assert.assertNotNull(ce.getCause()); } } @Test public void testMinimizeMaximize() throws FunctionEvaluationException, ConvergenceException { // the following function has 4 local extrema: final double xM = -3.841947088256863675365; final double yM = -1.391745200270734924416; final double xP = 0.2286682237349059125691; final double yP = -yM; final double valueXmYm = 0.2373295333134216789769; // local maximum final double valueXmYp = -valueXmYm; // local minimum final double valueXpYm = -0.7290400707055187115322; // global minimum final double valueXpYp = -valueXpYm; // global maximum MultivariateRealFunction fourExtrema = new MultivariateRealFunction() { private static final long serialVersionUID = -7039124064449091152L; public double value(double[] variables) throws FunctionEvaluationException { final double x = variables[0]; final double y = variables[1]; return ((x == 0) || (y == 0)) ? 0 : (FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y)); } }; MultiDirectional optimizer = new MultiDirectional(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-11, 1.0e-30)); optimizer.setMaxIterations(200); optimizer.setStartConfiguration(new double[] { 0.2, 0.2 }); RealPointValuePair optimum; // minimization optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { -3.0, 0 }); Assert.assertEquals(xM, optimum.getPoint()[0], 4.0e-6); Assert.assertEquals(yP, optimum.getPoint()[1], 3.0e-6); Assert.assertEquals(valueXmYp, optimum.getValue(), 8.0e-13); Assert.assertTrue(optimizer.getEvaluations() > 120); Assert.assertTrue(optimizer.getEvaluations() < 150); optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { +1, 0 }); Assert.assertEquals(xP, optimum.getPoint()[0], 2.0e-8); Assert.assertEquals(yM, optimum.getPoint()[1], 3.0e-6); Assert.assertEquals(valueXpYm, optimum.getValue(), 2.0e-12); Assert.assertTrue(optimizer.getEvaluations() > 120); Assert.assertTrue(optimizer.getEvaluations() < 150); // maximization optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 }); Assert.assertEquals(xM, optimum.getPoint()[0], 7.0e-7); Assert.assertEquals(yM, optimum.getPoint()[1], 3.0e-7); Assert.assertEquals(valueXmYm, optimum.getValue(), 2.0e-14); Assert.assertTrue(optimizer.getEvaluations() > 120); Assert.assertTrue(optimizer.getEvaluations() < 150); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-15, 1.0e-30)); optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { +1, 0 }); Assert.assertEquals(xP, optimum.getPoint()[0], 2.0e-8); Assert.assertEquals(yP, optimum.getPoint()[1], 3.0e-6); Assert.assertEquals(valueXpYp, optimum.getValue(), 2.0e-12); Assert.assertTrue(optimizer.getEvaluations() > 180); Assert.assertTrue(optimizer.getEvaluations() < 220); } @Test public void testRosenbrock() throws FunctionEvaluationException, ConvergenceException { MultivariateRealFunction rosenbrock = new MultivariateRealFunction() { private static final long serialVersionUID = -9044950469615237490L; public double value(double[] x) throws FunctionEvaluationException { ++count; double a = x[1] - x[0] * x[0]; double b = 1.0 - x[0]; return 100 * a * a + b * b; } }; count = 0; MultiDirectional optimizer = new MultiDirectional(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3)); optimizer.setMaxIterations(100); optimizer.setStartConfiguration(new double[][] { { -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 } }); RealPointValuePair optimum = optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 }); Assert.assertEquals(count, optimizer.getEvaluations()); Assert.assertTrue(optimizer.getEvaluations() > 50); Assert.assertTrue(optimizer.getEvaluations() < 100); Assert.assertTrue(optimum.getValue() > 1.0e-2); } @Test public void testPowell() throws FunctionEvaluationException, ConvergenceException { MultivariateRealFunction powell = new MultivariateRealFunction() { private static final long serialVersionUID = -832162886102041840L; public double value(double[] x) throws FunctionEvaluationException { ++count; double a = x[0] + 10 * x[1]; double b = x[2] - x[3]; double c = x[1] - 2 * x[2]; double d = x[0] - x[3]; return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d; } }; count = 0; MultiDirectional optimizer = new MultiDirectional(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3)); optimizer.setMaxIterations(1000); RealPointValuePair optimum = optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 }); Assert.assertEquals(count, optimizer.getEvaluations()); Assert.assertTrue(optimizer.getEvaluations() > 800); Assert.assertTrue(optimizer.getEvaluations() < 900); Assert.assertTrue(optimum.getValue() > 1.0e-2); } @Test public void testMath283() throws FunctionEvaluationException, OptimizationException { // fails because MultiDirectional.iterateSimplex is looping forever // the while(true) should be replaced with a convergence check MultiDirectional multiDirectional = new MultiDirectional(); multiDirectional.setMaxIterations(100); multiDirectional.setMaxEvaluations(1000); final Gaussian2D function = new Gaussian2D(0.0, 0.0, 1.0); RealPointValuePair estimate = multiDirectional.optimize(function, GoalType.MAXIMIZE, function.getMaximumPosition()); final double EPSILON = 1e-5; final double expectedMaximum = function.getMaximum(); final double actualMaximum = estimate.getValue(); Assert.assertEquals(expectedMaximum, actualMaximum, EPSILON); final double[] expectedPosition = function.getMaximumPosition(); final double[] actualPosition = estimate.getPoint(); Assert.assertEquals(expectedPosition[0], actualPosition[0], EPSILON ); Assert.assertEquals(expectedPosition[1], actualPosition[1], EPSILON ); } private static class Gaussian2D implements MultivariateRealFunction { private final double[] maximumPosition; private final double std; public Gaussian2D(double xOpt, double yOpt, double std) { maximumPosition = new double[] { xOpt, yOpt }; this.std = std; } public double getMaximum() { return value(maximumPosition); } public double[] getMaximumPosition() { return maximumPosition.clone(); } public double value(double[] point) { final double x = point[0], y = point[1]; final double twoS2 = 2.0 * std * std; return 1.0 / (twoS2 * FastMath.PI) * FastMath.exp(-(x * x + y * y) / twoS2); } } private int count; } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/PowellOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/PowellOptimizerTest.j100644 1750 1750 13605 11532241241 32600 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.analysis.SumSincFunction; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; import org.junit.Assert; import org.junit.Test; /** * Test for {@link PowellOptimizer}. */ public class PowellOptimizerTest { @Test public void testSumSinc() throws MathException { final DifferentiableMultivariateRealFunction func = new SumSincFunction(-1); int dim = 2; final double[] minPoint = new double[dim]; for (int i = 0; i < dim; i++) { minPoint[i] = 0; } double[] init = new double[dim]; // Initial is minimum. for (int i = 0; i < dim; i++) { init[i] = minPoint[i]; } // doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-5, 1e-9, 1e-7); // Initial is far from minimum. for (int i = 0; i < dim; i++) { init[i] = minPoint[i] + 3; } doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-5, 1e-9, 1e-7); } @Test public void testQuadratic() throws MathException { final DifferentiableMultivariateRealFunction func = new DifferentiableMultivariateRealFunction() { public double value(double[] x) { final double a = x[0] - 1; final double b = x[1] - 1; return a * a + b * b + 1; } public MultivariateRealFunction partialDerivative(int k) { return null; // Not used } public MultivariateVectorialFunction gradient() { return null; // Not used } }; int dim = 2; final double[] minPoint = new double[dim]; for (int i = 0; i < dim; i++) { minPoint[i] = 1; } double[] init = new double[dim]; // Initial is minimum. for (int i = 0; i < dim; i++) { init[i] = minPoint[i]; } doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-5, 1e-9, 1e-8); // Initial is far from minimum. for (int i = 0; i < dim; i++) { init[i] = minPoint[i] - 20; } doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-5, 1e-9, 1e-8); } @Test public void testMaximizeQuadratic() throws MathException { final DifferentiableMultivariateRealFunction func = new DifferentiableMultivariateRealFunction() { public double value(double[] x) { final double a = x[0] - 1; final double b = x[1] - 1; return -a * a - b * b + 1; } public MultivariateRealFunction partialDerivative(int k) { return null; // Not used } public MultivariateVectorialFunction gradient() { return null; // Not used } }; int dim = 2; final double[] maxPoint = new double[dim]; for (int i = 0; i < dim; i++) { maxPoint[i] = 1; } double[] init = new double[dim]; // Initial is minimum. for (int i = 0; i < dim; i++) { init[i] = maxPoint[i]; } doTest(func, maxPoint, init, GoalType.MAXIMIZE, 1e-5, 1e-9, 1e-8); // Initial is far from minimum. for (int i = 0; i < dim; i++) { init[i] = maxPoint[i] - 20; } doTest(func, maxPoint, init, GoalType.MAXIMIZE, 1e-5, 1e-9, 1e-8); } /** * @param func Function to optimize. * @param optimum Expected optimum. * @param init Starting point. * @param goal Minimization or maximization. * @param xTol Tolerance (relative error on the objective function) for * "Brent" line search algorithm used by "Powell". * @param fTol Tolerance (relative error on the objective function) for * "Powell" algorithm. * @param pointTol Tolerance for checking that the optimum is correct. */ private void doTest(DifferentiableMultivariateRealFunction func, double[] optimum, double[] init, GoalType goal, double xTol, double fTol, double pointTol) throws MathException { final PowellOptimizer optim = new PowellOptimizer(xTol); optim.setConvergenceChecker(new SimpleScalarValueChecker(fTol, -1)); final RealPointValuePair result = optim.optimize(func, goal, init); final double[] found = result.getPoint(); for (int i = 0, dim = optimum.length; i < dim; i++) { Assert.assertEquals(optimum[i], found[i], pointTol); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/direct/NelderMeadTest.java100644 1750 1750 32452 11532241241 32124 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.LeastSquaresConverter; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleRealPointChecker; import org.apache.commons.math.optimization.SimpleScalarValueChecker; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class NelderMeadTest { @Test public void testFunctionEvaluationException() throws OptimizationException, FunctionEvaluationException, IllegalArgumentException { MultivariateRealFunction wrong = new MultivariateRealFunction() { private static final long serialVersionUID = 4751314470965489371L; public double value(double[] x) throws FunctionEvaluationException { if (x[0] < 0) { throw new FunctionEvaluationException(x, LocalizedFormats.SIMPLE_MESSAGE, "oops"); } else if (x[0] > 1) { throw new FunctionEvaluationException(new RuntimeException("oops"), x); } else { return x[0] * (1 - x[0]); } } }; try { NelderMead optimizer = new NelderMead(0.9, 1.9, 0.4, 0.6); optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { -1.0 }); fail("an exception should have been thrown"); } catch (FunctionEvaluationException ce) { // expected behavior assertNull(ce.getCause()); } try { NelderMead optimizer = new NelderMead(0.9, 1.9, 0.4, 0.6); optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { +2.0 }); fail("an exception should have been thrown"); } catch (FunctionEvaluationException ce) { // expected behavior assertNotNull(ce.getCause()); } } @Test public void testMinimizeMaximize() throws FunctionEvaluationException, ConvergenceException { // the following function has 4 local extrema: final double xM = -3.841947088256863675365; final double yM = -1.391745200270734924416; final double xP = 0.2286682237349059125691; final double yP = -yM; final double valueXmYm = 0.2373295333134216789769; // local maximum final double valueXmYp = -valueXmYm; // local minimum final double valueXpYm = -0.7290400707055187115322; // global minimum final double valueXpYp = -valueXpYm; // global maximum MultivariateRealFunction fourExtrema = new MultivariateRealFunction() { private static final long serialVersionUID = -7039124064449091152L; public double value(double[] variables) throws FunctionEvaluationException { final double x = variables[0]; final double y = variables[1]; return ((x == 0) || (y == 0)) ? 0 : (FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y)); } }; NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-10, 1.0e-30)); optimizer.setMaxIterations(100); optimizer.setStartConfiguration(new double[] { 0.2, 0.2 }); RealPointValuePair optimum; // minimization optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { -3.0, 0 }); assertEquals(xM, optimum.getPoint()[0], 2.0e-7); assertEquals(yP, optimum.getPoint()[1], 2.0e-5); assertEquals(valueXmYp, optimum.getValue(), 6.0e-12); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 90); optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { +1, 0 }); assertEquals(xP, optimum.getPoint()[0], 5.0e-6); assertEquals(yM, optimum.getPoint()[1], 6.0e-6); assertEquals(valueXpYm, optimum.getValue(), 1.0e-11); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 90); // maximization optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 }); assertEquals(xM, optimum.getPoint()[0], 1.0e-5); assertEquals(yM, optimum.getPoint()[1], 3.0e-6); assertEquals(valueXmYm, optimum.getValue(), 3.0e-12); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 90); optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { +1, 0 }); assertEquals(xP, optimum.getPoint()[0], 4.0e-6); assertEquals(yP, optimum.getPoint()[1], 5.0e-6); assertEquals(valueXpYp, optimum.getValue(), 7.0e-12); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 90); } @Test public void testRosenbrock() throws FunctionEvaluationException, ConvergenceException { Rosenbrock rosenbrock = new Rosenbrock(); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3)); optimizer.setMaxIterations(100); optimizer.setStartConfiguration(new double[][] { { -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 } }); RealPointValuePair optimum = optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 }); assertEquals(rosenbrock.getCount(), optimizer.getEvaluations()); assertTrue(optimizer.getEvaluations() > 40); assertTrue(optimizer.getEvaluations() < 50); assertTrue(optimum.getValue() < 8.0e-4); } @Test public void testPowell() throws FunctionEvaluationException, ConvergenceException { Powell powell = new Powell(); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3)); optimizer.setMaxIterations(200); RealPointValuePair optimum = optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 }); assertEquals(powell.getCount(), optimizer.getEvaluations()); assertTrue(optimizer.getEvaluations() > 110); assertTrue(optimizer.getEvaluations() < 130); assertTrue(optimum.getValue() < 2.0e-3); } @Test public void testLeastSquares1() throws FunctionEvaluationException, ConvergenceException { final RealMatrix factors = new Array2DRowRealMatrix(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 } }, false); LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() { public double[] value(double[] variables) { return factors.operate(variables); } }, new double[] { 2.0, -3.0 }); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6)); optimizer.setMaxIterations(200); RealPointValuePair optimum = optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 }); assertEquals( 2.0, optimum.getPointRef()[0], 3.0e-5); assertEquals(-3.0, optimum.getPointRef()[1], 4.0e-4); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 80); assertTrue(optimum.getValue() < 1.0e-6); } @Test public void testLeastSquares2() throws FunctionEvaluationException, ConvergenceException { final RealMatrix factors = new Array2DRowRealMatrix(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 } }, false); LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() { public double[] value(double[] variables) { return factors.operate(variables); } }, new double[] { 2.0, -3.0 }, new double[] { 10.0, 0.1 }); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6)); optimizer.setMaxIterations(200); RealPointValuePair optimum = optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 }); assertEquals( 2.0, optimum.getPointRef()[0], 5.0e-5); assertEquals(-3.0, optimum.getPointRef()[1], 8.0e-4); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 80); assertTrue(optimum.getValue() < 1.0e-6); } @Test public void testLeastSquares3() throws FunctionEvaluationException, ConvergenceException { final RealMatrix factors = new Array2DRowRealMatrix(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 } }, false); LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() { public double[] value(double[] variables) { return factors.operate(variables); } }, new double[] { 2.0, -3.0 }, new Array2DRowRealMatrix(new double [][] { { 1.0, 1.2 }, { 1.2, 2.0 } })); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6)); optimizer.setMaxIterations(200); RealPointValuePair optimum = optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 }); assertEquals( 2.0, optimum.getPointRef()[0], 2.0e-3); assertEquals(-3.0, optimum.getPointRef()[1], 8.0e-4); assertTrue(optimizer.getEvaluations() > 60); assertTrue(optimizer.getEvaluations() < 80); assertTrue(optimum.getValue() < 1.0e-6); } @Test(expected = MaxIterationsExceededException.class) public void testMaxIterations() throws MathException { try { Powell powell = new Powell(); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3)); optimizer.setMaxIterations(20); optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 }); } catch (OptimizationException oe) { if (oe.getCause() instanceof ConvergenceException) { throw (ConvergenceException) oe.getCause(); } throw oe; } } @Test(expected = MaxEvaluationsExceededException.class) public void testMaxEvaluations() throws MathException { try { Powell powell = new Powell(); NelderMead optimizer = new NelderMead(); optimizer.setConvergenceChecker(new SimpleRealPointChecker(-1.0, 1.0e-3)); optimizer.setMaxEvaluations(20); optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 }); } catch (FunctionEvaluationException fee) { if (fee.getCause() instanceof ConvergenceException) { throw (ConvergenceException) fee.getCause(); } throw fee; } } private static class Rosenbrock implements MultivariateRealFunction { private int count; public Rosenbrock() { count = 0; } public double value(double[] x) { ++count; double a = x[1] - x[0] * x[0]; double b = 1.0 - x[0]; return 100 * a * a + b * b; } public int getCount() { return count; } } private static class Powell implements MultivariateRealFunction { private int count; public Powell() { count = 0; } public double value(double[] x) { ++count; double a = x[0] + 10 * x[1]; double b = x[2] - x[3]; double c = x[1] - 2 * x[2]; double d = x[0] - x[3]; return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d; } public int getCount() { return count; } } } ././@LongLink100644 0 0 203 11532242443 10246 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartDifferentiableMult100644 1750 1750 14413 11532241241 32665 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.awt.geom.Point2D; import java.util.ArrayList; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.general.ConjugateGradientFormula; import org.apache.commons.math.optimization.general.NonLinearConjugateGradientOptimizer; import org.apache.commons.math.random.GaussianRandomGenerator; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.random.RandomVectorGenerator; import org.apache.commons.math.random.UncorrelatedRandomVectorGenerator; import org.junit.Test; public class MultiStartDifferentiableMultivariateRealOptimizerTest { @Test public void testCircleFitting() throws Exception { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); NonLinearConjugateGradientOptimizer underlying = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(753289573253l); RandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(new double[] { 50.0, 50.0 }, new double[] { 10.0, 10.0 }, new GaussianRandomGenerator(g)); MultiStartDifferentiableMultivariateRealOptimizer optimizer = new MultiStartDifferentiableMultivariateRealOptimizer(underlying, 10, generator); optimizer.setMaxIterations(100); assertEquals(100, optimizer.getMaxIterations()); optimizer.setMaxEvaluations(100); assertEquals(100, optimizer.getMaxEvaluations()); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-10, 1.0e-10)); BrentSolver solver = new BrentSolver(); solver.setAbsoluteAccuracy(1.0e-13); solver.setRelativeAccuracy(1.0e-15); RealPointValuePair optimum = optimizer.optimize(circle, GoalType.MINIMIZE, new double[] { 98.680, 47.345 }); RealPointValuePair[] optima = optimizer.getOptima(); for (RealPointValuePair o : optima) { Point2D.Double center = new Point2D.Double(o.getPointRef()[0], o.getPointRef()[1]); assertEquals(69.960161753, circle.getRadius(center), 1.0e-8); assertEquals(96.075902096, center.x, 1.0e-8); assertEquals(48.135167894, center.y, 1.0e-8); } assertTrue(optimizer.getGradientEvaluations() > 650); assertTrue(optimizer.getGradientEvaluations() < 700); assertTrue(optimizer.getEvaluations() > 70); assertTrue(optimizer.getEvaluations() < 90); assertTrue(optimizer.getIterations() > 70); assertTrue(optimizer.getIterations() < 90); assertEquals(3.1267527, optimum.getValue(), 1.0e-8); } private static class Circle implements DifferentiableMultivariateRealFunction { private ArrayList points; public Circle() { points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new Point2D.Double(px, py)); } public double getRadius(Point2D.Double center) { double r = 0; for (Point2D.Double point : points) { r += point.distance(center); } return r / points.size(); } private double[] gradient(double[] point) { // optimal radius Point2D.Double center = new Point2D.Double(point[0], point[1]); double radius = getRadius(center); // gradient of the sum of squared residuals double dJdX = 0; double dJdY = 0; for (Point2D.Double pk : points) { double dk = pk.distance(center); dJdX += (center.x - pk.x) * (dk - radius) / dk; dJdY += (center.y - pk.y) * (dk - radius) / dk; } dJdX *= 2; dJdY *= 2; return new double[] { dJdX, dJdY }; } public double value(double[] variables) throws IllegalArgumentException, FunctionEvaluationException { Point2D.Double center = new Point2D.Double(variables[0], variables[1]); double radius = getRadius(center); double sum = 0; for (Point2D.Double point : points) { double di = point.distance(center) - radius; sum += di * di; } return sum; } public MultivariateVectorialFunction gradient() { return new MultivariateVectorialFunction() { public double[] value(double[] point) { return gradient(point); } }; } public MultivariateRealFunction partialDerivative(final int k) { return new MultivariateRealFunction() { public double value(double[] point) { return gradient(point)[k]; } }; } } } ././@LongLink100644 0 0 210 11532242443 10244 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/MultiStartDifferentiableMult100644 1750 1750 22424 11532241241 32666 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.Serializable; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; import org.apache.commons.math.random.GaussianRandomGenerator; import org.apache.commons.math.random.JDKRandomGenerator; import org.apache.commons.math.random.RandomVectorGenerator; import org.apache.commons.math.random.UncorrelatedRandomVectorGenerator; import org.junit.Test; /** *

        Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

        * * * *
        * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
        * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
          *
        1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
        2. *
        3. 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.
        4. *
        5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
        6. *
        7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
        8. *
        9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
        10. *
          * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ public class MultiStartDifferentiableMultivariateVectorialOptimizerTest { @Test public void testTrivial() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 2 } }, new double[] { 3 }); DifferentiableMultivariateVectorialOptimizer underlyingOptimizer = new GaussNewtonOptimizer(true); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(16069223052l); RandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(1, new GaussianRandomGenerator(g)); MultiStartDifferentiableMultivariateVectorialOptimizer optimizer = new MultiStartDifferentiableMultivariateVectorialOptimizer(underlyingOptimizer, 10, generator); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); // no optima before first optimization attempt try { optimizer.getOptima(); fail("an exception should have been thrown"); } catch (IllegalStateException ise) { // expected } VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0 }); assertEquals(1.5, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getValue()[0], 1.0e-10); VectorialPointValuePair[] optima = optimizer.getOptima(); assertEquals(10, optima.length); for (int i = 0; i < optima.length; ++i) { assertEquals(1.5, optima[i].getPoint()[0], 1.0e-10); assertEquals(3.0, optima[i].getValue()[0], 1.0e-10); } assertTrue(optimizer.getEvaluations() > 20); assertTrue(optimizer.getEvaluations() < 50); assertTrue(optimizer.getIterations() > 20); assertTrue(optimizer.getIterations() < 50); assertTrue(optimizer.getJacobianEvaluations() > 20); assertTrue(optimizer.getJacobianEvaluations() < 50); assertEquals(100, optimizer.getMaxIterations()); } @Test(expected = OptimizationException.class) public void testNoOptimum() throws FunctionEvaluationException, OptimizationException { DifferentiableMultivariateVectorialOptimizer underlyingOptimizer = new GaussNewtonOptimizer(true); JDKRandomGenerator g = new JDKRandomGenerator(); g.setSeed(12373523445l); RandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(1, new GaussianRandomGenerator(g)); MultiStartDifferentiableMultivariateVectorialOptimizer optimizer = new MultiStartDifferentiableMultivariateVectorialOptimizer(underlyingOptimizer, 10, generator); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); optimizer.optimize(new DifferentiableMultivariateVectorialFunction() { public MultivariateMatrixFunction jacobian() { return null; } public double[] value(double[] point) throws FunctionEvaluationException { throw new FunctionEvaluationException(point); } }, new double[] { 2 }, new double[] { 1 }, new double[] { 0 }); } private static class LinearProblem implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = -8804268799379350190L; final RealMatrix factors; final double[] target; public LinearProblem(double[][] factors, double[] target) { this.factors = new BlockRealMatrix(factors); this.target = target; } public double[] value(double[] variables) { return factors.operate(variables); } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -8387467946663627585L; public double[][] value(double[] point) { return factors.getData(); } }; } } } ././@LongLink100644 0 0 175 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/NonLinearConjugateGr100644 1750 1750 52033 11532241241 32522 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import java.awt.geom.Point2D; import java.io.Serializable; import java.util.ArrayList; import junit.framework.TestCase; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; /** *

          Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

          * * * *
          * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
          * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
            *
          1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
          2. *
          3. 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.
          4. *
          5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
          6. *
          7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
          8. *
          9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
          10. *
            * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ public class NonLinearConjugateGradientOptimizerTest extends TestCase { public NonLinearConjugateGradientOptimizerTest(String name) { super(name); } public void testTrivial() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 2 } }, new double[] { 3 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0 }); assertEquals(1.5, optimum.getPoint()[0], 1.0e-10); assertEquals(0.0, optimum.getValue(), 1.0e-10); } public void testColumnsPermutation() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } }, new double[] { 4.0, 6.0, 1.0 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0, 0 }); assertEquals(7.0, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getPoint()[1], 1.0e-10); assertEquals(0.0, optimum.getValue(), 1.0e-10); } public void testNoDependency() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 2, 0, 0, 0, 0, 0 }, { 0, 2, 0, 0, 0, 0 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 }, { 0, 0, 0, 0, 2, 0 }, { 0, 0, 0, 0, 0, 2 } }, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0, 0, 0, 0, 0, 0 }); for (int i = 0; i < problem.target.length; ++i) { assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10); } } public void testOneSet() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1, 0, 0 }, { -1, 1, 0 }, { 0, -1, 1 } }, new double[] { 1, 1, 1}); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0, 0, 0 }); assertEquals(1.0, optimum.getPoint()[0], 1.0e-10); assertEquals(2.0, optimum.getPoint()[1], 1.0e-10); assertEquals(3.0, optimum.getPoint()[2], 1.0e-10); } public void testTwoSets() throws Exception { final double epsilon = 1.0e-7; LinearProblem problem = new LinearProblem(new double[][] { { 2, 1, 0, 4, 0, 0 }, { -4, -2, 3, -7, 0, 0 }, { 4, 1, -2, 8, 0, 0 }, { 0, -3, -12, -1, 0, 0 }, { 0, 0, 0, 0, epsilon, 1 }, { 0, 0, 0, 0, 1, 1 } }, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2}); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setPreconditioner(new Preconditioner() { public double[] precondition(double[] point, double[] r) { double[] d = r.clone(); d[0] /= 72.0; d[1] /= 30.0; d[2] /= 314.0; d[3] /= 260.0; d[4] /= 2 * (1 + epsilon * epsilon); d[5] /= 4.0; return d; } }); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-13, 1.0e-13)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0, 0, 0, 0, 0, 0 }); assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10); assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10); assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10); assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10); assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10); assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10); } public void testNonInversible() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1, 2, -3 }, { 2, 1, 3 }, { -3, 0, -9 } }, new double[] { 1, 1, 1 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 0, 0, 0 }); assertTrue(optimum.getValue() > 0.5); } public void testIllConditioned() throws Exception { LinearProblem problem1 = new LinearProblem(new double[][] { { 10.0, 7.0, 8.0, 7.0 }, { 7.0, 5.0, 6.0, 5.0 }, { 8.0, 6.0, 10.0, 9.0 }, { 7.0, 5.0, 9.0, 10.0 } }, new double[] { 32, 23, 33, 31 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-13, 1.0e-13)); BrentSolver solver = new BrentSolver(); solver.setAbsoluteAccuracy(1.0e-15); solver.setRelativeAccuracy(1.0e-15); optimizer.setLineSearchSolver(solver); RealPointValuePair optimum1 = optimizer.optimize(problem1, GoalType.MINIMIZE, new double[] { 0, 1, 2, 3 }); assertEquals(1.0, optimum1.getPoint()[0], 1.0e-5); assertEquals(1.0, optimum1.getPoint()[1], 1.0e-5); assertEquals(1.0, optimum1.getPoint()[2], 1.0e-5); assertEquals(1.0, optimum1.getPoint()[3], 1.0e-5); LinearProblem problem2 = new LinearProblem(new double[][] { { 10.00, 7.00, 8.10, 7.20 }, { 7.08, 5.04, 6.00, 5.00 }, { 8.00, 5.98, 9.89, 9.00 }, { 6.99, 4.99, 9.00, 9.98 } }, new double[] { 32, 23, 33, 31 }); RealPointValuePair optimum2 = optimizer.optimize(problem2, GoalType.MINIMIZE, new double[] { 0, 1, 2, 3 }); assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-1); assertEquals(137.0, optimum2.getPoint()[1], 1.0e-1); assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-1); assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-1); } public void testMoreEstimatedParametersSimple() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 3.0, 2.0, 0.0, 0.0 }, { 0.0, 1.0, -1.0, 1.0 }, { 2.0, 0.0, 1.0, 0.0 } }, new double[] { 7.0, 3.0, 5.0 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 7, 6, 5, 4 }); assertEquals(0, optimum.getValue(), 1.0e-10); } public void testMoreEstimatedParametersUnsorted() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0, 1.0, -1.0 }, { 0.0, 0.0, -1.0, 1.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0, -1.0, 1.0, 0.0 } }, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 2, 2, 2, 2, 2, 2 }); assertEquals(0, optimum.getValue(), 1.0e-10); } public void testRedundantEquations() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 5.0 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 1, 1 }); assertEquals(2.0, optimum.getPoint()[0], 1.0e-8); assertEquals(1.0, optimum.getPoint()[1], 1.0e-8); } public void testInconsistentEquations() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 4.0 }); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-6, 1.0e-6)); RealPointValuePair optimum = optimizer.optimize(problem, GoalType.MINIMIZE, new double[] { 1, 1 }); assertTrue(optimum.getValue() > 0.1); } public void testCircleFitting() throws Exception { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); NonLinearConjugateGradientOptimizer optimizer = new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-30, 1.0e-30)); BrentSolver solver = new BrentSolver(); solver.setAbsoluteAccuracy(1.0e-13); solver.setRelativeAccuracy(1.0e-15); optimizer.setLineSearchSolver(solver); RealPointValuePair optimum = optimizer.optimize(circle, GoalType.MINIMIZE, new double[] { 98.680, 47.345 }); Point2D.Double center = new Point2D.Double(optimum.getPointRef()[0], optimum.getPointRef()[1]); assertEquals(69.960161753, circle.getRadius(center), 1.0e-8); assertEquals(96.075902096, center.x, 1.0e-8); assertEquals(48.135167894, center.y, 1.0e-8); } private static class LinearProblem implements DifferentiableMultivariateRealFunction, Serializable { private static final long serialVersionUID = 703247177355019415L; final RealMatrix factors; final double[] target; public LinearProblem(double[][] factors, double[] target) { this.factors = new BlockRealMatrix(factors); this.target = target; } private double[] gradient(double[] point) { double[] r = factors.operate(point); for (int i = 0; i < r.length; ++i) { r[i] -= target[i]; } double[] p = factors.transpose().operate(r); for (int i = 0; i < p.length; ++i) { p[i] *= 2; } return p; } public double value(double[] variables) throws FunctionEvaluationException { double[] y = factors.operate(variables); double sum = 0; for (int i = 0; i < y.length; ++i) { double ri = y[i] - target[i]; sum += ri * ri; } return sum; } public MultivariateVectorialFunction gradient() { return new MultivariateVectorialFunction() { private static final long serialVersionUID = 2621997811350805819L; public double[] value(double[] point) { return gradient(point); } }; } public MultivariateRealFunction partialDerivative(final int k) { return new MultivariateRealFunction() { private static final long serialVersionUID = -6186178619133562011L; public double value(double[] point) { return gradient(point)[k]; } }; } } private static class Circle implements DifferentiableMultivariateRealFunction, Serializable { private static final long serialVersionUID = -4711170319243817874L; private ArrayList points; public Circle() { points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new Point2D.Double(px, py)); } public double getRadius(Point2D.Double center) { double r = 0; for (Point2D.Double point : points) { r += point.distance(center); } return r / points.size(); } private double[] gradient(double[] point) { // optimal radius Point2D.Double center = new Point2D.Double(point[0], point[1]); double radius = getRadius(center); // gradient of the sum of squared residuals double dJdX = 0; double dJdY = 0; for (Point2D.Double pk : points) { double dk = pk.distance(center); dJdX += (center.x - pk.x) * (dk - radius) / dk; dJdY += (center.y - pk.y) * (dk - radius) / dk; } dJdX *= 2; dJdY *= 2; return new double[] { dJdX, dJdY }; } public double value(double[] variables) throws IllegalArgumentException, FunctionEvaluationException { Point2D.Double center = new Point2D.Double(variables[0], variables[1]); double radius = getRadius(center); double sum = 0; for (Point2D.Double point : points) { double di = point.distance(center) - radius; sum += di * di; } return sum; } public MultivariateVectorialFunction gradient() { return new MultivariateVectorialFunction() { private static final long serialVersionUID = 3174909643301201710L; public double[] value(double[] point) { return gradient(point); } }; } public MultivariateRealFunction partialDerivative(final int k) { return new MultivariateRealFunction() { private static final long serialVersionUID = 3073956364104833888L; public double value(double[] point) { return gradient(point)[k]; } }; } } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOp100644 1750 1750 72703 11532241241 32603 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import java.awt.geom.Point2D; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import junit.framework.TestCase; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.SimpleVectorialValueChecker; import org.apache.commons.math.optimization.VectorialPointValuePair; import org.apache.commons.math.util.FastMath; /** *

            Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

            * * * *
            * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
            * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
              *
            1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
            2. *
            3. 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.
            4. *
            5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
            6. *
            7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
            8. *
            9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
            10. *
              * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ public class LevenbergMarquardtOptimizerTest extends TestCase { public LevenbergMarquardtOptimizerTest(String name) { super(name); } public void testTrivial() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 2 } }, new double[] { 3 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); try { optimizer.guessParametersErrors(); fail("an exception should have been thrown"); } catch (OptimizationException ee) { // expected behavior } assertEquals(1.5, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getValue()[0], 1.0e-10); } public void testQRColumnsPermutation() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } }, new double[] { 4.0, 6.0, 1.0 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(7.0, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getPoint()[1], 1.0e-10); assertEquals(4.0, optimum.getValue()[0], 1.0e-10); assertEquals(6.0, optimum.getValue()[1], 1.0e-10); assertEquals(1.0, optimum.getValue()[2], 1.0e-10); } public void testNoDependency() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 2, 0, 0, 0, 0, 0 }, { 0, 2, 0, 0, 0, 0 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 }, { 0, 0, 0, 0, 2, 0 }, { 0, 0, 0, 0, 0, 2 } }, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 }, new double[] { 0, 0, 0, 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); for (int i = 0; i < problem.target.length; ++i) { assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10); } } public void testOneSet() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1, 0, 0 }, { -1, 1, 0 }, { 0, -1, 1 } }, new double[] { 1, 1, 1}); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(1.0, optimum.getPoint()[0], 1.0e-10); assertEquals(2.0, optimum.getPoint()[1], 1.0e-10); assertEquals(3.0, optimum.getPoint()[2], 1.0e-10); } public void testTwoSets() throws Exception { double epsilon = 1.0e-7; LinearProblem problem = new LinearProblem(new double[][] { { 2, 1, 0, 4, 0, 0 }, { -4, -2, 3, -7, 0, 0 }, { 4, 1, -2, 8, 0, 0 }, { 0, -3, -12, -1, 0, 0 }, { 0, 0, 0, 0, epsilon, 1 }, { 0, 0, 0, 0, 1, 1 } }, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2}); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 }, new double[] { 0, 0, 0, 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10); assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10); assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10); assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10); assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10); assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10); } public void testNonInversible() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1, 2, -3 }, { 2, 1, 3 }, { -3, 0, -9 } }, new double[] { 1, 1, 1 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 }); assertTrue(FastMath.sqrt(problem.target.length) * optimizer.getRMS() > 0.6); try { optimizer.getCovariances(); fail("an exception should have been thrown"); } catch (OptimizationException ee) { // expected behavior } } public void testIllConditioned() throws Exception { LinearProblem problem1 = new LinearProblem(new double[][] { { 10.0, 7.0, 8.0, 7.0 }, { 7.0, 5.0, 6.0, 5.0 }, { 8.0, 6.0, 10.0, 9.0 }, { 7.0, 5.0, 9.0, 10.0 } }, new double[] { 32, 23, 33, 31 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum1 = optimizer.optimize(problem1, problem1.target, new double[] { 1, 1, 1, 1 }, new double[] { 0, 1, 2, 3 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(1.0, optimum1.getPoint()[0], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[1], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[2], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[3], 1.0e-10); LinearProblem problem2 = new LinearProblem(new double[][] { { 10.00, 7.00, 8.10, 7.20 }, { 7.08, 5.04, 6.00, 5.00 }, { 8.00, 5.98, 9.89, 9.00 }, { 6.99, 4.99, 9.00, 9.98 } }, new double[] { 32, 23, 33, 31 }); VectorialPointValuePair optimum2 = optimizer.optimize(problem2, problem2.target, new double[] { 1, 1, 1, 1 }, new double[] { 0, 1, 2, 3 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-8); assertEquals(137.0, optimum2.getPoint()[1], 1.0e-8); assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-8); assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-8); } public void testMoreEstimatedParametersSimple() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 3.0, 2.0, 0.0, 0.0 }, { 0.0, 1.0, -1.0, 1.0 }, { 2.0, 0.0, 1.0, 0.0 } }, new double[] { 7.0, 3.0, 5.0 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 7, 6, 5, 4 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); } public void testMoreEstimatedParametersUnsorted() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0, 1.0, -1.0 }, { 0.0, 0.0, -1.0, 1.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0, -1.0, 1.0, 0.0 } }, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1 }, new double[] { 2, 2, 2, 2, 2, 2 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(3.0, optimum.getPointRef()[2], 1.0e-10); assertEquals(4.0, optimum.getPointRef()[3], 1.0e-10); assertEquals(5.0, optimum.getPointRef()[4], 1.0e-10); assertEquals(6.0, optimum.getPointRef()[5], 1.0e-10); } public void testRedundantEquations() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 5.0 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 1, 1 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(2.0, optimum.getPointRef()[0], 1.0e-10); assertEquals(1.0, optimum.getPointRef()[1], 1.0e-10); } public void testInconsistentEquations() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 4.0 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 1, 1 }); assertTrue(optimizer.getRMS() > 0.1); } public void testInconsistentSizes() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1, 0 }, { 0, 1 } }, new double[] { -1, 1 }); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1 }, new double[] { 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(-1, optimum.getPoint()[0], 1.0e-10); assertEquals(+1, optimum.getPoint()[1], 1.0e-10); try { optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0, 0 }); fail("an exception should have been thrown"); } catch (OptimizationException oe) { // expected behavior } try { optimizer.optimize(problem, new double[] { 1 }, new double[] { 1 }, new double[] { 0, 0 }); fail("an exception should have been thrown"); } catch (FunctionEvaluationException oe) { // expected behavior } } public void testControlParameters() { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); checkEstimate(circle, 0.1, 10, 1.0e-14, 1.0e-16, 1.0e-10, false); checkEstimate(circle, 0.1, 10, 1.0e-15, 1.0e-17, 1.0e-10, true); checkEstimate(circle, 0.1, 5, 1.0e-15, 1.0e-16, 1.0e-10, true); circle.addPoint(300, -300); checkEstimate(circle, 0.1, 20, 1.0e-18, 1.0e-16, 1.0e-10, true); } private void checkEstimate(DifferentiableMultivariateVectorialFunction problem, double initialStepBoundFactor, int maxCostEval, double costRelativeTolerance, double parRelativeTolerance, double orthoTolerance, boolean shouldFail) { try { LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.setInitialStepBoundFactor(initialStepBoundFactor); optimizer.setMaxIterations(maxCostEval); optimizer.setCostRelativeTolerance(costRelativeTolerance); optimizer.setParRelativeTolerance(parRelativeTolerance); optimizer.setOrthoTolerance(orthoTolerance); optimizer.optimize(problem, new double[] { 0, 0, 0, 0, 0 }, new double[] { 1, 1, 1, 1, 1 }, new double[] { 98.680, 47.345 }); assertTrue(! shouldFail); } catch (OptimizationException ee) { assertTrue(shouldFail); } catch (FunctionEvaluationException ee) { assertTrue(shouldFail); } } public void testCircleFitting() throws Exception { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); VectorialPointValuePair optimum = optimizer.optimize(circle, new double[] { 0, 0, 0, 0, 0 }, new double[] { 1, 1, 1, 1, 1 }, new double[] { 98.680, 47.345 }); assertTrue(optimizer.getEvaluations() < 10); assertTrue(optimizer.getJacobianEvaluations() < 10); double rms = optimizer.getRMS(); assertEquals(1.768262623567235, FastMath.sqrt(circle.getN()) * rms, 1.0e-10); Point2D.Double center = new Point2D.Double(optimum.getPointRef()[0], optimum.getPointRef()[1]); assertEquals(69.96016176931406, circle.getRadius(center), 1.0e-10); assertEquals(96.07590211815305, center.x, 1.0e-10); assertEquals(48.13516790438953, center.y, 1.0e-10); double[][] cov = optimizer.getCovariances(); assertEquals(1.839, cov[0][0], 0.001); assertEquals(0.731, cov[0][1], 0.001); assertEquals(cov[0][1], cov[1][0], 1.0e-14); assertEquals(0.786, cov[1][1], 0.001); double[] errors = optimizer.guessParametersErrors(); assertEquals(1.384, errors[0], 0.001); assertEquals(0.905, errors[1], 0.001); // add perfect measurements and check errors are reduced double r = circle.getRadius(center); for (double d= 0; d < 2 * FastMath.PI; d += 0.01) { circle.addPoint(center.x + r * FastMath.cos(d), center.y + r * FastMath.sin(d)); } double[] target = new double[circle.getN()]; Arrays.fill(target, 0.0); double[] weights = new double[circle.getN()]; Arrays.fill(weights, 2.0); optimizer.optimize(circle, target, weights, new double[] { 98.680, 47.345 }); cov = optimizer.getCovariances(); assertEquals(0.0016, cov[0][0], 0.001); assertEquals(3.2e-7, cov[0][1], 1.0e-9); assertEquals(cov[0][1], cov[1][0], 1.0e-14); assertEquals(0.0016, cov[1][1], 0.001); errors = optimizer.guessParametersErrors(); assertEquals(0.004, errors[0], 0.001); assertEquals(0.004, errors[1], 0.001); } public void testCircleFittingBadInit() throws FunctionEvaluationException, OptimizationException { Circle circle = new Circle(); double[][] points = new double[][] { {-0.312967, 0.072366}, {-0.339248, 0.132965}, {-0.379780, 0.202724}, {-0.390426, 0.260487}, {-0.361212, 0.328325}, {-0.346039, 0.392619}, {-0.280579, 0.444306}, {-0.216035, 0.470009}, {-0.149127, 0.493832}, {-0.075133, 0.483271}, {-0.007759, 0.452680}, { 0.060071, 0.410235}, { 0.103037, 0.341076}, { 0.118438, 0.273884}, { 0.131293, 0.192201}, { 0.115869, 0.129797}, { 0.072223, 0.058396}, { 0.022884, 0.000718}, {-0.053355, -0.020405}, {-0.123584, -0.032451}, {-0.216248, -0.032862}, {-0.278592, -0.005008}, {-0.337655, 0.056658}, {-0.385899, 0.112526}, {-0.405517, 0.186957}, {-0.415374, 0.262071}, {-0.387482, 0.343398}, {-0.347322, 0.397943}, {-0.287623, 0.458425}, {-0.223502, 0.475513}, {-0.135352, 0.478186}, {-0.061221, 0.483371}, { 0.003711, 0.422737}, { 0.065054, 0.375830}, { 0.108108, 0.297099}, { 0.123882, 0.222850}, { 0.117729, 0.134382}, { 0.085195, 0.056820}, { 0.029800, -0.019138}, {-0.027520, -0.072374}, {-0.102268, -0.091555}, {-0.200299, -0.106578}, {-0.292731, -0.091473}, {-0.356288, -0.051108}, {-0.420561, 0.014926}, {-0.471036, 0.074716}, {-0.488638, 0.182508}, {-0.485990, 0.254068}, {-0.463943, 0.338438}, {-0.406453, 0.404704}, {-0.334287, 0.466119}, {-0.254244, 0.503188}, {-0.161548, 0.495769}, {-0.075733, 0.495560}, { 0.001375, 0.434937}, { 0.082787, 0.385806}, { 0.115490, 0.323807}, { 0.141089, 0.223450}, { 0.138693, 0.131703}, { 0.126415, 0.049174}, { 0.066518, -0.010217}, {-0.005184, -0.070647}, {-0.080985, -0.103635}, {-0.177377, -0.116887}, {-0.260628, -0.100258}, {-0.335756, -0.056251}, {-0.405195, -0.000895}, {-0.444937, 0.085456}, {-0.484357, 0.175597}, {-0.472453, 0.248681}, {-0.438580, 0.347463}, {-0.402304, 0.422428}, {-0.326777, 0.479438}, {-0.247797, 0.505581}, {-0.152676, 0.519380}, {-0.071754, 0.516264}, { 0.015942, 0.472802}, { 0.076608, 0.419077}, { 0.127673, 0.330264}, { 0.159951, 0.262150}, { 0.153530, 0.172681}, { 0.140653, 0.089229}, { 0.078666, 0.024981}, { 0.023807, -0.037022}, {-0.048837, -0.077056}, {-0.127729, -0.075338}, {-0.221271, -0.067526} }; double[] target = new double[points.length]; Arrays.fill(target, 0.0); double[] weights = new double[points.length]; Arrays.fill(weights, 2.0); for (int i = 0; i < points.length; ++i) { circle.addPoint(points[i][0], points[i][1]); } LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-8, 1.0e-8)); VectorialPointValuePair optimum = optimizer.optimize(circle, target, weights, new double[] { -12, -12 }); Point2D.Double center = new Point2D.Double(optimum.getPointRef()[0], optimum.getPointRef()[1]); assertTrue(optimizer.getEvaluations() < 25); assertTrue(optimizer.getJacobianEvaluations() < 20); assertEquals( 0.043, optimizer.getRMS(), 1.0e-3); assertEquals( 0.292235, circle.getRadius(center), 1.0e-6); assertEquals(-0.151738, center.x, 1.0e-6); assertEquals( 0.2075001, center.y, 1.0e-6); } public void testMath199() throws FunctionEvaluationException { try { QuadraticProblem problem = new QuadraticProblem(); problem.addPoint (0, -3.182591015485607); problem.addPoint (1, -2.5581184967730577); problem.addPoint (2, -2.1488478161387325); problem.addPoint (3, -1.9122489313410047); problem.addPoint (4, 1.7785661310051026); LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.setQRRankingThreshold(0); optimizer.optimize(problem, new double[] { 0, 0, 0, 0, 0 }, new double[] { 0.0, 4.4e-323, 1.0, 4.4e-323, 0.0 }, new double[] { 0, 0, 0 }); fail("an exception should have been thrown"); } catch (OptimizationException ee) { // expected behavior } } private static class LinearProblem implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = 703247177355019415L; final RealMatrix factors; final double[] target; public LinearProblem(double[][] factors, double[] target) { this.factors = new BlockRealMatrix(factors); this.target = target; } public double[] value(double[] variables) { return factors.operate(variables); } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = 556396458721526234L; public double[][] value(double[] point) { return factors.getData(); } }; } } private static class Circle implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = -4711170319243817874L; private ArrayList points; public Circle() { points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new Point2D.Double(px, py)); } public int getN() { return points.size(); } public double getRadius(Point2D.Double center) { double r = 0; for (Point2D.Double point : points) { r += point.distance(center); } return r / points.size(); } private double[][] jacobian(double[] point) { int n = points.size(); Point2D.Double center = new Point2D.Double(point[0], point[1]); // gradient of the optimal radius double dRdX = 0; double dRdY = 0; for (Point2D.Double pk : points) { double dk = pk.distance(center); dRdX += (center.x - pk.x) / dk; dRdY += (center.y - pk.y) / dk; } dRdX /= n; dRdY /= n; // jacobian of the radius residuals double[][] jacobian = new double[n][2]; for (int i = 0; i < n; ++i) { Point2D.Double pi = points.get(i); double di = pi.distance(center); jacobian[i][0] = (center.x - pi.x) / di - dRdX; jacobian[i][1] = (center.y - pi.y) / di - dRdY; } return jacobian; } public double[] value(double[] variables) throws FunctionEvaluationException, IllegalArgumentException { Point2D.Double center = new Point2D.Double(variables[0], variables[1]); double radius = getRadius(center); double[] residuals = new double[points.size()]; for (int i = 0; i < residuals.length; ++i) { residuals[i] = points.get(i).distance(center) - radius; } return residuals; } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -4340046230875165095L; public double[][] value(double[] point) { return jacobian(point); } }; } } private static class QuadraticProblem implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = 7072187082052755854L; private List x; private List y; public QuadraticProblem() { x = new ArrayList(); y = new ArrayList(); } public void addPoint(double x, double y) { this.x.add(x); this.y.add(y); } private double[][] jacobian(double[] variables) { double[][] jacobian = new double[x.size()][3]; for (int i = 0; i < jacobian.length; ++i) { jacobian[i][0] = x.get(i) * x.get(i); jacobian[i][1] = x.get(i); jacobian[i][2] = 1.0; } return jacobian; } public double[] value(double[] variables) { double[] values = new double[x.size()]; for (int i = 0; i < values.length; ++i) { values[i] = (variables[0] * x.get(i) + variables[1]) * x.get(i) + variables[2]; } return values; } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -8673650298627399464L; public double[][] value(double[] point) { return jacobian(point); } }; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/MinpackTest.java100644 1750 1750 164157 11532241241 31701 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import java.io.Serializable; import java.util.Arrays; import junit.framework.TestCase; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.VectorialPointValuePair; import org.apache.commons.math.util.FastMath; /** *

              Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

              * * * *
              * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
              * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                *
              1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
              2. *
              3. 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.
              4. *
              5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
              6. *
              7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
              8. *
              9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
              10. *
                * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ public class MinpackTest extends TestCase { public MinpackTest(String name) { super(name); } public void testMinpackLinearFullRank() { minpackTest(new LinearFullRankFunction(10, 5, 1.0, 5.0, 2.23606797749979), false); minpackTest(new LinearFullRankFunction(50, 5, 1.0, 8.06225774829855, 6.70820393249937), false); } public void testMinpackLinearRank1() { minpackTest(new LinearRank1Function(10, 5, 1.0, 291.521868819476, 1.4638501094228), false); minpackTest(new LinearRank1Function(50, 5, 1.0, 3101.60039334535, 3.48263016573496), false); } public void testMinpackLinearRank1ZeroColsAndRows() { minpackTest(new LinearRank1ZeroColsAndRowsFunction(10, 5, 1.0), false); minpackTest(new LinearRank1ZeroColsAndRowsFunction(50, 5, 1.0), false); } public void testMinpackRosenbrok() { minpackTest(new RosenbrockFunction(new double[] { -1.2, 1.0 }, FastMath.sqrt(24.2)), false); minpackTest(new RosenbrockFunction(new double[] { -12.0, 10.0 }, FastMath.sqrt(1795769.0)), false); minpackTest(new RosenbrockFunction(new double[] { -120.0, 100.0 }, 11.0 * FastMath.sqrt(169000121.0)), false); } public void testMinpackHelicalValley() { minpackTest(new HelicalValleyFunction(new double[] { -1.0, 0.0, 0.0 }, 50.0), false); minpackTest(new HelicalValleyFunction(new double[] { -10.0, 0.0, 0.0 }, 102.95630140987), false); minpackTest(new HelicalValleyFunction(new double[] { -100.0, 0.0, 0.0}, 991.261822123701), false); } public void testMinpackPowellSingular() { minpackTest(new PowellSingularFunction(new double[] { 3.0, -1.0, 0.0, 1.0 }, 14.6628782986152), false); minpackTest(new PowellSingularFunction(new double[] { 30.0, -10.0, 0.0, 10.0 }, 1270.9838708654), false); minpackTest(new PowellSingularFunction(new double[] { 300.0, -100.0, 0.0, 100.0 }, 126887.903284750), false); } public void testMinpackFreudensteinRoth() { minpackTest(new FreudensteinRothFunction(new double[] { 0.5, -2.0 }, 20.0124960961895, 6.99887517584575, new double[] { 11.4124844654993, -0.896827913731509 }), false); minpackTest(new FreudensteinRothFunction(new double[] { 5.0, -20.0 }, 12432.833948863, 6.9988751744895, new double[] { 11.41300466147456, -0.896796038685959 }), false); minpackTest(new FreudensteinRothFunction(new double[] { 50.0, -200.0 }, 11426454.595762, 6.99887517242903, new double[] { 11.412781785788564, -0.8968051074920405 }), false); } public void testMinpackBard() { minpackTest(new BardFunction(1.0, 6.45613629515967, 0.0906359603390466, new double[] { 0.0824105765758334, 1.1330366534715, 2.34369463894115 }), false); minpackTest(new BardFunction(10.0, 36.1418531596785, 4.17476870138539, new double[] { 0.840666673818329, -158848033.259565, -164378671.653535 }), false); minpackTest(new BardFunction(100.0, 384.114678637399, 4.17476870135969, new double[] { 0.840666673867645, -158946167.205518, -164464906.857771 }), false); } public void testMinpackKowalikOsborne() { minpackTest(new KowalikOsborneFunction(new double[] { 0.25, 0.39, 0.415, 0.39 }, 0.0728915102882945, 0.017535837721129, new double[] { 0.192807810476249, 0.191262653354071, 0.123052801046931, 0.136053221150517 }), false); minpackTest(new KowalikOsborneFunction(new double[] { 2.5, 3.9, 4.15, 3.9 }, 2.97937007555202, 0.032052192917937, new double[] { 728675.473768287, -14.0758803129393, -32977797.7841797, -20571594.1977912 }), false); minpackTest(new KowalikOsborneFunction(new double[] { 25.0, 39.0, 41.5, 39.0 }, 29.9590617016037, 0.0175364017658228, new double[] { 0.192948328597594, 0.188053165007911, 0.122430604321144, 0.134575665392506 }), false); } public void testMinpackMeyer() { minpackTest(new MeyerFunction(new double[] { 0.02, 4000.0, 250.0 }, 41153.4665543031, 9.37794514651874, new double[] { 0.00560963647102661, 6181.34634628659, 345.223634624144 }), false); minpackTest(new MeyerFunction(new double[] { 0.2, 40000.0, 2500.0 }, 4168216.89130846, 792.917871779501, new double[] { 1.42367074157994e-11, 33695.7133432541, 901.268527953801 }), true); } public void testMinpackWatson() { minpackTest(new WatsonFunction(6, 0.0, 5.47722557505166, 0.0478295939097601, new double[] { -0.0157249615083782, 1.01243488232965, -0.232991722387673, 1.26043101102818, -1.51373031394421, 0.99299727291842 }), false); minpackTest(new WatsonFunction(6, 10.0, 6433.12578950026, 0.0478295939096951, new double[] { -0.0157251901386677, 1.01243485860105, -0.232991545843829, 1.26042932089163, -1.51372776706575, 0.99299573426328 }), false); minpackTest(new WatsonFunction(6, 100.0, 674256.040605213, 0.047829593911544, new double[] { -0.0157247019712586, 1.01243490925658, -0.232991922761641, 1.26043292929555, -1.51373320452707, 0.99299901922322 }), false); minpackTest(new WatsonFunction(9, 0.0, 5.47722557505166, 0.00118311459212420, new double[] { -0.153070644166722e-4, 0.999789703934597, 0.0147639634910978, 0.146342330145992, 1.00082109454817, -2.61773112070507, 4.10440313943354, -3.14361226236241, 1.05262640378759 }), false); minpackTest(new WatsonFunction(9, 10.0, 12088.127069307, 0.00118311459212513, new double[] { -0.153071334849279e-4, 0.999789703941234, 0.0147639629786217, 0.146342334818836, 1.00082107321386, -2.61773107084722, 4.10440307655564, -3.14361222178686, 1.05262639322589 }), false); minpackTest(new WatsonFunction(9, 100.0, 1269109.29043834, 0.00118311459212384, new double[] { -0.153069523352176e-4, 0.999789703958371, 0.0147639625185392, 0.146342341096326, 1.00082104729164, -2.61773101573645, 4.10440301427286, -3.14361218602503, 1.05262638516774 }), false); minpackTest(new WatsonFunction(12, 0.0, 5.47722557505166, 0.217310402535861e-4, new double[] { -0.660266001396382e-8, 1.00000164411833, -0.000563932146980154, 0.347820540050756, -0.156731500244233, 1.05281515825593, -3.24727109519451, 7.2884347837505, -10.271848098614, 9.07411353715783, -4.54137541918194, 1.01201187975044 }), false); minpackTest(new WatsonFunction(12, 10.0, 19220.7589790951, 0.217310402518509e-4, new double[] { -0.663710223017410e-8, 1.00000164411787, -0.000563932208347327, 0.347820540486998, -0.156731503955652, 1.05281517654573, -3.2472711515214, 7.28843489430665, -10.2718482369638, 9.07411364383733, -4.54137546533666, 1.01201188830857 }), false); minpackTest(new WatsonFunction(12, 100.0, 2018918.04462367, 0.217310402539845e-4, new double[] { -0.663806046485249e-8, 1.00000164411786, -0.000563932210324959, 0.347820540503588, -0.156731504091375, 1.05281517718031, -3.24727115337025, 7.28843489775302, -10.2718482410813, 9.07411364688464, -4.54137546660822, 1.0120118885369 }), false); } public void testMinpackBox3Dimensional() { minpackTest(new Box3DimensionalFunction(10, new double[] { 0.0, 10.0, 20.0 }, 32.1115837449572), false); } public void testMinpackJennrichSampson() { minpackTest(new JennrichSampsonFunction(10, new double[] { 0.3, 0.4 }, 64.5856498144943, 11.1517793413499, new double[] { // 0.2578330049, 0.257829976764542 0.2578199266368004, 0.25782997676455244 }), false); } public void testMinpackBrownDennis() { minpackTest(new BrownDennisFunction(20, new double[] { 25.0, 5.0, -5.0, -1.0 }, 2815.43839161816, 292.954288244866, new double[] { -11.59125141003, 13.2024883984741, -0.403574643314272, 0.236736269844604 }), false); minpackTest(new BrownDennisFunction(20, new double[] { 250.0, 50.0, -50.0, -10.0 }, 555073.354173069, 292.954270581415, new double[] { -11.5959274272203, 13.2041866926242, -0.403417362841545, 0.236771143410386 }), false); minpackTest(new BrownDennisFunction(20, new double[] { 2500.0, 500.0, -500.0, -100.0 }, 61211252.2338581, 292.954306151134, new double[] { -11.5902596937374, 13.2020628854665, -0.403688070279258, 0.236665033746463 }), false); } public void testMinpackChebyquad() { minpackTest(new ChebyquadFunction(1, 8, 1.0, 1.88623796907732, 1.88623796907732, new double[] { 0.5 }), false); minpackTest(new ChebyquadFunction(1, 8, 10.0, 5383344372.34005, 1.88424820499951, new double[] { 0.9817314924684 }), false); minpackTest(new ChebyquadFunction(1, 8, 100.0, 0.118088726698392e19, 1.88424820499347, new double[] { 0.9817314852934 }), false); minpackTest(new ChebyquadFunction(8, 8, 1.0, 0.196513862833975, 0.0593032355046727, new double[] { 0.0431536648587336, 0.193091637843267, 0.266328593812698, 0.499999334628884, 0.500000665371116, 0.733671406187302, 0.806908362156733, 0.956846335141266 }), false); minpackTest(new ChebyquadFunction(9, 9, 1.0, 0.16994993465202, 0.0, new double[] { 0.0442053461357828, 0.199490672309881, 0.23561910847106, 0.416046907892598, 0.5, 0.583953092107402, 0.764380891528940, 0.800509327690119, 0.955794653864217 }), false); minpackTest(new ChebyquadFunction(10, 10, 1.0, 0.183747831178711, 0.0806471004038253, new double[] { 0.0596202671753563, 0.166708783805937, 0.239171018813509, 0.398885290346268, 0.398883667870681, 0.601116332129320, 0.60111470965373, 0.760828981186491, 0.833291216194063, 0.940379732824644 }), false); } public void testMinpackBrownAlmostLinear() { minpackTest(new BrownAlmostLinearFunction(10, 0.5, 16.5302162063499, 0.0, new double[] { 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 0.979430303349862, 1.20569696650138 }), false); minpackTest(new BrownAlmostLinearFunction(10, 5.0, 9765624.00089211, 0.0, new double[] { 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 0.979430303349865, 1.20569696650135 }), false); minpackTest(new BrownAlmostLinearFunction(10, 50.0, 0.9765625e17, 0.0, new double[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }), false); minpackTest(new BrownAlmostLinearFunction(30, 0.5, 83.476044467848, 0.0, new double[] { 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 0.997754216442807, 1.06737350671578 }), false); minpackTest(new BrownAlmostLinearFunction(40, 0.5, 128.026364472323, 0.0, new double[] { 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 1.00000000000002, 0.999999999999121 }), false); } public void testMinpackOsborne1() { minpackTest(new Osborne1Function(new double[] { 0.5, 1.5, -1.0, 0.01, 0.02, }, 0.937564021037838, 0.00739249260904843, new double[] { 0.375410049244025, 1.93584654543108, -1.46468676748716, 0.0128675339110439, 0.0221227011813076 }), false); } public void testMinpackOsborne2() { minpackTest(new Osborne2Function(new double[] { 1.3, 0.65, 0.65, 0.7, 0.6, 3.0, 5.0, 7.0, 2.0, 4.5, 5.5 }, 1.44686540984712, 0.20034404483314, new double[] { 1.30997663810096, 0.43155248076, 0.633661261602859, 0.599428560991695, 0.754179768272449, 0.904300082378518, 1.36579949521007, 4.82373199748107, 2.39868475104871, 4.56887554791452, 5.67534206273052 }), false); } private void minpackTest(MinpackFunction function, boolean exceptionExpected) { LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); optimizer.setMaxIterations(100 * (function.getN() + 1)); optimizer.setCostRelativeTolerance(FastMath.sqrt(2.22044604926e-16)); optimizer.setParRelativeTolerance(FastMath.sqrt(2.22044604926e-16)); optimizer.setOrthoTolerance(2.22044604926e-16); // assertTrue(function.checkTheoreticalStartCost(optimizer.getRMS())); try { VectorialPointValuePair optimum = optimizer.optimize(function, function.getTarget(), function.getWeight(), function.getStartPoint()); assertFalse(exceptionExpected); function.checkTheoreticalMinCost(optimizer.getRMS()); function.checkTheoreticalMinParams(optimum); } catch (OptimizationException lsse) { assertTrue(exceptionExpected); } catch (FunctionEvaluationException fe) { assertTrue(exceptionExpected); } } private static abstract class MinpackFunction implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = -6209760235478794233L; protected int n; protected int m; protected double[] startParams; protected double theoreticalMinCost; protected double[] theoreticalMinParams; protected double costAccuracy; protected double paramsAccuracy; protected MinpackFunction(int m, double[] startParams, double theoreticalMinCost, double[] theoreticalMinParams) { this.m = m; this.n = startParams.length; this.startParams = startParams.clone(); this.theoreticalMinCost = theoreticalMinCost; this.theoreticalMinParams = theoreticalMinParams; this.costAccuracy = 1.0e-8; this.paramsAccuracy = 1.0e-5; } protected static double[] buildArray(int n, double x) { double[] array = new double[n]; Arrays.fill(array, x); return array; } public double[] getTarget() { return buildArray(m, 0.0); } public double[] getWeight() { return buildArray(m, 1.0); } public double[] getStartPoint() { return startParams.clone(); } protected void setCostAccuracy(double costAccuracy) { this.costAccuracy = costAccuracy; } protected void setParamsAccuracy(double paramsAccuracy) { this.paramsAccuracy = paramsAccuracy; } public int getN() { return startParams.length; } public void checkTheoreticalMinCost(double rms) { double threshold = costAccuracy * (1.0 + theoreticalMinCost); assertEquals(theoreticalMinCost, FastMath.sqrt(m) * rms, threshold); } public void checkTheoreticalMinParams(VectorialPointValuePair optimum) { double[] params = optimum.getPointRef(); if (theoreticalMinParams != null) { for (int i = 0; i < theoreticalMinParams.length; ++i) { double mi = theoreticalMinParams[i]; double vi = params[i]; assertEquals(mi, vi, paramsAccuracy * (1.0 + FastMath.abs(mi))); } } } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -2435076097232923678L; public double[][] value(double[] point) { return jacobian(point); } }; } public abstract double[][] jacobian(double[] variables); public abstract double[] value(double[] variables); } private static class LinearFullRankFunction extends MinpackFunction { private static final long serialVersionUID = -9030323226268039536L; public LinearFullRankFunction(int m, int n, double x0, double theoreticalStartCost, double theoreticalMinCost) { super(m, buildArray(n, x0), theoreticalMinCost, buildArray(n, -1.0)); } @Override public double[][] jacobian(double[] variables) { double t = 2.0 / m; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = (i == j) ? (1 - t) : -t; } } return jacobian; } @Override public double[] value(double[] variables) { double sum = 0; for (int i = 0; i < n; ++i) { sum += variables[i]; } double t = 1 + 2 * sum / m; double[] f = new double[m]; for (int i = 0; i < n; ++i) { f[i] = variables[i] - t; } Arrays.fill(f, n, m, -t); return f; } } private static class LinearRank1Function extends MinpackFunction { private static final long serialVersionUID = 8494863245104608300L; public LinearRank1Function(int m, int n, double x0, double theoreticalStartCost, double theoreticalMinCost) { super(m, buildArray(n, x0), theoreticalMinCost, null); } @Override public double[][] jacobian(double[] variables) { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = (i + 1) * (j + 1); } } return jacobian; } @Override public double[] value(double[] variables) { double[] f = new double[m]; double sum = 0; for (int i = 0; i < n; ++i) { sum += (i + 1) * variables[i]; } for (int i = 0; i < m; ++i) { f[i] = (i + 1) * sum - 1; } return f; } } private static class LinearRank1ZeroColsAndRowsFunction extends MinpackFunction { private static final long serialVersionUID = -3316653043091995018L; public LinearRank1ZeroColsAndRowsFunction(int m, int n, double x0) { super(m, buildArray(n, x0), FastMath.sqrt((m * (m + 3) - 6) / (2.0 * (2 * m - 3))), null); } @Override public double[][] jacobian(double[] variables) { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; jacobian[i][0] = 0; for (int j = 1; j < (n - 1); ++j) { if (i == 0) { jacobian[i][j] = 0; } else if (i != (m - 1)) { jacobian[i][j] = i * (j + 1); } else { jacobian[i][j] = 0; } } jacobian[i][n - 1] = 0; } return jacobian; } @Override public double[] value(double[] variables) { double[] f = new double[m]; double sum = 0; for (int i = 1; i < (n - 1); ++i) { sum += (i + 1) * variables[i]; } for (int i = 0; i < (m - 1); ++i) { f[i] = i * sum - 1; } f[m - 1] = -1; return f; } } private static class RosenbrockFunction extends MinpackFunction { private static final long serialVersionUID = 2893438180956569134L; public RosenbrockFunction(double[] startParams, double theoreticalStartCost) { super(2, startParams, 0.0, buildArray(2, 1.0)); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; return new double[][] { { -20 * x1, 10 }, { -1, 0 } }; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; return new double[] { 10 * (x2 - x1 * x1), 1 - x1 }; } } private static class HelicalValleyFunction extends MinpackFunction { private static final long serialVersionUID = 220613787843200102L; public HelicalValleyFunction(double[] startParams, double theoreticalStartCost) { super(3, startParams, 0.0, new double[] { 1.0, 0.0, 0.0 }); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double tmpSquare = x1 * x1 + x2 * x2; double tmp1 = twoPi * tmpSquare; double tmp2 = FastMath.sqrt(tmpSquare); return new double[][] { { 100 * x2 / tmp1, -100 * x1 / tmp1, 10 }, { 10 * x1 / tmp2, 10 * x2 / tmp2, 0 }, { 0, 0, 1 } }; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double tmp1; if (x1 == 0) { tmp1 = (x2 >= 0) ? 0.25 : -0.25; } else { tmp1 = FastMath.atan(x2 / x1) / twoPi; if (x1 < 0) { tmp1 += 0.5; } } double tmp2 = FastMath.sqrt(x1 * x1 + x2 * x2); return new double[] { 10.0 * (x3 - 10 * tmp1), 10.0 * (tmp2 - 1), x3 }; } private static final double twoPi = 2.0 * FastMath.PI; } private static class PowellSingularFunction extends MinpackFunction { private static final long serialVersionUID = 7298364171208142405L; public PowellSingularFunction(double[] startParams, double theoreticalStartCost) { super(4, startParams, 0.0, buildArray(4, 0.0)); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; return new double[][] { { 1, 10, 0, 0 }, { 0, 0, sqrt5, -sqrt5 }, { 0, 2 * (x2 - 2 * x3), -4 * (x2 - 2 * x3), 0 }, { 2 * sqrt10 * (x1 - x4), 0, 0, -2 * sqrt10 * (x1 - x4) } }; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; return new double[] { x1 + 10 * x2, sqrt5 * (x3 - x4), (x2 - 2 * x3) * (x2 - 2 * x3), sqrt10 * (x1 - x4) * (x1 - x4) }; } private static final double sqrt5 = FastMath.sqrt( 5.0); private static final double sqrt10 = FastMath.sqrt(10.0); } private static class FreudensteinRothFunction extends MinpackFunction { private static final long serialVersionUID = 2892404999344244214L; public FreudensteinRothFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(2, startParams, theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double x2 = variables[1]; return new double[][] { { 1, x2 * (10 - 3 * x2) - 2 }, { 1, x2 * ( 2 + 3 * x2) - 14, } }; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; return new double[] { -13.0 + x1 + ((5.0 - x2) * x2 - 2.0) * x2, -29.0 + x1 + ((1.0 + x2) * x2 - 14.0) * x2 }; } } private static class BardFunction extends MinpackFunction { private static final long serialVersionUID = 5990442612572087668L; public BardFunction(double x0, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(15, buildArray(3, x0), theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double x2 = variables[1]; double x3 = variables[2]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp1 = i + 1; double tmp2 = 15 - i; double tmp3 = (i <= 7) ? tmp1 : tmp2; double tmp4 = x2 * tmp2 + x3 * tmp3; tmp4 *= tmp4; jacobian[i] = new double[] { -1, tmp1 * tmp2 / tmp4, tmp1 * tmp3 / tmp4 }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double tmp1 = i + 1; double tmp2 = 15 - i; double tmp3 = (i <= 7) ? tmp1 : tmp2; f[i] = y[i] - (x1 + tmp1 / (x2 * tmp2 + x3 * tmp3)); } return f; } private static final double[] y = { 0.14, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.39, 0.37, 0.58, 0.73, 0.96, 1.34, 2.10, 4.39 }; } private static class KowalikOsborneFunction extends MinpackFunction { private static final long serialVersionUID = -4867445739880495801L; public KowalikOsborneFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(11, startParams, theoreticalMinCost, theoreticalMinParams); if (theoreticalStartCost > 20.0) { setCostAccuracy(2.0e-4); setParamsAccuracy(5.0e-3); } } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp = v[i] * (v[i] + x3) + x4; double j1 = -v[i] * (v[i] + x2) / tmp; double j2 = -v[i] * x1 / tmp; double j3 = j1 * j2; double j4 = j3 / v[i]; jacobian[i] = new double[] { j1, j2, j3, j4 }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { f[i] = y[i] - x1 * (v[i] * (v[i] + x2)) / (v[i] * (v[i] + x3) + x4); } return f; } private static final double[] v = { 4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625 }; private static final double[] y = { 0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627, 0.0456, 0.0342, 0.0323, 0.0235, 0.0246 }; } private static class MeyerFunction extends MinpackFunction { private static final long serialVersionUID = -838060619150131027L; public MeyerFunction(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(16, startParams, theoreticalMinCost, theoreticalMinParams); if (theoreticalStartCost > 1.0e6) { setCostAccuracy(7.0e-3); setParamsAccuracy(2.0e-2); } } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = 5.0 * (i + 1) + 45.0 + x3; double tmp1 = x2 / temp; double tmp2 = FastMath.exp(tmp1); double tmp3 = x1 * tmp2 / temp; jacobian[i] = new double[] { tmp2, tmp3, -tmp1 * tmp3 }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { f[i] = x1 * FastMath.exp(x2 / (5.0 * (i + 1) + 45.0 + x3)) - y[i]; } return f; } private static final double[] y = { 34780.0, 28610.0, 23650.0, 19630.0, 16370.0, 13720.0, 11540.0, 9744.0, 8261.0, 7030.0, 6005.0, 5147.0, 4427.0, 3820.0, 3307.0, 2872.0 }; } private static class WatsonFunction extends MinpackFunction { private static final long serialVersionUID = -9034759294980218927L; public WatsonFunction(int n, double x0, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(31, buildArray(n, x0), theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double[][] jacobian = new double[m][]; for (int i = 0; i < (m - 2); ++i) { double div = (i + 1) / 29.0; double s2 = 0.0; double dx = 1.0; for (int j = 0; j < n; ++j) { s2 += dx * variables[j]; dx *= div; } double temp= 2 * div * s2; dx = 1.0 / div; jacobian[i] = new double[n]; for (int j = 0; j < n; ++j) { jacobian[i][j] = dx * (j - temp); dx *= div; } } jacobian[m - 2] = new double[n]; jacobian[m - 2][0] = 1; jacobian[m - 1] = new double[n]; jacobian[m - 1][0]= -2 * variables[0]; jacobian[m - 1][1]= 1; return jacobian; } @Override public double[] value(double[] variables) { double[] f = new double[m]; for (int i = 0; i < (m - 2); ++i) { double div = (i + 1) / 29.0; double s1 = 0; double dx = 1; for (int j = 1; j < n; ++j) { s1 += j * dx * variables[j]; dx *= div; } double s2 =0; dx =1; for (int j = 0; j < n; ++j) { s2 += dx * variables[j]; dx *= div; } f[i] = s1 - s2 * s2 - 1; } double x1 = variables[0]; double x2 = variables[1]; f[m - 2] = x1; f[m - 1] = x2 - x1 * x1 - 1; return f; } } private static class Box3DimensionalFunction extends MinpackFunction { private static final long serialVersionUID = 5511403858142574493L; public Box3DimensionalFunction(int m, double[] startParams, double theoreticalStartCost) { super(m, startParams, 0.0, new double[] { 1.0, 10.0, 1.0 }); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double tmp = (i + 1) / 10.0; jacobian[i] = new double[] { -tmp * FastMath.exp(-tmp * x1), tmp * FastMath.exp(-tmp * x2), FastMath.exp(-i - 1) - FastMath.exp(-tmp) }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double tmp = (i + 1) / 10.0; f[i] = FastMath.exp(-tmp * x1) - FastMath.exp(-tmp * x2) + (FastMath.exp(-i - 1) - FastMath.exp(-tmp)) * x3; } return f; } } private static class JennrichSampsonFunction extends MinpackFunction { private static final long serialVersionUID = -2489165190443352947L; public JennrichSampsonFunction(int m, double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, startParams, theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double t = i + 1; jacobian[i] = new double[] { -t * FastMath.exp(t * x1), -t * FastMath.exp(t * x2) }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = i + 1; f[i] = 2 + 2 * temp - FastMath.exp(temp * x1) - FastMath.exp(temp * x2); } return f; } } private static class BrownDennisFunction extends MinpackFunction { private static final long serialVersionUID = 8340018645694243910L; public BrownDennisFunction(int m, double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, startParams, theoreticalMinCost, theoreticalMinParams); setCostAccuracy(2.5e-8); } @Override public double[][] jacobian(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = (i + 1) / 5.0; double ti = FastMath.sin(temp); double tmp1 = x1 + temp * x2 - FastMath.exp(temp); double tmp2 = x3 + ti * x4 - FastMath.cos(temp); jacobian[i] = new double[] { 2 * tmp1, 2 * temp * tmp1, 2 * tmp2, 2 * ti * tmp2 }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = (i + 1) / 5.0; double tmp1 = x1 + temp * x2 - FastMath.exp(temp); double tmp2 = x3 + FastMath.sin(temp) * x4 - FastMath.cos(temp); f[i] = tmp1 * tmp1 + tmp2 * tmp2; } return f; } } private static class ChebyquadFunction extends MinpackFunction { private static final long serialVersionUID = -2394877275028008594L; private static double[] buildChebyquadArray(int n, double factor) { double[] array = new double[n]; double inv = factor / (n + 1); for (int i = 0; i < n; ++i) { array[i] = (i + 1) * inv; } return array; } public ChebyquadFunction(int n, int m, double factor, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, buildChebyquadArray(n, factor), theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; } double dx = 1.0 / n; for (int j = 0; j < n; ++j) { double tmp1 = 1; double tmp2 = 2 * variables[j] - 1; double temp = 2 * tmp2; double tmp3 = 0; double tmp4 = 2; for (int i = 0; i < m; ++i) { jacobian[i][j] = dx * tmp4; double ti = 4 * tmp2 + temp * tmp4 - tmp3; tmp3 = tmp4; tmp4 = ti; ti = temp * tmp2 - tmp1; tmp1 = tmp2; tmp2 = ti; } } return jacobian; } @Override public double[] value(double[] variables) { double[] f = new double[m]; for (int j = 0; j < n; ++j) { double tmp1 = 1; double tmp2 = 2 * variables[j] - 1; double temp = 2 * tmp2; for (int i = 0; i < m; ++i) { f[i] += tmp2; double ti = temp * tmp2 - tmp1; tmp1 = tmp2; tmp2 = ti; } } double dx = 1.0 / n; boolean iev = false; for (int i = 0; i < m; ++i) { f[i] *= dx; if (iev) { f[i] += 1.0 / (i * (i + 2)); } iev = ! iev; } return f; } } private static class BrownAlmostLinearFunction extends MinpackFunction { private static final long serialVersionUID = 8239594490466964725L; public BrownAlmostLinearFunction(int m, double factor, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(m, buildArray(m, factor), theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { jacobian[i] = new double[n]; } double prod = 1; for (int j = 0; j < n; ++j) { prod *= variables[j]; for (int i = 0; i < n; ++i) { jacobian[i][j] = 1; } jacobian[j][j] = 2; } for (int j = 0; j < n; ++j) { double temp = variables[j]; if (temp == 0) { temp = 1; prod = 1; for (int k = 0; k < n; ++k) { if (k != j) { prod *= variables[k]; } } } jacobian[n - 1][j] = prod / temp; } return jacobian; } @Override public double[] value(double[] variables) { double[] f = new double[m]; double sum = -(n + 1); double prod = 1; for (int j = 0; j < n; ++j) { sum += variables[j]; prod *= variables[j]; } for (int i = 0; i < n; ++i) { f[i] = variables[i] + sum; } f[n - 1] = prod - 1; return f; } } private static class Osborne1Function extends MinpackFunction { private static final long serialVersionUID = 4006743521149849494L; public Osborne1Function(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(33, startParams, theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double x5 = variables[4]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = 10.0 * i; double tmp1 = FastMath.exp(-temp * x4); double tmp2 = FastMath.exp(-temp * x5); jacobian[i] = new double[] { -1, -tmp1, -tmp2, temp * x2 * tmp1, temp * x3 * tmp2 }; } return jacobian; } @Override public double[] value(double[] variables) { double x1 = variables[0]; double x2 = variables[1]; double x3 = variables[2]; double x4 = variables[3]; double x5 = variables[4]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = 10.0 * i; double tmp1 = FastMath.exp(-temp * x4); double tmp2 = FastMath.exp(-temp * x5); f[i] = y[i] - (x1 + x2 * tmp1 + x3 * tmp2); } return f; } private static final double[] y = { 0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818, 0.784, 0.751, 0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506, 0.490, 0.478, 0.467, 0.457, 0.448, 0.438, 0.431, 0.424, 0.420, 0.414, 0.411, 0.406 }; } private static class Osborne2Function extends MinpackFunction { private static final long serialVersionUID = -8418268780389858746L; public Osborne2Function(double[] startParams, double theoreticalStartCost, double theoreticalMinCost, double[] theoreticalMinParams) { super(65, startParams, theoreticalMinCost, theoreticalMinParams); } @Override public double[][] jacobian(double[] variables) { double x01 = variables[0]; double x02 = variables[1]; double x03 = variables[2]; double x04 = variables[3]; double x05 = variables[4]; double x06 = variables[5]; double x07 = variables[6]; double x08 = variables[7]; double x09 = variables[8]; double x10 = variables[9]; double x11 = variables[10]; double[][] jacobian = new double[m][]; for (int i = 0; i < m; ++i) { double temp = i / 10.0; double tmp1 = FastMath.exp(-x05 * temp); double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09)); double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10)); double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11)); jacobian[i] = new double[] { -tmp1, -tmp2, -tmp3, -tmp4, temp * x01 * tmp1, x02 * (temp - x09) * (temp - x09) * tmp2, x03 * (temp - x10) * (temp - x10) * tmp3, x04 * (temp - x11) * (temp - x11) * tmp4, -2 * x02 * x06 * (temp - x09) * tmp2, -2 * x03 * x07 * (temp - x10) * tmp3, -2 * x04 * x08 * (temp - x11) * tmp4 }; } return jacobian; } @Override public double[] value(double[] variables) { double x01 = variables[0]; double x02 = variables[1]; double x03 = variables[2]; double x04 = variables[3]; double x05 = variables[4]; double x06 = variables[5]; double x07 = variables[6]; double x08 = variables[7]; double x09 = variables[8]; double x10 = variables[9]; double x11 = variables[10]; double[] f = new double[m]; for (int i = 0; i < m; ++i) { double temp = i / 10.0; double tmp1 = FastMath.exp(-x05 * temp); double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09)); double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10)); double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11)); f[i] = y[i] - (x01 * tmp1 + x02 * tmp2 + x03 * tmp3 + x04 * tmp4); } return f; } private static final double[] y = { 1.366, 1.191, 1.112, 1.013, 0.991, 0.885, 0.831, 0.847, 0.786, 0.725, 0.746, 0.679, 0.608, 0.655, 0.616, 0.606, 0.602, 0.626, 0.651, 0.724, 0.649, 0.649, 0.694, 0.644, 0.624, 0.661, 0.612, 0.558, 0.533, 0.495, 0.500, 0.423, 0.395, 0.375, 0.372, 0.391, 0.396, 0.405, 0.428, 0.429, 0.523, 0.562, 0.607, 0.653, 0.672, 0.708, 0.633, 0.668, 0.645, 0.632, 0.591, 0.559, 0.597, 0.625, 0.739, 0.710, 0.729, 0.720, 0.636, 0.581, 0.428, 0.292, 0.162, 0.098, 0.054 }; } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer100644 1750 1750 64375 11532241241 32700 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import java.awt.geom.Point2D; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import junit.framework.TestCase; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.SimpleVectorialPointChecker; import org.apache.commons.math.optimization.SimpleVectorialValueChecker; import org.apache.commons.math.optimization.VectorialPointValuePair; import org.apache.commons.math.util.FastMath; /** *

                Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files. * The redistribution policy for MINPACK is available here, for * convenience, it is reproduced below.

                * * * *
                * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
                * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                  *
                1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
                2. *
                3. 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.
                4. *
                5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
                6. *
                7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
                8. *
                9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
                10. *
                  * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) * @author Burton S. Garbow (original fortran minpack tests) * @author Kenneth E. Hillstrom (original fortran minpack tests) * @author Jorge J. More (original fortran minpack tests) * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) */ public class GaussNewtonOptimizerTest extends TestCase { public GaussNewtonOptimizerTest(String name) { super(name); } public void testTrivial() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 2 } }, new double[] { 3 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(1.5, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getValue()[0], 1.0e-10); } public void testColumnsPermutation() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } }, new double[] { 4.0, 6.0, 1.0 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(7.0, optimum.getPoint()[0], 1.0e-10); assertEquals(3.0, optimum.getPoint()[1], 1.0e-10); assertEquals(4.0, optimum.getValue()[0], 1.0e-10); assertEquals(6.0, optimum.getValue()[1], 1.0e-10); assertEquals(1.0, optimum.getValue()[2], 1.0e-10); } public void testNoDependency() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 2, 0, 0, 0, 0, 0 }, { 0, 2, 0, 0, 0, 0 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 }, { 0, 0, 0, 0, 2, 0 }, { 0, 0, 0, 0, 0, 2 } }, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 }, new double[] { 0, 0, 0, 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); for (int i = 0; i < problem.target.length; ++i) { assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10); } } public void testOneSet() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1, 0, 0 }, { -1, 1, 0 }, { 0, -1, 1 } }, new double[] { 1, 1, 1}); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(1.0, optimum.getPoint()[0], 1.0e-10); assertEquals(2.0, optimum.getPoint()[1], 1.0e-10); assertEquals(3.0, optimum.getPoint()[2], 1.0e-10); } public void testTwoSets() throws FunctionEvaluationException, OptimizationException { double epsilon = 1.0e-7; LinearProblem problem = new LinearProblem(new double[][] { { 2, 1, 0, 4, 0, 0 }, { -4, -2, 3, -7, 0, 0 }, { 4, 1, -2, 8, 0, 0 }, { 0, -3, -12, -1, 0, 0 }, { 0, 0, 0, 0, epsilon, 1 }, { 0, 0, 0, 0, 1, 1 } }, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2}); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 }, new double[] { 0, 0, 0, 0, 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10); assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10); assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10); assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10); assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10); assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10); } public void testNonInversible() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1, 2, -3 }, { 2, 1, 3 }, { -3, 0, -9 } }, new double[] { 1, 1, 1 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); try { optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 }); fail("an exception should have been caught"); } catch (OptimizationException ee) { // expected behavior } } public void testIllConditioned() throws FunctionEvaluationException, OptimizationException { LinearProblem problem1 = new LinearProblem(new double[][] { { 10.0, 7.0, 8.0, 7.0 }, { 7.0, 5.0, 6.0, 5.0 }, { 8.0, 6.0, 10.0, 9.0 }, { 7.0, 5.0, 9.0, 10.0 } }, new double[] { 32, 23, 33, 31 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum1 = optimizer.optimize(problem1, problem1.target, new double[] { 1, 1, 1, 1 }, new double[] { 0, 1, 2, 3 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(1.0, optimum1.getPoint()[0], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[1], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[2], 1.0e-10); assertEquals(1.0, optimum1.getPoint()[3], 1.0e-10); LinearProblem problem2 = new LinearProblem(new double[][] { { 10.00, 7.00, 8.10, 7.20 }, { 7.08, 5.04, 6.00, 5.00 }, { 8.00, 5.98, 9.89, 9.00 }, { 6.99, 4.99, 9.00, 9.98 } }, new double[] { 32, 23, 33, 31 }); VectorialPointValuePair optimum2 = optimizer.optimize(problem2, problem2.target, new double[] { 1, 1, 1, 1 }, new double[] { 0, 1, 2, 3 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-8); assertEquals(137.0, optimum2.getPoint()[1], 1.0e-8); assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-8); assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-8); } public void testMoreEstimatedParametersSimple() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 3.0, 2.0, 0.0, 0.0 }, { 0.0, 1.0, -1.0, 1.0 }, { 2.0, 0.0, 1.0, 0.0 } }, new double[] { 7.0, 3.0, 5.0 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); try { optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 7, 6, 5, 4 }); fail("an exception should have been caught"); } catch (OptimizationException ee) { // expected behavior } } public void testMoreEstimatedParametersUnsorted() throws Exception { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0, 1.0, -1.0 }, { 0.0, 0.0, -1.0, 1.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0, -1.0, 1.0, 0.0 } }, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); try { optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1, 1, 1 }, new double[] { 2, 2, 2, 2, 2, 2 }); fail("an exception should have been caught"); } catch (OptimizationException ee) { // expected behavior } } public void testRedundantEquations() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 5.0 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 1, 1 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(2.0, optimum.getPoint()[0], 1.0e-8); assertEquals(1.0, optimum.getPoint()[1], 1.0e-8); } public void testInconsistentEquations() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1.0, 1.0 }, { 1.0, -1.0 }, { 1.0, 3.0 } }, new double[] { 3.0, 1.0, 4.0 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); optimizer.optimize(problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 1, 1 }); assertTrue(optimizer.getRMS() > 0.1); } public void testInconsistentSizes() throws FunctionEvaluationException, OptimizationException { LinearProblem problem = new LinearProblem(new double[][] { { 1, 0 }, { 0, 1 } }, new double[] { -1, 1 }); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); VectorialPointValuePair optimum = optimizer.optimize(problem, problem.target, new double[] { 1, 1 }, new double[] { 0, 0 }); assertEquals(0, optimizer.getRMS(), 1.0e-10); assertEquals(-1, optimum.getPoint()[0], 1.0e-10); assertEquals(+1, optimum.getPoint()[1], 1.0e-10); try { optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0, 0 }); fail("an exception should have been thrown"); } catch (OptimizationException oe) { // expected behavior } try { optimizer.optimize(problem, new double[] { 1 }, new double[] { 1 }, new double[] { 0, 0 }); fail("an exception should have been thrown"); } catch (FunctionEvaluationException oe) { // expected behavior } } public void testMaxEvaluations() throws Exception { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialPointChecker(1.0e-30, 1.0e-30)); try { optimizer.optimize(circle, new double[] { 0, 0, 0, 0, 0 }, new double[] { 1, 1, 1, 1, 1 }, new double[] { 98.680, 47.345 }); fail("an exception should have been caught"); } catch (OptimizationException ee) { // expected behavior } } public void testCircleFitting() throws FunctionEvaluationException, OptimizationException { Circle circle = new Circle(); circle.addPoint( 30.0, 68.0); circle.addPoint( 50.0, -6.0); circle.addPoint(110.0, -20.0); circle.addPoint( 35.0, 15.0); circle.addPoint( 45.0, 97.0); GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-13, 1.0e-13)); VectorialPointValuePair optimum = optimizer.optimize(circle, new double[] { 0, 0, 0, 0, 0 }, new double[] { 1, 1, 1, 1, 1 }, new double[] { 98.680, 47.345 }); assertEquals(1.768262623567235, FastMath.sqrt(circle.getN()) * optimizer.getRMS(), 1.0e-10); Point2D.Double center = new Point2D.Double(optimum.getPointRef()[0], optimum.getPointRef()[1]); assertEquals(69.96016175359975, circle.getRadius(center), 1.0e-10); assertEquals(96.07590209601095, center.x, 1.0e-10); assertEquals(48.135167894714, center.y, 1.0e-10); } public void testCircleFittingBadInit() throws FunctionEvaluationException, OptimizationException { Circle circle = new Circle(); double[][] points = new double[][] { {-0.312967, 0.072366}, {-0.339248, 0.132965}, {-0.379780, 0.202724}, {-0.390426, 0.260487}, {-0.361212, 0.328325}, {-0.346039, 0.392619}, {-0.280579, 0.444306}, {-0.216035, 0.470009}, {-0.149127, 0.493832}, {-0.075133, 0.483271}, {-0.007759, 0.452680}, { 0.060071, 0.410235}, { 0.103037, 0.341076}, { 0.118438, 0.273884}, { 0.131293, 0.192201}, { 0.115869, 0.129797}, { 0.072223, 0.058396}, { 0.022884, 0.000718}, {-0.053355, -0.020405}, {-0.123584, -0.032451}, {-0.216248, -0.032862}, {-0.278592, -0.005008}, {-0.337655, 0.056658}, {-0.385899, 0.112526}, {-0.405517, 0.186957}, {-0.415374, 0.262071}, {-0.387482, 0.343398}, {-0.347322, 0.397943}, {-0.287623, 0.458425}, {-0.223502, 0.475513}, {-0.135352, 0.478186}, {-0.061221, 0.483371}, { 0.003711, 0.422737}, { 0.065054, 0.375830}, { 0.108108, 0.297099}, { 0.123882, 0.222850}, { 0.117729, 0.134382}, { 0.085195, 0.056820}, { 0.029800, -0.019138}, {-0.027520, -0.072374}, {-0.102268, -0.091555}, {-0.200299, -0.106578}, {-0.292731, -0.091473}, {-0.356288, -0.051108}, {-0.420561, 0.014926}, {-0.471036, 0.074716}, {-0.488638, 0.182508}, {-0.485990, 0.254068}, {-0.463943, 0.338438}, {-0.406453, 0.404704}, {-0.334287, 0.466119}, {-0.254244, 0.503188}, {-0.161548, 0.495769}, {-0.075733, 0.495560}, { 0.001375, 0.434937}, { 0.082787, 0.385806}, { 0.115490, 0.323807}, { 0.141089, 0.223450}, { 0.138693, 0.131703}, { 0.126415, 0.049174}, { 0.066518, -0.010217}, {-0.005184, -0.070647}, {-0.080985, -0.103635}, {-0.177377, -0.116887}, {-0.260628, -0.100258}, {-0.335756, -0.056251}, {-0.405195, -0.000895}, {-0.444937, 0.085456}, {-0.484357, 0.175597}, {-0.472453, 0.248681}, {-0.438580, 0.347463}, {-0.402304, 0.422428}, {-0.326777, 0.479438}, {-0.247797, 0.505581}, {-0.152676, 0.519380}, {-0.071754, 0.516264}, { 0.015942, 0.472802}, { 0.076608, 0.419077}, { 0.127673, 0.330264}, { 0.159951, 0.262150}, { 0.153530, 0.172681}, { 0.140653, 0.089229}, { 0.078666, 0.024981}, { 0.023807, -0.037022}, {-0.048837, -0.077056}, {-0.127729, -0.075338}, {-0.221271, -0.067526} }; double[] target = new double[points.length]; Arrays.fill(target, 0.0); double[] weights = new double[points.length]; Arrays.fill(weights, 2.0); for (int i = 0; i < points.length; ++i) { circle.addPoint(points[i][0], points[i][1]); } GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer(true); optimizer.setMaxIterations(100); optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6)); try { optimizer.optimize(circle, target, weights, new double[] { -12, -12 }); fail("an exception should have been caught"); } catch (OptimizationException ee) { // expected behavior } VectorialPointValuePair optimum = optimizer.optimize(circle, target, weights, new double[] { 0, 0 }); assertEquals(-0.1517383071957963, optimum.getPointRef()[0], 1.0e-6); assertEquals(0.2074999736353867, optimum.getPointRef()[1], 1.0e-6); assertEquals(0.04268731682389561, optimizer.getRMS(), 1.0e-8); } private static class LinearProblem implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = -8804268799379350190L; final RealMatrix factors; final double[] target; public LinearProblem(double[][] factors, double[] target) { this.factors = new BlockRealMatrix(factors); this.target = target; } public double[] value(double[] variables) { return factors.operate(variables); } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -8387467946663627585L; public double[][] value(double[] point) { return factors.getData(); } }; } } private static class Circle implements DifferentiableMultivariateVectorialFunction, Serializable { private static final long serialVersionUID = -7165774454925027042L; private ArrayList points; public Circle() { points = new ArrayList(); } public void addPoint(double px, double py) { points.add(new Point2D.Double(px, py)); } public int getN() { return points.size(); } public double getRadius(Point2D.Double center) { double r = 0; for (Point2D.Double point : points) { r += point.distance(center); } return r / points.size(); } private double[][] jacobian(double[] variables) { int n = points.size(); Point2D.Double center = new Point2D.Double(variables[0], variables[1]); // gradient of the optimal radius double dRdX = 0; double dRdY = 0; for (Point2D.Double pk : points) { double dk = pk.distance(center); dRdX += (center.x - pk.x) / dk; dRdY += (center.y - pk.y) / dk; } dRdX /= n; dRdY /= n; // jacobian of the radius residuals double[][] jacobian = new double[n][2]; for (int i = 0; i < n; ++i) { Point2D.Double pi = points.get(i); double di = pi.distance(center); jacobian[i][0] = (center.x - pi.x) / di - dRdX; jacobian[i][1] = (center.y - pi.y) / di - dRdY; } return jacobian; } public double[] value(double[] variables) { Point2D.Double center = new Point2D.Double(variables[0], variables[1]); double radius = getRadius(center); double[] residuals = new double[points.size()]; for (int i = 0; i < residuals.length; ++i) { residuals[i] = points.get(i).distance(center) - radius; } return residuals; } public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { private static final long serialVersionUID = -4340046230875165095L; public double[][] value(double[] point) { return jacobian(point); } }; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblemHandler.java100644 1750 1750 12116 11532241242 27565 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ODEIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** * This class is used to handle steps for the test problems * integrated during the junit tests for the ODE integrators. */ public class TestProblemHandler implements StepHandler { /** Associated problem. */ private TestProblemAbstract problem; /** Maximal errors encountered during the integration. */ private double maxValueError; private double maxTimeError; /** Error at the end of the integration. */ private double lastError; /** Time at the end of integration. */ private double lastTime; /** ODE solver used. */ private ODEIntegrator integrator; /** Expected start for step. */ private double expectedStepStart; /** * Simple constructor. * @param problem problem for which steps should be handled * @param integrator ODE solver used */ public TestProblemHandler(TestProblemAbstract problem, ODEIntegrator integrator) { this.problem = problem; this.integrator = integrator; reset(); } public boolean requiresDenseOutput() { return true; } public void reset() { maxValueError = 0; maxTimeError = 0; lastError = 0; expectedStepStart = Double.NaN; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { double start = integrator.getCurrentStepStart(); if (FastMath.abs((start - problem.getInitialTime()) / integrator.getCurrentSignedStepsize()) > 0.001) { // multistep integrators do not handle the first steps themselves // so we have to make sure the integrator we look at has really started its work if (!Double.isNaN(expectedStepStart)) { // the step should either start at the end of the integrator step // or at an event if the step is split into several substeps double stepError = FastMath.max(maxTimeError, FastMath.abs(start - expectedStepStart)); for (double eventTime : problem.getTheoreticalEventsTimes()) { stepError = FastMath.min(stepError, FastMath.abs(start - eventTime)); } maxTimeError = FastMath.max(maxTimeError, stepError); } expectedStepStart = start + integrator.getCurrentSignedStepsize(); } double pT = interpolator.getPreviousTime(); double cT = interpolator.getCurrentTime(); double[] errorScale = problem.getErrorScale(); // store the error at the last step if (isLast) { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = problem.computeTheoreticalState(cT); for (int i = 0; i < interpolatedY.length; ++i) { double error = FastMath.abs(interpolatedY[i] - theoreticalY[i]); lastError = FastMath.max(error, lastError); } lastTime = cT; } // walk through the step for (int k = 0; k <= 20; ++k) { double time = pT + (k * (cT - pT)) / 20; interpolator.setInterpolatedTime(time); double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = problem.computeTheoreticalState(interpolator.getInterpolatedTime()); // update the errors for (int i = 0; i < interpolatedY.length; ++i) { double error = errorScale[i] * FastMath.abs(interpolatedY[i] - theoreticalY[i]); maxValueError = FastMath.max(error, maxValueError); } } } /** * Get the maximal value error encountered during integration. * @return maximal value error */ public double getMaximalValueError() { return maxValueError; } /** * Get the maximal time error encountered during integration. * @return maximal time error */ public double getMaximalTimeError() { return maxTimeError; } /** * Get the error at the end of the integration. * @return error at the end of the integration */ public double getLastError() { return lastError; } /** * Get the time at the end of the integration. * @return time at the end of the integration. */ public double getLastTime() { return lastTime; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem2.java100644 1750 1750 4567 11532241242 26344 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *

                  This specific problem is the following differential equation : *

                   *    y' = t^3 - t y
                   * 
                  * with the initial condition y (0) = 0. The solution of this equation * is the following function : *
                   *   y (t) = t^2 + 2 (exp (- t^2 / 2) - 1)
                   * 
                  *

                  */ public class TestProblem2 extends TestProblemAbstract { /** Serializable version identifier. */ private static final long serialVersionUID = 8330741783213512366L; /** theoretical state */ private double[] y; /** * Simple constructor. */ public TestProblem2() { super(); double[] y0 = { 0.0 }; setInitialConditions(0.0, y0); setFinalConditions(1.0); double[] errorScale = { 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem2(TestProblem2 problem) { super(problem); y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem2 copy() { return new TestProblem2(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // compute the derivatives for (int i = 0; i < n; ++i) yDot[i] = t * (t * t - y[i]); } @Override public double[] computeTheoreticalState(double t) { double t2 = t * t; double c = t2 + 2 * (FastMath.exp (-0.5 * t2) - 1); for (int i = 0; i < n; ++i) { y[i] = c; } return y; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem5.java100644 1750 1750 2554 11532241242 26341 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** * This class is used in the junit tests for the ODE integrators. *

                  This is the same as problem 1 except integration is done * backward in time

                  */ public class TestProblem5 extends TestProblem1 { /** Serializable version identifier. */ private static final long serialVersionUID = 7579233102411804237L; /** * Simple constructor. */ public TestProblem5() { super(); setFinalConditions(2 * t0 - t1); } /** {@inheritDoc} */ @Override public TestProblem5 copy() { return new TestProblem5(); } } ././@LongLink100644 0 0 164 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJac100644 1750 1750 45171 11532241242 32443 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; @Deprecated public class FirstOrderIntegratorWithJacobiansTest { @Test public void testLowAccuracyExternalDifferentiation() throws IntegratorException, DerivativeException { // this test does not really test FirstOrderIntegratorWithJacobians, // it only shows that WITHOUT this class, attempting to recover // the jacobians from external differentiation on simple integration // results with low accuracy gives very poor results. In fact, // the curves dy/dp = g(b) when b varies from 2.88 to 3.08 are // essentially noise. // This test is taken from Hairer, Norsett and Wanner book // Solving Ordinary Differential Equations I (Nonstiff problems), // the curves dy/dp = g(b) are in figure 6.5 FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); double hP = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); double[] y = { 1.3, b }; integ.integrate(brusselator, 0, y, 20.0, y); double[] yP = { 1.3, b + hP }; brusselator.setParameter(0, b + hP); integ.integrate(brusselator, 0, yP, 20.0, yP); residualsP0.addValue((yP[0] - y[0]) / hP - brusselator.dYdP0()); residualsP1.addValue((yP[1] - y[1]) / hP - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) > 600); Assert.assertTrue(residualsP0.getStandardDeviation() > 30); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) > 800); Assert.assertTrue(residualsP1.getStandardDeviation() > 50); } @Test public void testHighAccuracyExternalDifferentiation() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double hP = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); double[] y = { 1.3, b }; integ.integrate(brusselator, 0, y, 20.0, y); double[] yP = { 1.3, b + hP }; brusselator.setParameter(0, b + hP); integ.integrate(brusselator, 0, yP, 20.0, yP); residualsP0.addValue((yP[0] - y[0]) / hP - brusselator.dYdP0()); residualsP1.addValue((yP[1] - y[1]) / hP - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) > 0.02); Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.03); Assert.assertTrue(residualsP0.getStandardDeviation() > 0.003); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.004); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) > 0.04); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() > 0.007); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.008); } @Test public void testInternalDifferentiation() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); double hP = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); brusselator.setParameter(0, b); double[] z = { 1.3, b }; double[][] dZdZ0 = new double[2][2]; double[][] dZdP = new double[2][1]; double hY = 1.0e-12; FirstOrderIntegratorWithJacobians extInt = new FirstOrderIntegratorWithJacobians(integ, brusselator, new double[] { b }, new double[] { hY, hY }, new double[] { hP }); extInt.setMaxEvaluations(5000); extInt.integrate(0, z, new double[][] { { 0.0 }, { 1.0 } }, 20.0, z, dZdZ0, dZdP); Assert.assertEquals(5000, extInt.getMaxEvaluations()); Assert.assertTrue(extInt.getEvaluations() > 1400); Assert.assertTrue(extInt.getEvaluations() < 2000); Assert.assertEquals(4 * integ.getEvaluations(), extInt.getEvaluations()); residualsP0.addValue(dZdP[0][0] - brusselator.dYdP0()); residualsP1.addValue(dZdP[1][0] - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.02); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.003); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.01); } @Test public void testAnalyticalDifferentiation() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); brusselator.setParameter(0, b); double[] z = { 1.3, b }; double[][] dZdZ0 = new double[2][2]; double[][] dZdP = new double[2][1]; FirstOrderIntegratorWithJacobians extInt = new FirstOrderIntegratorWithJacobians(integ, brusselator); extInt.setMaxEvaluations(5000); extInt.integrate(0, z, new double[][] { { 0.0 }, { 1.0 } }, 20.0, z, dZdZ0, dZdP); Assert.assertEquals(5000, extInt.getMaxEvaluations()); Assert.assertTrue(extInt.getEvaluations() > 350); Assert.assertTrue(extInt.getEvaluations() < 510); Assert.assertEquals(integ.getEvaluations(), extInt.getEvaluations()); residualsP0.addValue(dZdP[0][0] - brusselator.dYdP0()); residualsP1.addValue(dZdP[1][0] - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.014); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.003); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.01); } @Test public void testFinalResult() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double[] y = new double[] { 0.0, 1.0 }; Circle circle = new Circle(y, 1.0, 1.0, 0.1); double[][] dydy0 = new double[2][2]; double[][] dydp = new double[2][3]; double t = 18 * FastMath.PI; FirstOrderIntegratorWithJacobians extInt = new FirstOrderIntegratorWithJacobians(integ, circle); extInt.integrate(0, y, circle.exactDyDp(0), t, y, dydy0, dydp); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(circle.exactY(t)[i], y[i], 1.0e-9); } for (int i = 0; i < dydy0.length; ++i) { for (int j = 0; j < dydy0[i].length; ++j) { Assert.assertEquals(circle.exactDyDy0(t)[i][j], dydy0[i][j], 1.0e-9); } } for (int i = 0; i < dydp.length; ++i) { for (int j = 0; j < dydp[i].length; ++j) { Assert.assertEquals(circle.exactDyDp(t)[i][j], dydp[i][j], 1.0e-7); } } } @Test public void testStepHandlerResult() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double[] y = new double[] { 0.0, 1.0 }; final Circle circle = new Circle(y, 1.0, 1.0, 0.1); double[][] dydy0 = new double[2][2]; double[][] dydp = new double[2][3]; double t = 18 * FastMath.PI; final FirstOrderIntegratorWithJacobians extInt = new FirstOrderIntegratorWithJacobians(integ, circle); extInt.addStepHandler(new StepHandlerWithJacobians() { public void reset() { } public boolean requiresDenseOutput() { return false; } public void handleStep(StepInterpolatorWithJacobians interpolator, boolean isLast) throws DerivativeException { double t = interpolator.getCurrentTime(); double[] y = interpolator.getInterpolatedY(); double[][] dydy0 = interpolator.getInterpolatedDyDy0(); double[][] dydp = interpolator.getInterpolatedDyDp(); Assert.assertEquals(interpolator.getPreviousTime(), extInt.getCurrentStepStart(), 1.0e-10); Assert.assertTrue(extInt.getCurrentSignedStepsize() < 0.5); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(circle.exactY(t)[i], y[i], 1.0e-9); } for (int i = 0; i < dydy0.length; ++i) { for (int j = 0; j < dydy0[i].length; ++j) { Assert.assertEquals(circle.exactDyDy0(t)[i][j], dydy0[i][j], 1.0e-9); } } for (int i = 0; i < dydp.length; ++i) { for (int j = 0; j < dydp[i].length; ++j) { Assert.assertEquals(circle.exactDyDp(t)[i][j], dydp[i][j], 3.0e-8); } } double[] yDot = interpolator.getInterpolatedYDot(); double[][] dydy0Dot = interpolator.getInterpolatedDyDy0Dot(); double[][] dydpDot = interpolator.getInterpolatedDyDpDot(); for (int i = 0; i < yDot.length; ++i) { Assert.assertEquals(circle.exactYDot(t)[i], yDot[i], 1.0e-10); } for (int i = 0; i < dydy0Dot.length; ++i) { for (int j = 0; j < dydy0Dot[i].length; ++j) { Assert.assertEquals(circle.exactDyDy0Dot(t)[i][j], dydy0Dot[i][j], 1.0e-10); } } for (int i = 0; i < dydpDot.length; ++i) { for (int j = 0; j < dydpDot[i].length; ++j) { Assert.assertEquals(circle.exactDyDpDot(t)[i][j], dydpDot[i][j], 3.0e-9); } } } }); extInt.integrate(0, y, circle.exactDyDp(0), t, y, dydy0, dydp); } @Test public void testEventHandler() throws IntegratorException, DerivativeException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double[] y = new double[] { 0.0, 1.0 }; final Circle circle = new Circle(y, 1.0, 1.0, 0.1); double[][] dydy0 = new double[2][2]; double[][] dydp = new double[2][3]; double t = 18 * FastMath.PI; final FirstOrderIntegratorWithJacobians extInt = new FirstOrderIntegratorWithJacobians(integ, circle); extInt.addEventHandler(new EventHandlerWithJacobians() { public int eventOccurred(double t, double[] y, double[][] dydy0, double[][] dydp, boolean increasing) { Assert.assertEquals(0.1, y[1], 1.0e-11); Assert.assertTrue(!increasing); return STOP; } public double g(double t, double[] y, double[][] dydy0, double[][] dydp) { return y[1] - 0.1; } public void resetState(double t, double[] y, double[][] dydy0, double[][] dydp) { } }, 10.0, 1.0e-10, 1000); double stopTime = extInt.integrate(0, y, circle.exactDyDp(0), t, y, dydy0, dydp); Assert.assertTrue(stopTime < 5.0 * FastMath.PI); } private static class Brusselator implements ParameterizedODE, ODEWithJacobians { private double b; public Brusselator(double b) { this.b = b; } public int getDimension() { return 2; } public void setParameter(int i, double p) { b = p; } public int getParametersDimension() { return 1; } public void computeDerivatives(double t, double[] y, double[] yDot) { double prod = y[0] * y[0] * y[1]; yDot[0] = 1 + prod - (b + 1) * y[0]; yDot[1] = b * y[0] - prod; } public void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) { double p = 2 * y[0] * y[1]; double y02 = y[0] * y[0]; dFdY[0][0] = p - (1 + b); dFdY[0][1] = y02; dFdY[1][0] = b - p; dFdY[1][1] = -y02; dFdP[0][0] = -y[0]; dFdP[1][0] = y[0]; } public double dYdP0() { return -1088.232716447743 + (1050.775747149553 + (-339.012934631828 + 36.52917025056327 * b) * b) * b; } public double dYdP1() { return 1502.824469929139 + (-1438.6974831849952 + (460.959476642384 - 49.43847385647082 * b) * b) * b; } } /** ODE representing a point moving on a circle with provided center and angular rate. */ private static class Circle implements ODEWithJacobians { private final double[] y0; private double cx; private double cy; private double omega; public Circle(double[] y0, double cx, double cy, double omega) { this.y0 = y0.clone(); this.cx = cx; this.cy = cy; this.omega = omega; } public int getDimension() { return 2; } public int getParametersDimension() { return 3; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (cy - y[1]); yDot[1] = omega * (y[0] - cx); } public void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) { dFdY[0][0] = 0; dFdY[0][1] = -omega; dFdY[1][0] = omega; dFdY[1][1] = 0; dFdP[0][0] = 0; dFdP[0][1] = omega; dFdP[0][2] = cy - y[1]; dFdP[1][0] = -omega; dFdP[1][1] = 0; dFdP[1][2] = y[0] - cx; } public double[] exactY(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { cx + cos * dx0 - sin * dy0, cy + sin * dx0 + cos * dy0 }; } public double[][] exactDyDy0(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[][] { { cos, -sin }, { sin, cos } }; } public double[][] exactDyDp(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[][] { { 1 - cos, sin, -t * (sin * dx0 + cos * dy0) }, { -sin, 1 - cos, t * (cos * dx0 - sin * dy0) } }; } public double[] exactYDot(double t) { double oCos = omega * FastMath.cos(omega * t); double oSin = omega * FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { -oSin * dx0 - oCos * dy0, oCos * dx0 - oSin * dy0 }; } public double[][] exactDyDy0Dot(double t) { double oCos = omega * FastMath.cos(omega * t); double oSin = omega * FastMath.sin(omega * t); return new double[][] { { -oSin, -oCos }, { oCos, -oSin } }; } public double[][] exactDyDpDot(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double oCos = omega * cos; double oSin = omega * sin; double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[][] { { oSin, oCos, -sin * dx0 - cos * dy0 - t * ( oCos * dx0 - oSin * dy0) }, { -oCos, oSin, cos * dx0 - sin * dy0 + t * (-oSin * dx0 - oCos * dy0) } }; } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblemFactory.java100644 1750 1750 2676 11532241242 27611 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** * This class is used in the junit tests for the ODE integrators. */ public class TestProblemFactory { /** Problems pool. */ private static final TestProblemAbstract[] pool = { new TestProblem1(), new TestProblem2(), new TestProblem3(), new TestProblem4(), new TestProblem5(), new TestProblem6() }; /** * Private constructor. * This is a utility class, so there are no instance at all. */ private TestProblemFactory() { } /** * Get the problems. * @return array of problems to solve */ public static TestProblemAbstract[] getProblems() { return pool; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/FirstOrderConverterTest.java100644 1750 1750 7155 11532241242 30631 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderConverter; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.SecondOrderDifferentialEquations; import org.apache.commons.math.ode.nonstiff.ClassicalRungeKuttaIntegrator; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class FirstOrderConverterTest extends TestCase { public FirstOrderConverterTest(String name) { super(name); } public void testDoubleDimension() { for (int i = 1; i < 10; ++i) { SecondOrderDifferentialEquations eqn2 = new Equations(i, 0.2); FirstOrderConverter eqn1 = new FirstOrderConverter(eqn2); assertTrue(eqn1.getDimension() == (2 * eqn2.getDimension())); } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { double previousError = Double.NaN; for (int i = 0; i < 10; ++i) { double step = FastMath.pow(2.0, -(i + 1)); double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, step) - FastMath.sin(4.0); if (i > 0) { assertTrue(FastMath.abs(error) < FastMath.abs(previousError)); } previousError = error; } } public void testSmallStep() throws DerivativeException, IntegratorException { double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 1.0e-4) - FastMath.sin(4.0); assertTrue(FastMath.abs(error) < 1.0e-10); } public void testBigStep() throws DerivativeException, IntegratorException { double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 0.5) - FastMath.sin(4.0); assertTrue(FastMath.abs(error) > 0.1); } private static class Equations implements SecondOrderDifferentialEquations { private int n; private double omega2; public Equations(int n, double omega) { this.n = n; omega2 = omega * omega; } public int getDimension() { return n; } public void computeSecondDerivatives(double t, double[] y, double[] yDot, double[] yDDot) { for (int i = 0; i < n; ++i) { yDDot[i] = -omega2 * y[i]; } } } private double integrateWithSpecifiedStep(double omega, double t0, double t, double step) throws DerivativeException, IntegratorException { double[] y0 = new double[2]; y0[0] = FastMath.sin(omega * t0); y0[1] = omega * FastMath.cos(omega * t0); ClassicalRungeKuttaIntegrator i = new ClassicalRungeKuttaIntegrator(step); double[] y = new double[2]; i.integrate(new FirstOrderConverter(new Equations(1, omega)), t0, y0, t, y); return y[0]; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem1.java100644 1750 1750 4436 11532241242 26336 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *

                  This specific problem is the following differential equation : *

                   *    y' = -y
                   * 
                  * the solution of this equation is a simple exponential function : *
                   *   y (t) = y (t0) exp (t0-t)
                   * 
                  *

                  */ public class TestProblem1 extends TestProblemAbstract { /** Serializable version identifier. */ private static final long serialVersionUID = 1977870815289373164L; /** theoretical state */ private double[] y; /** * Simple constructor. */ public TestProblem1() { super(); double[] y0 = { 1.0, 0.1 }; setInitialConditions(0.0, y0); setFinalConditions(4.0); double[] errorScale = { 1.0, 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem1(TestProblem1 problem) { super(problem); y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem1 copy() { return new TestProblem1(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // compute the derivatives for (int i = 0; i < n; ++i) yDot[i] = -y[i]; } @Override public double[] computeTheoreticalState(double t) { double c = FastMath.exp (t0 - t); for (int i = 0; i < n; ++i) { y[i] = c * y0[i]; } return y; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem3.java100644 1750 1750 6473 11532241242 26343 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *

                  This specific problem is the following differential equation : *

                   *    y1'' = -y1/r^3  y1 (0) = 1-e  y1' (0) = 0
                   *    y2'' = -y2/r^3  y2 (0) = 0    y2' (0) =sqrt((1+e)/(1-e))
                   *    r = sqrt (y1^2 + y2^2), e = 0.9
                   * 
                  * This is a two-body problem in the plane which can be solved by * Kepler's equation *
                   *   y1 (t) = ...
                   * 
                  *

                  */ public class TestProblem3 extends TestProblemAbstract { /** Serializable version identifier. */ private static final long serialVersionUID = 8567328542728919999L; /** Eccentricity */ double e; /** theoretical state */ private double[] y; /** * Simple constructor. * @param e eccentricity */ public TestProblem3(double e) { super(); this.e = e; double[] y0 = { 1 - e, 0, 0, FastMath.sqrt((1+e)/(1-e)) }; setInitialConditions(0.0, y0); setFinalConditions(20.0); double[] errorScale = { 1.0, 1.0, 1.0, 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Simple constructor. */ public TestProblem3() { this(0.1); } /** * Copy constructor. * @param problem problem to copy */ public TestProblem3(TestProblem3 problem) { super(problem); e = problem.e; y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem3 copy() { return new TestProblem3(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // current radius double r2 = y[0] * y[0] + y[1] * y[1]; double invR3 = 1 / (r2 * FastMath.sqrt(r2)); // compute the derivatives yDot[0] = y[2]; yDot[1] = y[3]; yDot[2] = -invR3 * y[0]; yDot[3] = -invR3 * y[1]; } @Override public double[] computeTheoreticalState(double t) { // solve Kepler's equation double E = t; double d = 0; double corr = 999.0; for (int i = 0; (i < 50) && (FastMath.abs(corr) > 1.0e-12); ++i) { double f2 = e * FastMath.sin(E); double f0 = d - f2; double f1 = 1 - e * FastMath.cos(E); double f12 = f1 + f1; corr = f0 * f12 / (f1 * f12 - f0 * f2); d -= corr; E = t + d; } double cosE = FastMath.cos(E); double sinE = FastMath.sin(E); y[0] = cosE - e; y[1] = FastMath.sqrt(1 - e * e) * sinE; y[2] = -sinE / (1 - e * cosE); y[3] = FastMath.sqrt(1 - e * e) * cosE / (1 - e * cosE); return y; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblemAbstract.java100644 1750 1750 10463 11532241242 27756 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.events.EventHandler; /** * This class is used as the base class of the problems that are * integrated during the junit tests for the ODE integrators. */ public abstract class TestProblemAbstract implements FirstOrderDifferentialEquations { /** Serializable version identifier. */ private static final long serialVersionUID = -8521928974502839379L; /** Dimension of the problem. */ protected int n; /** Number of functions calls. */ protected int calls; /** Initial time */ protected double t0; /** Initial state */ protected double[] y0; /** Final time */ protected double t1; /** Error scale */ protected double[] errorScale; /** * Simple constructor. */ protected TestProblemAbstract() { n = 0; calls = 0; t0 = 0; y0 = null; t1 = 0; errorScale = null; } /** * Copy constructor. * @param problem problem to copy */ protected TestProblemAbstract(TestProblemAbstract problem) { n = problem.n; calls = problem.calls; t0 = problem.t0; if (problem.y0 == null) { y0 = null; } else { y0 = problem.y0.clone(); } if (problem.errorScale == null) { errorScale = null; } else { errorScale = problem.errorScale.clone(); } t1 = problem.t1; } /** * Copy operation. * @return a copy of the instance */ public abstract TestProblemAbstract copy(); /** * Set the initial conditions * @param t0 initial time * @param y0 initial state vector */ protected void setInitialConditions(double t0, double[] y0) { calls = 0; n = y0.length; this.t0 = t0; this.y0 = y0.clone(); } /** * Set the final conditions. * @param t1 final time */ protected void setFinalConditions(double t1) { this.t1 = t1; } /** * Set the error scale * @param errorScale error scale */ protected void setErrorScale(double[] errorScale) { this.errorScale = errorScale.clone(); } public int getDimension() { return n; } /** * Get the initial time. * @return initial time */ public double getInitialTime() { return t0; } /** * Get the initial state vector. * @return initial state vector */ public double[] getInitialState() { return y0; } /** * Get the final time. * @return final time */ public double getFinalTime() { return t1; } /** * Get the error scale. * @return error scale */ public double[] getErrorScale() { return errorScale; } /** * Get the events handlers. * @return events handlers */ public EventHandler[] getEventsHandlers() { return new EventHandler[0]; } /** * Get the theoretical events times. * @return theoretical events times */ public double[] getTheoreticalEventsTimes() { return new double[0]; } /** * Get the number of calls. * @return nuber of calls */ public int getCalls() { return calls; } public void computeDerivatives(double t, double[] y, double[] yDot) { ++calls; doComputeDerivatives(t, y, yDot); } abstract public void doComputeDerivatives(double t, double[] y, double[] yDot); /** * Compute the theoretical state at the specified time. * @param t time at which the state is required * @return state vector at time t */ abstract public double[] computeTheoreticalState(double t); } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTes100644 1750 1750 32154 11532241242 32352 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem4; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class DormandPrince54IntegratorTest extends TestCase { public DormandPrince54IntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); DormandPrince54Integrator integrator = new DormandPrince54Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testMinStep() { try { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testSmallLastStep() throws DerivativeException, IntegratorException { TestProblemAbstract pb = new TestProblem5(); double minStep = 1.25; double maxStep = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double scalAbsoluteTolerance = 6.0e-4; double scalRelativeTolerance = 6.0e-4; AdaptiveStepsizeIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); DP54SmallLastHandler handler = new DP54SmallLastHandler(minStep); integ.addStepHandler(handler); integ.setInitialStepSize(1.7); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.wasLastSeen()); assertEquals("Dormand-Prince 5(4)", integ.getName()); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-7); assertTrue(handler.getMaximalValueError() < 2.0e-7); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Dormand-Prince 5(4)", integ.getName()); } private static class DP54SmallLastHandler implements StepHandler { public DP54SmallLastHandler(double minStep) { lastSeen = false; this.minStep = minStep; } public boolean requiresDenseOutput() { return false; } public void reset() { } public void handleStep(StepInterpolator interpolator, boolean isLast) { if (isLast) { lastSeen = true; double h = interpolator.getCurrentTime() - interpolator.getPreviousTime(); assertTrue(FastMath.abs(h) < minStep); } } public boolean wasLastSeen() { return lastSeen; } private boolean lastSeen; private double minStep; } public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; EmbeddedRungeKuttaIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.setSafety(0.8); integ.setMaxGrowth(5.0); integ.setMinReduction(0.3); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(0.8, integ.getSafety(), 1.0e-12); assertEquals(5.0, integ.getMaxGrowth(), 1.0e-12); assertEquals(0.3, integ.getMinReduction(), 1.0e-12); // the 0.7 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors assertTrue(handler.getMaximalValueError() < (0.7 * scalAbsoluteTolerance)); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } public void testEvents() throws DerivativeException, IntegratorException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getMaximalValueError() < 5.0e-6); assertEquals(0, handler.getMaximalTimeError(), convergence); assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); assertEquals(0, integ.getEventHandlers().size()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(integ.getEvaluations(), pb.getCalls()); assertTrue(pb.getCalls() < 2800); } public void testVariableSteps() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new VariableHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; reset(); } public boolean requiresDenseOutput() { return true; } public void reset() { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { ++nbSteps; for (int a = 1; a < 10; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((10 - a) * prev + a * curr) / 10; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { assertTrue(maxError < 7.0e-10); assertTrue(nbSteps < 400); } } private int nbSteps; private double maxError; private TestProblem3 pb; } private static class VariableHandler implements StepHandler { public VariableHandler() { firstTime = true; minStep = 0; maxStep = 0; } public boolean requiresDenseOutput() { return false; } public void reset() { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { assertTrue(minStep < (1.0 / 450.0)); assertTrue(maxStep > (1.0 / 4.2)); } } private boolean firstTime; private double minStep; private double maxStep; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java100644 1750 1750 21606 11532241242 31447 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.*; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemFactory; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.GillIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class GillIntegratorTest extends TestCase { public GillIntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); new GillIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 5; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 5) { assertTrue(valueError < FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 5) { assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } public void testSmallStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-13); assertTrue(handler.getMaximalValueError() < 4.0e-12); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Gill", integ.getName()); } public void testBigStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() > 0.0004); assertTrue(handler.getMaximalValueError() > 0.005); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 5.0e-10); assertTrue(handler.getMaximalValueError() < 7.0e-10); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Gill", integ.getName()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new KeplerStepHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } public void testUnstableDerivative() throws DerivativeException, IntegratorException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new GillIntegrator(0.3); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); assertEquals(8.0, y[0], 1.0e-12); } private static class KeplerStepHandler implements StepHandler { public KeplerStepHandler(TestProblem3 pb) { this.pb = pb; reset(); } public boolean requiresDenseOutput() { return false; } public void reset() { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy assertTrue(maxError > 0.001); } } private double maxError; private TestProblem3 pb; } public void testStepSize() throws DerivativeException, IntegratorException { final double step = 1.23456; FirstOrderIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public boolean requiresDenseOutput() { return false; } public void reset() { } }); integ.integrate(new FirstOrderDifferentialEquations() { private static final long serialVersionUID = 0L; public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.100644 1750 1750 21001 11532241242 32433 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.*; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemFactory; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.ThreeEighthesIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class ThreeEighthesIntegratorTest extends TestCase { public ThreeEighthesIntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); new ThreeEighthesIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double error = handler.getMaximalValueError(); if (i > 4) { assertTrue(error < FastMath.abs(previousValueError)); } previousValueError = error; double timeError = handler.getMaximalTimeError(); if (i > 4) { assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } public void testSmallStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-13); assertTrue(handler.getMaximalValueError() < 4.0e-12); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("3/8", integ.getName()); } public void testBigStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() > 0.0004); assertTrue(handler.getMaximalValueError() > 0.005); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 5.0e-10); assertTrue(handler.getMaximalValueError() < 7.0e-10); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("3/8", integ.getName()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; maxError = 0; } public boolean requiresDenseOutput() { return false; } public void reset() { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy assertTrue(maxError > 0.005); } } private TestProblem3 pb; private double maxError = 0; } public void testStepSize() throws DerivativeException, IntegratorException { final double step = 1.23456; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public boolean requiresDenseOutput() { return false; } public void reset() { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTe100644 1750 1750 40443 11532241242 32256 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem4; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator; import org.apache.commons.math.ode.sampling.DummyStepHandler; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class DormandPrince853IntegratorTest extends TestCase { public DormandPrince853IntegratorTest(String name) { super(name); } public void testMissedEndEvent() throws IntegratorException, DerivativeException { final double t0 = 1878250320.0000029; final double tEvent = 1878250379.9999986; final double[] k = { 1.0e-4, 1.0e-5, 1.0e-6 }; FirstOrderDifferentialEquations ode = new FirstOrderDifferentialEquations() { public int getDimension() { return k.length; } public void computeDerivatives(double t, double[] y, double[] yDot) { for (int i = 0; i < y.length; ++i) { yDot[i] = k[i] * y[i]; } } }; DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 100.0, 1.0e-10, 1.0e-10); double[] y0 = new double[k.length]; for (int i = 0; i < y0.length; ++i) { y0[i] = i + 1; } double[] y = new double[k.length]; integrator.setInitialStepSize(60.0); double finalT = integrator.integrate(ode, t0, y0, tEvent, y); Assert.assertEquals(tEvent, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } integrator.setInitialStepSize(60.0); integrator.addEventHandler(new EventHandler() { public void resetState(double t, double[] y) { } public double g(double t, double[] y) { return t - tEvent; } public int eventOccurred(double t, double[] y, boolean increasing) { Assert.assertEquals(tEvent, t, 5.0e-6); return CONTINUE; } }, Double.POSITIVE_INFINITY, 1.0e-20, 100); finalT = integrator.integrate(ode, t0, y0, tEvent + 120, y); Assert.assertEquals(tEvent + 120, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testNullIntervalCheck() { try { TestProblem1 pb = new TestProblem1(); DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testMinStep() { try { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 1.3 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors assertTrue(handler.getMaximalValueError() < (1.3 * scalAbsoluteTolerance)); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 8.1e-8); assertTrue(handler.getMaximalValueError() < 1.1e-7); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Dormand-Prince 8 (5, 3)", integ.getName()); } public void testEvents() throws DerivativeException, IntegratorException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-9; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getMaximalValueError() < 5.0e-8); assertEquals(0, handler.getMaximalTimeError(), convergence); assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); assertEquals(0, integ.getEventHandlers().size()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(integ.getEvaluations(), pb.getCalls()); assertTrue(pb.getCalls() < 3300); } public void testVariableSteps() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new VariableHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); assertEquals("Dormand-Prince 8 (5, 3)", integ.getName()); } public void testNoDenseOutput() throws DerivativeException, IntegratorException { TestProblem1 pb1 = new TestProblem1(); TestProblem1 pb2 = pb1.copy(); double minStep = 0.1 * (pb1.getFinalTime() - pb1.getInitialTime()); double maxStep = pb1.getFinalTime() - pb1.getInitialTime(); double scalAbsoluteTolerance = 1.0e-4; double scalRelativeTolerance = 1.0e-4; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(DummyStepHandler.getInstance()); integ.integrate(pb1, pb1.getInitialTime(), pb1.getInitialState(), pb1.getFinalTime(), new double[pb1.getDimension()]); int callsWithoutDenseOutput = pb1.getCalls(); assertEquals(integ.getEvaluations(), callsWithoutDenseOutput); integ.addStepHandler(new InterpolatingStepHandler()); integ.integrate(pb2, pb2.getInitialTime(), pb2.getInitialState(), pb2.getFinalTime(), new double[pb2.getDimension()]); int callsWithDenseOutput = pb2.getCalls(); assertEquals(integ.getEvaluations(), callsWithDenseOutput); assertTrue(callsWithDenseOutput > callsWithoutDenseOutput); } public void testUnstableDerivative() throws DerivativeException, IntegratorException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new DormandPrince853Integrator(0.1, 10, 1.0e-12, 0.0); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); assertEquals(8.0, y[0], 1.0e-12); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; reset(); } public boolean requiresDenseOutput() { return true; } public void reset() { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { ++nbSteps; for (int a = 1; a < 10; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((10 - a) * prev + a * curr) / 10; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { assertTrue(maxError < 2.4e-10); assertTrue(nbSteps < 150); } } private int nbSteps; private double maxError; private TestProblem3 pb; } private static class VariableHandler implements StepHandler { public VariableHandler() { reset(); } public boolean requiresDenseOutput() { return false; } public void reset() { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { assertTrue(minStep < (1.0 / 100.0)); assertTrue(maxStep > (1.0 / 2.0)); } } private boolean firstTime = true; private double minStep = 0; private double maxStep = 0; } private static class InterpolatingStepHandler implements StepHandler { public boolean requiresDenseOutput() { return true; } public void reset() { } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); interpolator.setInterpolatedTime(0.5*(prev + curr)); } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolatorTest.jav100644 1750 1750 7014 11532241242 32463 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertTrue; import java.util.Random; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.nonstiff.GillIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.junit.Test; public class GillStepInterpolatorTest { @Test public void testDerivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; GillIntegrator integ = new GillIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; GillIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 753000); assertTrue(bos.size () < 754000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 0.003); } } ././@LongLink100644 0 0 162 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpol100644 1750 1750 14504 11532241242 32276 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class DormandPrince853StepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 88000); assertTrue(bos.size () < 89000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 2.4e-10); } @Test public void checklone() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public boolean requiresDenseOutput() { return true; } public void reset() { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpola100644 1750 1750 14602 11532241242 32347 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class DormandPrince54StepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 126000); assertTrue(bos.size () < 127000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 7.0e-10); } @Test public void checkClone() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public boolean requiresDenseOutput() { return true; } public void reset() { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolato100644 1750 1750 6771 11532241242 32534 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.junit.Test; public class ThreeEighthesStepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; ThreeEighthesIntegrator integ = new ThreeEighthesIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; ThreeEighthesIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 753000); assertTrue(bos.size () < 754000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError > 0.005); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/HighamHall54IntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/HighamHall54IntegratorTest.j100644 1750 1750 34156 11532241242 32243 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.TestCase; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem4; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventException; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.util.FastMath; public class HighamHall54IntegratorTest extends TestCase { public HighamHall54IntegratorTest(String name) { super(name); } public void testWrongDerivative() throws Exception { HighamHall54Integrator integrator = new HighamHall54Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); FirstOrderDifferentialEquations equations = new FirstOrderDifferentialEquations() { private static final long serialVersionUID = -1157081786301178032L; public void computeDerivatives(double t, double[] y, double[] dot) throws DerivativeException { if (t < -0.5) { throw new DerivativeException(LocalizedFormats.SIMPLE_MESSAGE, "oops"); } else { throw new DerivativeException(new RuntimeException("oops")); } } public int getDimension() { return 1; } }; try { integrator.integrate(equations, -1.0, new double[1], 0.0, new double[1]); fail("an exception should have been thrown"); } catch(DerivativeException de) { // expected behavior } try { integrator.integrate(equations, 0.0, new double[1], 1.0, new double[1]); fail("an exception should have been thrown"); } catch(DerivativeException de) { // expected behavior } } public void testMinStep() { try { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 1.3 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors assertTrue(handler.getMaximalValueError() < (1.3 * scalAbsoluteTolerance)); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 5.0e-7); assertTrue(handler.getMaximalValueError() < 5.0e-7); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Higham-Hall 5(4)", integ.getName()); } public void testEvents() throws DerivativeException, IntegratorException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getMaximalValueError() < 1.0e-7); assertEquals(0, handler.getMaximalTimeError(), convergence); assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); assertEquals(0, integ.getEventHandlers().size()); } public void testEventsErrors() throws Exception { final TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.addEventHandler(new EventHandler() { public int eventOccurred(double t, double[] y, boolean increasing) { return EventHandler.CONTINUE; } public double g(double t, double[] y) throws EventException { double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2; double offset = t - middle; if (offset > 0) { throw new EventException(LocalizedFormats.EVALUATION_FAILED, t); } return offset; } public void resetState(double t, double[] y) { } private static final long serialVersionUID = 935652725339916361L; }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 1000); try { integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } } public void testEventsNoConvergence() throws Exception { final TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.addEventHandler(new EventHandler() { public int eventOccurred(double t, double[] y, boolean increasing) { return EventHandler.CONTINUE; } public double g(double t, double[] y) { double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2; double offset = t - middle; return (offset > 0) ? (offset + 0.5) : (offset - 0.5); } public void resetState(double t, double[] y) { } private static final long serialVersionUID = 935652725339916361L; }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 3); try { integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { assertTrue(ie.getCause() != null); assertTrue(ie.getCause() instanceof ConvergenceException); } } public void testSanityChecks() throws Exception { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), new double[6], pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[6]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[2], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[2]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getInitialTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch (IntegratorException ie) { // expected behavior } } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-8, 1.0e-8, 1.0e-10, 1.0e-10 }; double[] vecRelativeTolerance = { 1.0e-10, 1.0e-10, 1.0e-8, 1.0e-8 }; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(0.0, handler.getMaximalValueError(), 1.5e-4); assertEquals("Higham-Hall 5(4)", integ.getName()); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator100644 1750 1750 14373 11532241242 32352 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class HighamHall54StepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.1e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 167000); assertTrue(bos.size () < 168000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 1.6e-10); } @Test public void checkClone() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public boolean requiresDenseOutput() { return true; } public void reset() { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolatorTest100644 1750 1750 7022 11532241242 32577 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.junit.Test; public class MidpointStepInterpolatorTest { @Test public void testDerivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; MidpointIntegrator integ = new MidpointIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; MidpointIntegrator integ = new MidpointIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 114000); assertTrue(bos.size () < 115000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 1.0e-6); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java100644 1750 1750 16060 11532241242 31632 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.*; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemFactory; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.EulerIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class EulerIntegratorTest extends TestCase { public EulerIntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); new EulerIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 8; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 4) { assertTrue(valueError < FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 4) { assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } public void testSmallStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-4); assertTrue(handler.getMaximalValueError() < 1.0e-3); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Euler", integ.getName()); } public void testBigStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() > 0.01); assertTrue(handler.getMaximalValueError() > 0.2); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 0.45); assertTrue(handler.getMaximalValueError() < 0.45); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Euler", integ.getName()); } public void testStepSize() throws DerivativeException, IntegratorException { final double step = 1.23456; FirstOrderIntegrator integ = new EulerIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public boolean requiresDenseOutput() { return false; } public void reset() { } }); integ.integrate(new FirstOrderDifferentialEquations() { private static final long serialVersionUID = 0L; public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegratorTest100644 1750 1750 15511 11532241242 32524 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblem6; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class AdamsBashforthIntegratorTest { @Test(expected=IntegratorException.class) public void dimensionCheck() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); FirstOrderIntegrator integ = new AdamsBashforthIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10); integ.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=IntegratorException.class) public void testMinStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -5; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 31 and 36 factors are only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors assertTrue(handler.getMaximalValueError() > (31.0 * scalAbsoluteTolerance)); assertTrue(handler.getMaximalValueError() < (36.0 * scalAbsoluteTolerance)); assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test(expected = DerivativeException.class) public void exceedMaxEvaluations() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double range = pb.getFinalTime() - pb.getInitialTime(); AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(2, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.setMaxEvaluations(650); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void backward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 1.0e-8); assertTrue(handler.getMaximalValueError() < 1.0e-8); assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); assertEquals("Adams-Bashforth", integ.getName()); } @Test public void polynomial() throws DerivativeException, IntegratorException { TestProblem6 pb = new TestProblem6(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); for (int nSteps = 1; nSteps < 8; ++nSteps) { AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-10, 1.0e-10); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (nSteps < 4) { assertTrue(integ.getEvaluations() > 150); } else { assertTrue(integ.getEvaluations() < 70); } } } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolatorTest.ja100644 1750 1750 14466 11532241242 32513 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class EulerStepInterpolatorTest { @Test public void noReset() throws DerivativeException { double[] y = { 0.0, 1.0, -2.0 }; double[][] yDot = { { 1.0, 2.0, -2.0 } }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void interpolationAtBounds() throws DerivativeException { double t0 = 0; double[] y0 = {0.0, 1.0, -2.0}; double[] y = y0.clone(); double[][] yDot = { new double[y0.length] }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true); interpolator.storeTime(t0); double dt = 1.0; y[0] = 1.0; y[1] = 3.0; y[2] = -4.0; yDot[0][0] = (y[0] - y0[0]) / dt; yDot[0][1] = (y[1] - y0[1]) / dt; yDot[0][2] = (y[2] - y0[2]) / dt; interpolator.shift(); interpolator.storeTime(t0 + dt); interpolator.setInterpolatedTime(interpolator.getPreviousTime()); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y0[i]) < 1.0e-10); } interpolator.setInterpolatedTime(interpolator.getCurrentTime()); result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void interpolationInside() throws DerivativeException { double[] y = { 1.0, 3.0, -4.0 }; double[][] yDot = { { 1.0, 2.0, -2.0 } }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); interpolator.setInterpolatedTime(0.1); double[] result = interpolator.getInterpolatedState(); assertTrue(FastMath.abs(result[0] - 0.1) < 1.0e-10); assertTrue(FastMath.abs(result[1] - 1.2) < 1.0e-10); assertTrue(FastMath.abs(result[2] + 2.2) < 1.0e-10); interpolator.setInterpolatedTime(0.5); result = interpolator.getInterpolatedState(); assertTrue(FastMath.abs(result[0] - 0.5) < 1.0e-10); assertTrue(FastMath.abs(result[1] - 2.0) < 1.0e-10); assertTrue(FastMath.abs(result[2] + 3.0) < 1.0e-10); } @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; EulerIntegrator integ = new EulerIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; EulerIntegrator integ = new EulerIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 0.001); } private static class DummyIntegrator extends RungeKuttaIntegrator { protected DummyIntegrator(RungeKuttaStepInterpolator prototype) { super("dummy", new double[0], new double[0][0], new double[0], prototype, Double.NaN); } } } ././@LongLink100644 0 0 164 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterp100644 1750 1750 14100 11532241242 32506 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class GraggBulirschStoerStepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-8); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 34000); assertTrue(bos.size () < 35000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 5.0e-10); } @Test public void checklone() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public boolean requiresDenseOutput() { return true; } public void reset() { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator100644 1750 1750 32624 11532241242 32542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem4; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.GraggBulirschStoerIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class GraggBulirschStoerIntegratorTest extends TestCase { public GraggBulirschStoerIntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); AdaptiveStepsizeIntegrator integrator = new GraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testNullIntervalCheck() { try { TestProblem1 pb = new TestProblem1(); GraggBulirschStoerIntegrator integrator = new GraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testMinStep() { try { TestProblem5 pb = new TestProblem5(); double minStep = 0.1 * FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double maxStep = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double[] vecAbsoluteTolerance = { 1.0e-20, 1.0e-21 }; double[] vecRelativeTolerance = { 1.0e-20, 1.0e-21 }; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 7.5e-9); assertTrue(handler.getMaximalValueError() < 8.1e-9); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("Gragg-Bulirsch-Stoer", integ.getName()); } public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -4; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = FastMath.pow(10.0, i); double relTolerance = absTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the coefficients are only valid for this test // and have been obtained from trial and error // there is no general relation between local and global errors double ratio = handler.getMaximalValueError() / absTolerance; assertTrue(ratio < 2.4); assertTrue(ratio > 0.02); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } public void testIntegratorControls() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(0.999); GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(0, pb.getFinalTime() - pb.getInitialTime(), 1.0e-8, 1.0e-10); double errorWithDefaultSettings = getMaxError(integ, pb); // stability control integ.setStabilityCheck(true, 2, 1, 0.99); assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setStabilityCheck(true, -1, -1, -1); integ.setStepsizeControl(0.5, 0.99, 0.1, 2.5); assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setStepsizeControl(-1, -1, -1, -1); integ.setOrderControl(10, 0.7, 0.95); assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setOrderControl(-1, -1, -1); integ.setInterpolationControl(true, 3); assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setInterpolationControl(true, -1); } private double getMaxError(FirstOrderIntegrator integrator, TestProblemAbstract pb) throws DerivativeException, IntegratorException { TestProblemHandler handler = new TestProblemHandler(pb, integrator); integrator.addStepHandler(handler); integrator.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); return handler.getMaximalValueError(); } public void testEvents() throws DerivativeException, IntegratorException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-10; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getMaximalValueError() < 5.0e-8); assertEquals(0, handler.getMaximalTimeError(), convergence); assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); assertEquals(0, integ.getEventHandlers().size()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-6; double relTolerance = 1.0e-6; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new KeplerStepHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(integ.getEvaluations(), pb.getCalls()); assertTrue(pb.getCalls() < 2150); } public void testVariableSteps() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new VariableStepHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); assertEquals("Gragg-Bulirsch-Stoer", integ.getName()); } public void testUnstableDerivative() throws DerivativeException, IntegratorException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(0.1, 10, 1.0e-12, 0.0); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); assertEquals(8.0, y[0], 1.0e-12); } private static class KeplerStepHandler implements StepHandler { public KeplerStepHandler(TestProblem3 pb) { this.pb = pb; reset(); } public boolean requiresDenseOutput() { return true; } public void reset() { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { ++nbSteps; for (int a = 1; a < 100; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((100 - a) * prev + a * curr) / 100; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { assertTrue(maxError < 2.7e-6); assertTrue(nbSteps < 80); } } private int nbSteps; private double maxError; private TestProblem3 pb; } public static class VariableStepHandler implements StepHandler { public VariableStepHandler() { reset(); } public boolean requiresDenseOutput() { return false; } public void reset() { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { assertTrue(minStep < 8.2e-3); assertTrue(maxStep > 1.7); } } private boolean firstTime; private double minStep; private double maxStep; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/StepProblem.java100644 1750 1750 3532 11532241242 30073 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.events.EventHandler; public class StepProblem implements FirstOrderDifferentialEquations, EventHandler { public StepProblem(double rateBefore, double rateAfter, double switchTime) { this.rateAfter = rateAfter; this.switchTime = switchTime; setRate(rateBefore); } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = rate; } public int getDimension() { return 1; } public void setRate(double rate) { this.rate = rate; } public int eventOccurred(double t, double[] y, boolean increasing) { setRate(rateAfter); return RESET_DERIVATIVES; } public double g(double t, double[] y) { return t - switchTime; } public void resetState(double t, double[] y) { } private double rate; private double rateAfter; private double switchTime; private static final long serialVersionUID = 7590601995477504318L; } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java100644 1750 1750 16042 11532241242 32341 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.*; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemFactory; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.MidpointIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class MidpointIntegratorTest extends TestCase { public MidpointIntegratorTest(String name) { super(name); } public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); new MidpointIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 4) { assertTrue(valueError < FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 4) { assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } public void testSmallStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-7); assertTrue(handler.getMaximalValueError() < 1.0e-6); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("midpoint", integ.getName()); } public void testBigStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() > 0.01); assertTrue(handler.getMaximalValueError() > 0.05); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 6.0e-4); assertTrue(handler.getMaximalValueError() < 6.0e-4); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("midpoint", integ.getName()); } public void testStepSize() throws DerivativeException, IntegratorException { final double step = 1.23456; FirstOrderIntegrator integ = new MidpointIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public boolean requiresDenseOutput() { return false; } public void reset() { } }); integ.integrate(new FirstOrderDifferentialEquations() { private static final long serialVersionUID = 0L; public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegratorTest.j100644 1750 1750 15455 11532241242 32500 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblem6; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class AdamsMoultonIntegratorTest { @Test(expected=IntegratorException.class) public void dimensionCheck() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); FirstOrderIntegrator integ = new AdamsMoultonIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10); integ.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=IntegratorException.class) public void testMinStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testIncreasingTolerance() throws DerivativeException, IntegratorException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 0.15 and 3.0 factors are only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors assertTrue(handler.getMaximalValueError() > (0.15 * scalAbsoluteTolerance)); assertTrue(handler.getMaximalValueError() < (3.0 * scalAbsoluteTolerance)); assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); int calls = pb.getCalls(); assertEquals(integ.getEvaluations(), calls); assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test(expected = DerivativeException.class) public void exceedMaxEvaluations() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double range = pb.getFinalTime() - pb.getInitialTime(); AdamsMoultonIntegrator integ = new AdamsMoultonIntegrator(2, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.setMaxEvaluations(650); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void backward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 1.0e-9); assertTrue(handler.getMaximalValueError() < 1.0e-9); assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); assertEquals("Adams-Moulton", integ.getName()); } @Test public void polynomial() throws DerivativeException, IntegratorException { TestProblem6 pb = new TestProblem6(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); for (int nSteps = 1; nSteps < 7; ++nSteps) { AdamsMoultonIntegrator integ = new AdamsMoultonIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-9, 1.0e-9); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (nSteps < 4) { assertTrue(integ.getEvaluations() > 140); } else { assertTrue(integ.getEvaluations() < 90); } } } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInter100644 1750 1750 7027 11532241242 32470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils; import org.junit.Test; public class ClassicalRungeKuttaStepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 753000); assertTrue(bos.size () < 754000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError > 0.005); } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrato100644 1750 1750 27057 11532241242 32534 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import junit.framework.*; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.TestProblem5; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.ode.TestProblemFactory; import org.apache.commons.math.ode.TestProblemHandler; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.nonstiff.ClassicalRungeKuttaIntegrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class ClassicalRungeKuttaIntegratorTest extends TestCase { public ClassicalRungeKuttaIntegratorTest(String name) { super(name); } public void testMissedEndEvent() throws IntegratorException, DerivativeException { final double t0 = 1878250320.0000029; final double tEvent = 1878250379.9999986; final double[] k = { 1.0e-4, 1.0e-5, 1.0e-6 }; FirstOrderDifferentialEquations ode = new FirstOrderDifferentialEquations() { public int getDimension() { return k.length; } public void computeDerivatives(double t, double[] y, double[] yDot) { for (int i = 0; i < y.length; ++i) { yDot[i] = k[i] * y[i]; } } }; ClassicalRungeKuttaIntegrator integrator = new ClassicalRungeKuttaIntegrator(60.0); double[] y0 = new double[k.length]; for (int i = 0; i < y0.length; ++i) { y0[i] = i + 1; } double[] y = new double[k.length]; double finalT = integrator.integrate(ode, t0, y0, tEvent, y); Assert.assertEquals(tEvent, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } integrator.addEventHandler(new EventHandler() { public void resetState(double t, double[] y) { } public double g(double t, double[] y) { return t - tEvent; } public int eventOccurred(double t, double[] y, boolean increasing) { Assert.assertEquals(tEvent, t, 5.0e-6); return CONTINUE; } }, Double.POSITIVE_INFINITY, 1.0e-20, 100); finalT = integrator.integrate(ode, t0, y0, tEvent + 120, y); Assert.assertEquals(tEvent + 120, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } } public void testSanityChecks() { try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()], 1.0, new double[pb.getDimension()+10]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); fail("an exception should have been thrown"); } catch(DerivativeException de) { fail("wrong exception caught"); } catch(IntegratorException ie) { } } public void testDecreasingSteps() throws DerivativeException, IntegratorException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } assertEquals(functions.length, integ.getEventHandlers().size()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double error = handler.getMaximalValueError(); if (i > 4) { assertTrue(error < FastMath.abs(previousValueError)); } previousValueError = error; double timeError = handler.getMaximalTimeError(); if (i > 4) { assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; integ.clearEventHandlers(); assertEquals(0, integ.getEventHandlers().size()); } } } public void testSmallStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 2.0e-13); assertTrue(handler.getMaximalValueError() < 4.0e-12); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("classical Runge-Kutta", integ.getName()); } public void testBigStep() throws DerivativeException, IntegratorException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() > 0.0004); assertTrue(handler.getMaximalValueError() > 0.005); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } public void testBackward() throws DerivativeException, IntegratorException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(handler.getLastError() < 5.0e-10); assertTrue(handler.getMaximalValueError() < 7.0e-10); assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); assertEquals("classical Runge-Kutta", integ.getName()); } public void testKepler() throws DerivativeException, IntegratorException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; reset(); } public boolean requiresDenseOutput() { return false; } public void reset() { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy assertTrue(maxError > 0.005); } } private double maxError = 0; private TestProblem3 pb; } public void testStepSize() throws DerivativeException, IntegratorException { final double step = 1.23456; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public boolean requiresDenseOutput() { return false; } public void reset() { } }); integ.integrate(new FirstOrderDifferentialEquations() { private static final long serialVersionUID = 0L; public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/ContinuousOutputModelTest.java100644 1750 1750 16132 11532241242 31241 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import junit.framework.*; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; public class ContinuousOutputModelTest extends TestCase { public ContinuousOutputModelTest(String name) { super(name); pb = null; integ = null; } public void testBoundaries() throws DerivativeException, IntegratorException { integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ContinuousOutputModel cm = (ContinuousOutputModel) integ.getStepHandlers().iterator().next(); cm.setInterpolatedTime(2.0 * pb.getInitialTime() - pb.getFinalTime()); cm.setInterpolatedTime(2.0 * pb.getFinalTime() - pb.getInitialTime()); cm.setInterpolatedTime(0.5 * (pb.getFinalTime() + pb.getInitialTime())); } public void testRandomAccess() throws DerivativeException, IntegratorException { ContinuousOutputModel cm = new ContinuousOutputModel(); integ.addStepHandler(cm); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 1.0e-9); } public void testModelsMerging() throws DerivativeException, IntegratorException { // theoretical solution: y[0] = cos(t), y[1] = sin(t) FirstOrderDifferentialEquations problem = new FirstOrderDifferentialEquations() { private static final long serialVersionUID = 2472449657345878299L; public void computeDerivatives(double t, double[] y, double[] dot) throws DerivativeException { dot[0] = -y[1]; dot[1] = y[0]; } public int getDimension() { return 2; } }; // integrate backward from π to 0; ContinuousOutputModel cm1 = new ContinuousOutputModel(); FirstOrderIntegrator integ1 = new DormandPrince853Integrator(0, 1.0, 1.0e-8, 1.0e-8); integ1.addStepHandler(cm1); integ1.integrate(problem, FastMath.PI, new double[] { -1.0, 0.0 }, 0, new double[2]); // integrate backward from 2π to π ContinuousOutputModel cm2 = new ContinuousOutputModel(); FirstOrderIntegrator integ2 = new DormandPrince853Integrator(0, 0.1, 1.0e-12, 1.0e-12); integ2.addStepHandler(cm2); integ2.integrate(problem, 2.0 * FastMath.PI, new double[] { 1.0, 0.0 }, FastMath.PI, new double[2]); // merge the two half circles ContinuousOutputModel cm = new ContinuousOutputModel(); cm.append(cm2); cm.append(new ContinuousOutputModel()); cm.append(cm1); // check circle assertEquals(2.0 * FastMath.PI, cm.getInitialTime(), 1.0e-12); assertEquals(0, cm.getFinalTime(), 1.0e-12); assertEquals(cm.getFinalTime(), cm.getInterpolatedTime(), 1.0e-12); for (double t = 0; t < 2.0 * FastMath.PI; t += 0.1) { cm.setInterpolatedTime(t); double[] y = cm.getInterpolatedState(); assertEquals(FastMath.cos(t), y[0], 1.0e-7); assertEquals(FastMath.sin(t), y[1], 1.0e-7); } } public void testErrorConditions() throws DerivativeException { ContinuousOutputModel cm = new ContinuousOutputModel(); cm.handleStep(buildInterpolator(0, new double[] { 0.0, 1.0, -2.0 }, 1), true); // dimension mismatch assertTrue(checkAppendError(cm, 1.0, new double[] { 0.0, 1.0 }, 2.0)); // hole between time ranges assertTrue(checkAppendError(cm, 10.0, new double[] { 0.0, 1.0, -2.0 }, 20.0)); // propagation direction mismatch assertTrue(checkAppendError(cm, 1.0, new double[] { 0.0, 1.0, -2.0 }, 0.0)); // no errors assertFalse(checkAppendError(cm, 1.0, new double[] { 0.0, 1.0, -2.0 }, 2.0)); } private boolean checkAppendError(ContinuousOutputModel cm, double t0, double[] y0, double t1) throws DerivativeException { try { ContinuousOutputModel otherCm = new ContinuousOutputModel(); otherCm.handleStep(buildInterpolator(t0, y0, t1), true); cm.append(otherCm); } catch(IllegalArgumentException iae) { return true; // there was an allowable error } return false; // no allowable error } private StepInterpolator buildInterpolator(double t0, double[] y0, double t1) { DummyStepInterpolator interpolator = new DummyStepInterpolator(y0, new double[y0.length], t1 >= t0); interpolator.storeTime(t0); interpolator.shift(); interpolator.storeTime(t1); return interpolator; } public void checkValue(double value, double reference) { assertTrue(FastMath.abs(value - reference) < 1.0e-10); } @Override public void setUp() { pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); integ = new DormandPrince54Integrator(minStep, maxStep, 1.0e-8, 1.0e-8); } @Override public void tearDown() { pb = null; integ = null; } TestProblem3 pb; FirstOrderIntegrator integ; } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/events/EventStateTest.java100644 1750 1750 5427 11532241242 30244 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.events; import junit.framework.Assert; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.junit.Test; public class EventStateTest { // JIRA: MATH-322 @Test public void closeEvents() throws EventException, ConvergenceException, DerivativeException { final double r1 = 90.0; final double r2 = 135.0; final double gap = r2 - r1; EventHandler closeEventsGenerator = new EventHandler() { public void resetState(double t, double[] y) { } public double g(double t, double[] y) { return (t - r1) * (r2 - t); } public int eventOccurred(double t, double[] y, boolean increasing) { return CONTINUE; } }; final double tolerance = 0.1; EventState es = new EventState(closeEventsGenerator, 1.5 * gap, tolerance, 10); AbstractStepInterpolator interpolator = new DummyStepInterpolator(new double[0], new double[0], true); interpolator.storeTime(r1 - 2.5 * gap); interpolator.shift(); interpolator.storeTime(r1 - 1.5 * gap); es.reinitializeBegin(interpolator); interpolator.shift(); interpolator.storeTime(r1 - 0.5 * gap); Assert.assertFalse(es.evaluateStep(interpolator)); interpolator.shift(); interpolator.storeTime(0.5 * (r1 + r2)); Assert.assertTrue(es.evaluateStep(interpolator)); Assert.assertEquals(r1, es.getEventTime(), tolerance); es.stepAccepted(es.getEventTime(), new double[0]); interpolator.shift(); interpolator.storeTime(r2 + 0.4 * gap); Assert.assertTrue(es.evaluateStep(interpolator)); Assert.assertEquals(r2, es.getEventTime(), tolerance); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem6.java100644 1750 1750 5065 11532241242 26342 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** * This class is used in the junit tests for the ODE integrators. *

                  This specific problem is the following differential equation : *

                   *    y' = 3x^5 - y
                   * 
                  * when the initial condition is y(0) = -360, the solution of this * equation degenerates to a simple quintic polynomial function : *
                   *   y (t) = 3x^5 - 15x^4 + 60x^3 - 180x^2 + 360x - 360
                   * 
                  *

                  */ public class TestProblem6 extends TestProblemAbstract { /** Serializable version identifier. */ private static final long serialVersionUID = 1353409119804352378L; /** theoretical state */ private double[] y; /** * Simple constructor. */ public TestProblem6() { super(); double[] y0 = { -360.0 }; setInitialConditions(0.0, y0); setFinalConditions(1.0); double[] errorScale = { 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem6(TestProblem6 problem) { super(problem); y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem6 copy() { return new TestProblem6(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // compute the derivatives double t2 = t * t; double t4 = t2 * t2; double t5 = t4 * t; for (int i = 0; i < n; ++i) { yDot[i] = 3 * t5 - y[i]; } } @Override public double[] computeTheoreticalState(double t) { for (int i = 0; i < n; ++i) { y[i] = ((((3 * t - 15) * t + 60) * t - 180) * t + 360) * t - 360; } return y; } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/DummyStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/DummyStepInterpolatorTest.ja100644 1750 1750 11413 11532241242 32503 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.apache.commons.math.util.FastMath; import org.junit.Test; public class DummyStepInterpolatorTest { @Test public void testNoReset() throws DerivativeException { double[] y = { 0.0, 1.0, -2.0 }; DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void testFixedState() throws DerivativeException { double[] y = { 1.0, 3.0, -4.0 }; DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); interpolator.setInterpolatedTime(0.1); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } interpolator.setInterpolatedTime(0.5); result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void testSerialization() throws DerivativeException, IOException, ClassNotFoundException { double[] y = { 0.0, 1.0, -2.0 }; DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(interpolator); assertTrue(bos.size () > 200); assertTrue(bos.size () < 300); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); DummyStepInterpolator dsi = (DummyStepInterpolator) ois.readObject(); dsi.setInterpolatedTime(0.5); double[] result = dsi.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void testImpossibleSerialization() throws IOException { double[] y = { 0.0, 1.0, -2.0 }; AbstractStepInterpolator interpolator = new BadStepInterpolator(y, true); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); try { oos.writeObject(interpolator); fail("an exception should have been thrown"); } catch (IOException ioe) { // expected behavior assertEquals(0, ioe.getMessage().length()); } } private static class BadStepInterpolator extends DummyStepInterpolator { @SuppressWarnings("unused") public BadStepInterpolator() { } public BadStepInterpolator(double[] y, boolean forward) { super(y, new double[y.length], forward); } @Override protected void doFinalize() throws DerivativeException { throw new DerivativeException((Localizable) null, LocalizedFormats.SIMPLE_MESSAGE, ""); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerTest.java100644 1750 1750 11544 11532241242 31463 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math.ode.sampling.FixedStepHandler; import org.apache.commons.math.ode.sampling.StepNormalizer; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class StepNormalizerTest extends TestCase { public StepNormalizerTest(String name) { super(name); pb = null; integ = null; } public void testBoundaries() throws DerivativeException, IntegratorException { double range = pb.getFinalTime() - pb.getInitialTime(); setLastSeen(false); integ.addStepHandler(new StepNormalizer(range / 10.0, new FixedStepHandler() { private static final long serialVersionUID = 1650337364641626444L; private boolean firstCall = true; public void handleStep(double t, double[] y, double[] yDot, boolean isLast) { if (firstCall) { checkValue(t, pb.getInitialTime()); firstCall = false; } if (isLast) { setLastSeen(true); checkValue(t, pb.getFinalTime()); } } })); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(lastSeen); } public void testBeforeEnd() throws DerivativeException, IntegratorException { final double range = pb.getFinalTime() - pb.getInitialTime(); setLastSeen(false); integ.addStepHandler(new StepNormalizer(range / 10.5, new FixedStepHandler() { private static final long serialVersionUID = 2228457391561277298L; public void handleStep(double t, double[] y, double[] yDot, boolean isLast) { if (isLast) { setLastSeen(true); checkValue(t, pb.getFinalTime() - range / 21.0); } } })); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); assertTrue(lastSeen); } public void checkValue(double value, double reference) { assertTrue(FastMath.abs(value - reference) < 1.0e-10); } public void setLastSeen(boolean lastSeen) { this.lastSeen = lastSeen; } @Override public void setUp() { pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); integ = new DormandPrince54Integrator(minStep, maxStep, 10.e-8, 1.0e-8); lastSeen = false; } @Override public void tearDown() { pb = null; integ = null; } TestProblem3 pb; FirstOrderIntegrator integ; boolean lastSeen; } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolatorTes100644 1750 1750 7075 11532241242 32545 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ContinuousOutputModel; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblem1; import org.apache.commons.math.ode.TestProblem3; import org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator; import org.junit.Test; public class NordsieckStepInterpolatorTest { @Test public void derivativesConsistency() throws DerivativeException, IntegratorException { TestProblem3 pb = new TestProblem3(); AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(4, 0.0, 1.0, 1.0e-10, 1.0e-10); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 5e-9); } @Test public void serialization() throws DerivativeException, IntegratorException, IOException, ClassNotFoundException { TestProblem1 pb = new TestProblem1(); AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(4, 0.0, 1.0, 1.0e-10, 1.0e-10); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } assertTrue(bos.size () > 25500); assertTrue(bos.size () < 26500); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } assertTrue(maxError < 1.0e-6); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/StepInterpolatorTestUtils.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/ode/sampling/StepInterpolatorTestUtils.ja100644 1750 1750 10021 11532241242 32502 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import static org.junit.Assert.assertEquals; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.TestProblemAbstract; import org.apache.commons.math.util.FastMath; public class StepInterpolatorTestUtils { public static void checkDerivativesConsistency(final FirstOrderIntegrator integrator, final TestProblemAbstract problem, final double threshold) throws DerivativeException, IntegratorException { integrator.addStepHandler(new StepHandler() { public boolean requiresDenseOutput() { return true; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { final double h = 0.001 * (interpolator.getCurrentTime() - interpolator.getPreviousTime()); final double t = interpolator.getCurrentTime() - 300 * h; if (FastMath.abs(h) < 10 * FastMath.ulp(t)) { return; } interpolator.setInterpolatedTime(t - 4 * h); final double[] yM4h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - 3 * h); final double[] yM3h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - 2 * h); final double[] yM2h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - h); final double[] yM1h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + h); final double[] yP1h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 2 * h); final double[] yP2h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 3 * h); final double[] yP3h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 4 * h); final double[] yP4h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t); final double[] yDot = interpolator.getInterpolatedDerivatives(); for (int i = 0; i < yDot.length; ++i) { final double approYDot = ( -3 * (yP4h[i] - yM4h[i]) + 32 * (yP3h[i] - yM3h[i]) + -168 * (yP2h[i] - yM2h[i]) + 672 * (yP1h[i] - yM1h[i])) / (840 * h); assertEquals(approYDot, yDot[i], threshold); } } public void reset() { } }); integrator.integrate(problem, problem.getInitialTime(), problem.getInitialState(), problem.getFinalTime(), new double[problem.getDimension()]); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ode/TestProblem4.java100644 1750 1750 7607 11532241242 26344 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *

                  This specific problem is the following differential equation : *

                   *    x'' = -x
                   * 
                  * And when x decreases down to 0, the state should be changed as follows : *
                   *   x' -> -x'
                   * 
                  * The theoretical solution of this problem is x = |sin(t+a)| *

                  */ public class TestProblem4 extends TestProblemAbstract { /** Serializable version identifier. */ private static final long serialVersionUID = -5910438521889015745L; /** Time offset. */ private double a; /** theoretical state */ private double[] y; /** Simple constructor. */ public TestProblem4() { super(); a = 1.2; double[] y0 = { FastMath.sin(a), FastMath.cos(a) }; setInitialConditions(0.0, y0); setFinalConditions(15); double[] errorScale = { 1.0, 0.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem4(TestProblem4 problem) { super(problem); a = problem.a; y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem4 copy() { return new TestProblem4(this); } @Override public EventHandler[] getEventsHandlers() { return new EventHandler[] { new Bounce(), new Stop() }; } /** * Get the theoretical events times. * @return theoretical events times */ @Override public double[] getTheoreticalEventsTimes() { return new double[] { 1 * FastMath.PI - a, 2 * FastMath.PI - a, 3 * FastMath.PI - a, 4 * FastMath.PI - a, 12.0 }; } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = y[1]; yDot[1] = -y[0]; } @Override public double[] computeTheoreticalState(double t) { double sin = FastMath.sin(t + a); double cos = FastMath.cos(t + a); y[0] = FastMath.abs(sin); y[1] = (sin >= 0) ? cos : -cos; return y; } private static class Bounce implements EventHandler { private static final long serialVersionUID = 1356097180027801200L; private int sign; public Bounce() { sign = +1; } public double g(double t, double[] y) { return sign * y[0]; } public int eventOccurred(double t, double[] y, boolean increasing) { // this sign change is needed because the state will be reset soon sign = -sign; return EventHandler.RESET_STATE; } public void resetState(double t, double[] y) { y[0] = -y[0]; y[1] = -y[1]; } } private static class Stop implements EventHandler { private static final long serialVersionUID = 6975050568227951931L; public Stop() { } public double g(double t, double[] y) { return t - 12.0; } public int eventOccurred(double t, double[] y, boolean increasing) { return EventHandler.STOP; } public void resetState(double t, double[] y) { } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/MathConfigurationExceptionTest.java100644 1750 1750 6140 11532241244 31402 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import junit.framework.TestCase; import java.util.Locale; import org.apache.commons.math.exception.util.LocalizedFormats; /** * @version $Revision: 1035475 $ $Date: 2010-11-15 23:39:25 +0100 (lun. 15 nov. 2010) $ */ public class MathConfigurationExceptionTest extends TestCase { public void testConstructor(){ MathConfigurationException ex = new MathConfigurationException(); assertNull(ex.getCause()); assertEquals("", ex.getMessage()); assertEquals("", ex.getMessage(Locale.FRENCH)); } public void testConstructorPatternArguments(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; MathConfigurationException ex = new MathConfigurationException(pattern, arguments); assertNull(ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorCause(){ String inMsg = "inner message"; Exception cause = new Exception(inMsg); MathConfigurationException ex = new MathConfigurationException(cause); assertEquals(cause, ex.getCause()); } public void testConstructorPatternArgumentsCause(){ LocalizedFormats pattern = LocalizedFormats.ROTATION_MATRIX_DIMENSIONS; Object[] arguments = { Integer.valueOf(6), Integer.valueOf(4) }; String inMsg = "inner message"; Exception cause = new Exception(inMsg); MathConfigurationException ex = new MathConfigurationException(cause, pattern, arguments); assertEquals(cause, ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.j100644 1750 1750 2443 11532241242 32466 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link NumberIsTooSmallException}. * * @version $Revision$ $Date$ */ public class NumberIsTooSmallExceptionTest { @Test public void testAccessors() { final NumberIsTooSmallException e = new NumberIsTooSmallException(0, 0, false); Assert.assertEquals(0, e.getArgument()); Assert.assertEquals(0, e.getMin()); Assert.assertFalse(e.getBoundIsAllowed()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java100644 1750 1750 2406 11532241242 32241 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link NotPositiveException}. * * @version $Revision$ $Date$ */ public class NotPositiveExceptionTest { @Test public void testAccessors() { final NotPositiveException e = new NotPositiveException(-1); Assert.assertEquals(-1, e.getArgument()); Assert.assertEquals(0, e.getMin()); Assert.assertTrue(e.getBoundIsAllowed()); } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTes100644 1750 1750 2445 11532241242 32676 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link NotStrictlyPositiveException}. * * @version $Revision$ $Date$ */ public class NotStrictlyPositiveExceptionTest { @Test public void testAccessors() { final NotStrictlyPositiveException e = new NotStrictlyPositiveException(0); Assert.assertEquals(0, e.getArgument()); Assert.assertEquals(0, e.getMin()); Assert.assertFalse(e.getBoundIsAllowed()); } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NonMonotonousSequenceExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NonMonotonousSequenceExceptionT100644 1750 1750 3540 11532241242 32646 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.util.MathUtils; import org.junit.Assert; import org.junit.Test; /** * Test for {@link NonMonotonousSequenceException}. * * @version $Revision$ $Date$ */ public class NonMonotonousSequenceExceptionTest { @Test public void testAccessors() { NonMonotonousSequenceException e = new NonMonotonousSequenceException(0, -1, 1, MathUtils.OrderDirection.DECREASING, false); Assert.assertEquals(0, e.getArgument()); Assert.assertEquals(-1, e.getPrevious()); Assert.assertEquals(1, e.getIndex()); Assert.assertTrue(e.getDirection() == MathUtils.OrderDirection.DECREASING); Assert.assertFalse(e.getStrict()); e = new NonMonotonousSequenceException(-1, 0, 1); Assert.assertEquals(-1, e.getArgument()); Assert.assertEquals(0, e.getPrevious()); Assert.assertEquals(1, e.getIndex()); Assert.assertTrue(e.getDirection() == MathUtils.OrderDirection.INCREASING); Assert.assertTrue(e.getStrict()); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/DimensionMismatchExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/exception/DimensionMismatchExceptionTest.100644 1750 1750 2363 11532241242 32531 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link DimensionMismatchException}. * * @version $Revision$ $Date$ */ public class DimensionMismatchExceptionTest { @Test public void testAccessors() { final DimensionMismatchException e = new DimensionMismatchException(1, 2); Assert.assertEquals(1, e.getArgument()); Assert.assertEquals(2, e.getDimension()); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.j100644 1750 1750 2441 11532241242 32446 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link NumberIsTooLargeException}. * * @version $Revision$ $Date$ */ public class NumberIsTooLargeExceptionTest { @Test public void testAccessors() { final NumberIsTooLargeException e = new NumberIsTooLargeException(1, 0, true); Assert.assertEquals(1, e.getArgument()); Assert.assertEquals(0, e.getMax()); Assert.assertTrue(e.getBoundIsAllowed()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/util/ArgUtilsTest.java100644 1750 1750 4274 11532241242 30613 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.util.List; import java.util.ArrayList; import org.junit.Assert; import org.junit.Test; /** * Test for {@link ArgUtils}. * * @version $Revision$ $Date$ */ public class ArgUtilsTest { @Test public void testFlatten() { final List orig = new ArrayList(); final Object[] struct = new Object[] { new Object[] { new Object[] { create(orig), create(orig), }, create(orig), new Object[] { create(orig), } }, create(orig), new Object[] { create(orig), new Object[] { create(orig), create(orig), } }, create(orig), }; Object[] flat = ArgUtils.flatten(struct); Assert.assertEquals(flat.length, orig.size()); for (int i = 0, max = orig.size(); i < max; i++) { Assert.assertEquals(orig.get(i), flat[i]); } } /** * Create and store an {@code Object}. * * @param list List to store to. * @return the stored object. */ private Object create(List list) { final Object o = new Object(); list.add(o); return o; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/util/MessageFactoryTest.java100644 1750 1750 4355 11532241242 31775 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.util.Locale; import org.junit.Assert; import org.junit.Test; public class MessageFactoryTest { @Test public void testSpecificGeneral() { Localizable specific = new DummyLocalizable("specific {0} - {1} - {2}"); Localizable general = new DummyLocalizable("general {0} / {1}"); String message = MessageFactory.buildMessage(Locale.FRENCH, specific, general, 0, 1, 2, 'a', 'b'); Assert.assertEquals("general 0 / 1: specific 0 - 1 - 2", message); } @Test public void testNullSpecific() { Localizable general = new DummyLocalizable("general {0} / {1}"); String message = MessageFactory.buildMessage(Locale.FRENCH, null, general, 0, 1, 2, 'a', 'b'); Assert.assertEquals("general 0 / 1", message); } @Test public void testNullGeneral() { Localizable specific = new DummyLocalizable("specific {0} - {1} - {2}"); String message = MessageFactory.buildMessage(Locale.FRENCH, specific, null, 0, 1, 2, 'a', 'b'); Assert.assertEquals("specific 0 - 1 - 2", message); } @Test public void testNull() { String message = MessageFactory.buildMessage(Locale.FRENCH, null, null, "nothing"); Assert.assertEquals("", message); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/exception/OutOfRangeExceptionTest.java100644 1750 1750 2400 11532241242 31761 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.junit.Assert; import org.junit.Test; /** * Test for {@link OutOfRangeException}. * * @version $Revision$ $Date$ */ public class OutOfRangeExceptionTest { @Test public void testAccessors() { final OutOfRangeException e = new OutOfRangeException(-1, 0, 2); Assert.assertEquals(-1, e.getArgument()); Assert.assertEquals(0, e.getLo()); Assert.assertEquals(2, e.getHi()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/ArgumentOutsideDomainExceptionTest.java100644 1750 1750 2766 11532241244 32242 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.util.Locale; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class ArgumentOutsideDomainExceptionTest extends TestCase { public void testConstructor(){ ArgumentOutsideDomainException ex = new ArgumentOutsideDomainException(FastMath.PI, 10.0, 20.0); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("3.14") > 0); assertEquals(FastMath.PI, ex.getArgument()[0], 0); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/TestUtils.java100644 1750 1750 47521 11532241244 25232 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.text.DecimalFormat; import junit.framework.Assert; import junit.framework.AssertionFailedError; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.complex.ComplexFormat; import org.apache.commons.math.distribution.ContinuousDistribution; import org.apache.commons.math.linear.FieldMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.stat.inference.ChiSquareTest; import org.apache.commons.math.stat.inference.ChiSquareTestImpl; import org.apache.commons.math.util.FastMath; /** * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ public class TestUtils { /** * Collection of static methods used in math unit tests. */ private TestUtils() { super(); } /** * Verifies that expected and actual are within delta, or are both NaN or * infinities of the same sign. */ public static void assertEquals(double expected, double actual, double delta) { assertEquals(null, expected, actual, delta); } /** * Verifies that expected and actual are within delta, or are both NaN or * infinities of the same sign. */ public static void assertEquals(String msg, double expected, double actual, double delta) { // check for NaN if(Double.isNaN(expected)){ Assert.assertTrue("" + actual + " is not NaN.", Double.isNaN(actual)); } else { Assert.assertEquals(msg, expected, actual, delta); } } /** * Verifies that the two arguments are exactly the same, either * both NaN or infinities of same sign, or identical floating point values. */ public static void assertSame(double expected, double actual) { assertEquals(expected, actual, 0); } /** * Verifies that real and imaginary parts of the two complex arguments * are exactly the same. Also ensures that NaN / infinite components match. */ public static void assertSame(Complex expected, Complex actual) { assertSame(expected.getReal(), actual.getReal()); assertSame(expected.getImaginary(), actual.getImaginary()); } /** * Verifies that real and imaginary parts of the two complex arguments * differ by at most delta. Also ensures that NaN / infinite components match. */ public static void assertEquals(Complex expected, Complex actual, double delta) { assertEquals(expected.getReal(), actual.getReal(), delta); assertEquals(expected.getImaginary(), actual.getImaginary(), delta); } /** * Verifies that two double arrays have equal entries, up to tolerance */ public static void assertEquals(double expected[], double observed[], double tolerance) { assertEquals("Array comparison failure", expected, observed, tolerance); } /** * Serializes an object to a bytes array and then recovers the object from the bytes array. * Returns the deserialized object. * * @param o object to serialize and recover * @return the recovered, deserialized object */ public static Object serializeAndRecover(Object o) { try { // serialize the Object ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream so = new ObjectOutputStream(bos); so.writeObject(o); // deserialize the Object ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream si = new ObjectInputStream(bis); return si.readObject(); } catch (IOException ioe) { return null; } catch (ClassNotFoundException cnfe) { return null; } } /** * Verifies that serialization preserves equals and hashCode. * Serializes the object, then recovers it and checks equals and hash code. * * @param object the object to serialize and recover */ public static void checkSerializedEquality(Object object) { Object object2 = serializeAndRecover(object); Assert.assertEquals("Equals check", object, object2); Assert.assertEquals("HashCode check", object.hashCode(), object2.hashCode()); } /** * Verifies that the relative error in actual vs. expected is less than or * equal to relativeError. If expected is infinite or NaN, actual must be * the same (NaN or infinity of the same sign). * * @param expected expected value * @param actual observed value * @param relativeError maximum allowable relative error */ public static void assertRelativelyEquals(double expected, double actual, double relativeError) { assertRelativelyEquals(null, expected, actual, relativeError); } /** * Verifies that the relative error in actual vs. expected is less than or * equal to relativeError. If expected is infinite or NaN, actual must be * the same (NaN or infinity of the same sign). * * @param msg message to return with failure * @param expected expected value * @param actual observed value * @param relativeError maximum allowable relative error */ public static void assertRelativelyEquals(String msg, double expected, double actual, double relativeError) { if (Double.isNaN(expected)) { Assert.assertTrue(msg, Double.isNaN(actual)); } else if (Double.isNaN(actual)) { Assert.assertTrue(msg, Double.isNaN(expected)); } else if (Double.isInfinite(actual) || Double.isInfinite(expected)) { Assert.assertEquals(expected, actual, relativeError); } else if (expected == 0.0) { Assert.assertEquals(msg, actual, expected, relativeError); } else { double absError = FastMath.abs(expected) * relativeError; Assert.assertEquals(msg, expected, actual, absError); } } /** * Fails iff values does not contain a number within epsilon of z. * * @param msg message to return with failure * @param values complex array to search * @param z value sought * @param epsilon tolerance */ public static void assertContains(String msg, Complex[] values, Complex z, double epsilon) { int i = 0; boolean found = false; while (!found && i < values.length) { try { assertEquals(values[i], z, epsilon); found = true; } catch (AssertionFailedError er) { // no match } i++; } if (!found) { Assert.fail(msg + " Unable to find " + ComplexFormat.formatComplex(z)); } } /** * Fails iff values does not contain a number within epsilon of z. * * @param values complex array to search * @param z value sought * @param epsilon tolerance */ public static void assertContains(Complex[] values, Complex z, double epsilon) { assertContains(null, values, z, epsilon); } /** * Fails iff values does not contain a number within epsilon of x. * * @param msg message to return with failure * @param values double array to search * @param x value sought * @param epsilon tolerance */ public static void assertContains(String msg, double[] values, double x, double epsilon) { int i = 0; boolean found = false; while (!found && i < values.length) { try { assertEquals(values[i], x, epsilon); found = true; } catch (AssertionFailedError er) { // no match } i++; } if (!found) { Assert.fail(msg + " Unable to find" + x); } } /** * Fails iff values does not contain a number within epsilon of x. * * @param values double array to search * @param x value sought * @param epsilon tolerance */ public static void assertContains(double[] values, double x, double epsilon) { assertContains(null, values, x, epsilon); } /** verifies that two matrices are close (1-norm) */ public static void assertEquals(String msg, RealMatrix expected, RealMatrix observed, double tolerance) { Assert.assertNotNull(msg + "\nObserved should not be null",observed); if (expected.getColumnDimension() != observed.getColumnDimension() || expected.getRowDimension() != observed.getRowDimension()) { StringBuilder messageBuffer = new StringBuilder(msg); messageBuffer.append("\nObserved has incorrect dimensions."); messageBuffer.append("\nobserved is " + observed.getRowDimension() + " x " + observed.getColumnDimension()); messageBuffer.append("\nexpected " + expected.getRowDimension() + " x " + expected.getColumnDimension()); Assert.fail(messageBuffer.toString()); } RealMatrix delta = expected.subtract(observed); if (delta.getNorm() >= tolerance) { StringBuilder messageBuffer = new StringBuilder(msg); messageBuffer.append("\nExpected: " + expected); messageBuffer.append("\nObserved: " + observed); messageBuffer.append("\nexpected - observed: " + delta); Assert.fail(messageBuffer.toString()); } } /** verifies that two matrices are equal */ public static void assertEquals(FieldMatrix> expected, FieldMatrix> observed) { Assert.assertNotNull("Observed should not be null",observed); if (expected.getColumnDimension() != observed.getColumnDimension() || expected.getRowDimension() != observed.getRowDimension()) { StringBuilder messageBuffer = new StringBuilder(); messageBuffer.append("Observed has incorrect dimensions."); messageBuffer.append("\nobserved is " + observed.getRowDimension() + " x " + observed.getColumnDimension()); messageBuffer.append("\nexpected " + expected.getRowDimension() + " x " + expected.getColumnDimension()); Assert.fail(messageBuffer.toString()); } for (int i = 0; i < expected.getRowDimension(); ++i) { for (int j = 0; j < expected.getColumnDimension(); ++j) { FieldElement eij = expected.getEntry(i, j); FieldElement oij = observed.getEntry(i, j); Assert.assertEquals(eij, oij); } } } /** verifies that two arrays are close (sup norm) */ public static void assertEquals(String msg, double[] expected, double[] observed, double tolerance) { StringBuilder out = new StringBuilder(msg); if (expected.length != observed.length) { out.append("\n Arrays not same length. \n"); out.append("expected has length "); out.append(expected.length); out.append(" observed length = "); out.append(observed.length); Assert.fail(out.toString()); } boolean failure = false; for (int i=0; i < expected.length; i++) { try { assertEquals(expected[i], observed[i], tolerance); } catch (AssertionFailedError ex) { failure = true; out.append("\n Elements at index "); out.append(i); out.append(" differ. "); out.append(" expected = "); out.append(expected[i]); out.append(" observed = "); out.append(observed[i]); } } if (failure) { Assert.fail(out.toString()); } } /** verifies that two arrays are equal */ public static > void assertEquals(T[] m, T[] n) { if (m.length != n.length) { Assert.fail("vectors not same length"); } for (int i = 0; i < m.length; i++) { Assert.assertEquals(m[i],n[i]); } } /** * Computes the sum of squared deviations of from * @param values array of deviates * @param target value to compute deviations from * * @return sum of squared deviations */ public static double sumSquareDev(double[] values, double target) { double sumsq = 0d; for (int i = 0; i < values.length; i++) { final double dev = values[i] - target; sumsq += (dev * dev); } return sumsq; } /** * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)% * * @param valueLabels * @param expected expected counts * @param observed observed counts * @param alpha significance level of the test */ public static void assertChiSquareAccept(String[] valueLabels, double[] expected, long[] observed, double alpha) throws Exception { ChiSquareTest chiSquareTest = new ChiSquareTestImpl(); try { // Fail if we can reject null hypothesis that distributions are the same Assert.assertFalse(chiSquareTest.chiSquareTest(expected, observed, alpha)); } catch (AssertionFailedError ex) { StringBuilder msgBuffer = new StringBuilder(); DecimalFormat df = new DecimalFormat("#.##"); msgBuffer.append("Chisquare test failed"); msgBuffer.append(" p-value = "); msgBuffer.append(chiSquareTest.chiSquareTest(expected, observed)); msgBuffer.append(" chisquare statistic = "); msgBuffer.append(chiSquareTest.chiSquare(expected, observed)); msgBuffer.append(". \n"); msgBuffer.append("value\texpected\tobserved\n"); for (int i = 0; i < expected.length; i++) { msgBuffer.append(valueLabels[i]); msgBuffer.append("\t"); msgBuffer.append(df.format(expected[i])); msgBuffer.append("\t\t"); msgBuffer.append(observed[i]); msgBuffer.append("\n"); } msgBuffer.append("This test can fail randomly due to sampling error with probability "); msgBuffer.append(alpha); msgBuffer.append("."); Assert.fail(msgBuffer.toString()); } } /** * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)% * * @param values * @param expected expected counts * @param observed observed counts * @param alpha significance level of the test */ public static void assertChiSquareAccept(int[] values, double[] expected, long[] observed, double alpha) throws Exception { String[] labels = new String[values.length]; for (int i = 0; i < values.length; i++) { labels[i] = Integer.toString(values[i]); } assertChiSquareAccept(labels, expected, observed, alpha); } /** * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)% * * @param values * @param expected expected counts * @param observed observed counts * @param alpha significance level of the test */ public static void assertChiSquareAccept(double[] values, double[] expected, long[] observed, double alpha) throws Exception { String[] labels = new String[values.length]; for (int i = 0; i < values.length; i++) { labels[i] = Double.toString(values[i]); } assertChiSquareAccept(labels, expected, observed, alpha); } /** * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)% * * @param expected expected counts * @param observed observed counts * @param alpha significance level of the test */ public static void assertChiSquareAccept(double[] expected, long[] observed, double alpha) throws Exception { String[] labels = new String[expected.length]; for (int i = 0; i < labels.length; i++) { labels[i] = Integer.toString(i + 1); } assertChiSquareAccept(labels, expected, observed, alpha); } /** * Computes the 25th, 50th and 75th percentiles of the given distribution and returns * these values in an array. */ public static double[] getDistributionQuartiles(ContinuousDistribution distribution) throws Exception { double[] quantiles = new double[3]; quantiles[0] = distribution.inverseCumulativeProbability(0.25d); quantiles[1] = distribution.inverseCumulativeProbability(0.5d); quantiles[2] = distribution.inverseCumulativeProbability(0.75d); return quantiles; } /** * Updates observed counts of values in quartiles. * counts[0] <-> 1st quartile ... counts[3] <-> top quartile */ public static void updateCounts(double value, long[] counts, double[] quartiles) { if (value < quartiles[0]) { counts[0]++; } else if (value > quartiles[2]) { counts[3]++; } else if (value > quartiles[1]) { counts[2]++; } else { counts[1]++; } } /** * Eliminates points with zero mass from densityPoints and densityValues parallel * arrays. Returns the number of positive mass points and collapses the arrays so * that the first elements of the input arrays represent the positive * mass points. */ public static int eliminateZeroMassPoints(int[] densityPoints, double[] densityValues) { int positiveMassCount = 0; for (int i = 0; i < densityValues.length; i++) { if (densityValues[i] > 0) { positiveMassCount++; } } if (positiveMassCount < densityValues.length) { int[] newPoints = new int[positiveMassCount]; double[] newValues = new double[positiveMassCount]; int j = 0; for (int i = 0; i < densityValues.length; i++) { if (densityValues[i] > 0) { newPoints[j] = densityPoints[i]; newValues[j] = densityValues[i]; j++; } } System.arraycopy(newPoints,0,densityPoints,0,positiveMassCount); System.arraycopy(newValues,0,densityValues,0,positiveMassCount); } return positiveMassCount; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/FunctionEvaluationExceptionTest.java100644 1750 1750 14043 11532241244 31617 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.util.Locale; import org.apache.commons.math.exception.util.LocalizedFormats; import junit.framework.TestCase; /** * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ * @deprecated in 2.2 (to be removed in 3.0) */ @Deprecated public class FunctionEvaluationExceptionTest extends TestCase { public void testConstructor(){ FunctionEvaluationException ex = new FunctionEvaluationException(0.0); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("0") > 0); assertEquals(0.0, ex.getArgument()[0], 0); } public void testConstructorArray(){ FunctionEvaluationException ex = new FunctionEvaluationException(new double[] { 0, 1, 2 }); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("0") > 0); assertEquals(0.0, ex.getArgument()[0], 0); assertEquals(1.0, ex.getArgument()[1], 0); assertEquals(2.0, ex.getArgument()[2], 0); } public void testConstructorPatternArguments(){ LocalizedFormats pattern = LocalizedFormats.EVALUATION_FAILED; Object[] arguments = { Double.valueOf(0.0) }; FunctionEvaluationException ex = new FunctionEvaluationException(0.0, pattern, arguments); assertNull(ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorArrayPatternArguments(){ LocalizedFormats pattern = LocalizedFormats.EVALUATION_FAILED; Object[] arguments = { Double.valueOf(0.0) }; FunctionEvaluationException ex = new FunctionEvaluationException(new double[] { 0, 1, 2 }, pattern, arguments); assertNull(ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); assertEquals(0.0, ex.getArgument()[0], 0); assertEquals(1.0, ex.getArgument()[1], 0); assertEquals(2.0, ex.getArgument()[2], 0); } public void testConstructorPatternArgumentsCause(){ LocalizedFormats pattern = LocalizedFormats.EVALUATION_FAILED; Object[] arguments = { Double.valueOf(0.0) }; String inMsg = "inner message"; Exception cause = new Exception(inMsg); FunctionEvaluationException ex = new FunctionEvaluationException(cause, 0.0, pattern, arguments); assertEquals(cause, ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorArrayPatternArgumentsCause(){ LocalizedFormats pattern = LocalizedFormats.EVALUATION_FAILED; Object[] arguments = { Double.valueOf(0.0) }; String inMsg = "inner message"; Exception cause = new Exception(inMsg); FunctionEvaluationException ex = new FunctionEvaluationException(cause, new double[] { 0, 1, 2 }, pattern, arguments); assertEquals(cause, ex.getCause()); assertEquals(pattern, ex.getGeneralPattern()); assertEquals(arguments.length, ex.getArguments().length); for (int i = 0; i < arguments.length; ++i) { assertEquals(arguments[i], ex.getArguments()[i]); } assertFalse(pattern.equals(ex.getMessage())); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); assertEquals(0.0, ex.getArgument()[0], 0); assertEquals(1.0, ex.getArgument()[1], 0); assertEquals(2.0, ex.getArgument()[2], 0); } public void testConstructorArgumentCause(){ String inMsg = "inner message"; Exception cause = new Exception(inMsg); FunctionEvaluationException ex = new FunctionEvaluationException(cause, 0.0); assertEquals(cause, ex.getCause()); assertTrue(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testConstructorArrayArgumentCause(){ String inMsg = "inner message"; Exception cause = new Exception(inMsg); FunctionEvaluationException ex = new FunctionEvaluationException(cause, new double[] { 0, 1, 2 }); assertEquals(cause, ex.getCause()); assertTrue(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); assertEquals(0.0, ex.getArgument()[0], 0); assertEquals(1.0, ex.getArgument()[1], 0); assertEquals(2.0, ex.getArgument()[2], 0); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/dfp/DfpMathTest.java100644 1750 1750 44526 11532241242 26226 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class DfpMathTest { private DfpField factory; private Dfp pinf; private Dfp ninf; private Dfp nan; private Dfp qnan; @Before public void setUp() { // Some basic setup. Define some constants and clear the status flags factory = new DfpField(20); pinf = factory.newDfp("1").divide(factory.newDfp("0")); ninf = factory.newDfp("-1").divide(factory.newDfp("0")); nan = factory.newDfp("0").divide(factory.newDfp("0")); qnan = factory.newDfp((byte)1, Dfp.QNAN); ninf.getField().clearIEEEFlags(); // force loading of dfpmath Dfp pi = factory.getPi(); pi.getField().clearIEEEFlags(); } @After public void tearDown() { pinf = null; ninf = null; nan = null; qnan = null; } // Generic test function. Takes params x and y and tests them for // equality. Then checks the status flags against the flags argument. // If the test fail, it prints the desc string private void test(Dfp x, Dfp y, int flags, String desc) { boolean b = x.equals(y); if (!x.equals(y) && !x.unequal(y)) // NaNs involved b = (x.toString().equals(y.toString())); if (x.equals(factory.newDfp("0"))) // distinguish +/- zero b = (b && (x.toString().equals(y.toString()))); b = (b && x.getField().getIEEEFlags() == flags); if (!b) Assert.assertTrue("assersion failed "+desc+" x = "+x.toString()+" flags = "+x.getField().getIEEEFlags(), b); x.getField().clearIEEEFlags(); } @Test public void testPow() { // Test special cases exponent of zero test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("0")), factory.newDfp("1"), 0, "pow #1"); test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-0")), factory.newDfp("1"), 0, "pow #2"); test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("0")), factory.newDfp("1"), 0, "pow #3"); test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-0")), factory.newDfp("1"), 0, "pow #4"); test(DfpMath.pow(pinf, factory.newDfp("-0")), factory.newDfp("1"), 0, "pow #5"); test(DfpMath.pow(pinf, factory.newDfp("0")), factory.newDfp("1"), 0, "pow #6"); test(DfpMath.pow(ninf, factory.newDfp("-0")), factory.newDfp("1"), 0, "pow #7"); test(DfpMath.pow(ninf, factory.newDfp("0")), factory.newDfp("1"), 0, "pow #8"); test(DfpMath.pow(qnan, factory.newDfp("0")), factory.newDfp("1"), 0, "pow #8"); // exponent of one test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")), factory.newDfp("0"), 0, "pow #9"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1")), factory.newDfp("-0"), 0, "pow #10"); test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("1")), factory.newDfp("2"), 0, "pow #11"); test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("1")), factory.newDfp("-2"), 0, "pow #12"); test(DfpMath.pow(pinf, factory.newDfp("1")), pinf, 0, "pow #13"); test(DfpMath.pow(ninf, factory.newDfp("1")), ninf, 0, "pow #14"); test(DfpMath.pow(qnan, factory.newDfp("1")), qnan, DfpField.FLAG_INVALID, "pow #14.1"); // exponent of NaN test(DfpMath.pow(factory.newDfp("0"), qnan), qnan, DfpField.FLAG_INVALID, "pow #15"); test(DfpMath.pow(factory.newDfp("-0"), qnan), qnan, DfpField.FLAG_INVALID, "pow #16"); test(DfpMath.pow(factory.newDfp("2"), qnan), qnan, DfpField.FLAG_INVALID, "pow #17"); test(DfpMath.pow(factory.newDfp("-2"), qnan), qnan, DfpField.FLAG_INVALID, "pow #18"); test(DfpMath.pow(pinf, qnan), qnan, DfpField.FLAG_INVALID, "pow #19"); test(DfpMath.pow(ninf, qnan), qnan, DfpField.FLAG_INVALID, "pow #20"); test(DfpMath.pow(qnan, qnan), qnan, DfpField.FLAG_INVALID, "pow #21"); // radix of NaN test(DfpMath.pow(qnan, factory.newDfp("1")), qnan, DfpField.FLAG_INVALID, "pow #22"); test(DfpMath.pow(qnan, factory.newDfp("-1")), qnan, DfpField.FLAG_INVALID, "pow #23"); test(DfpMath.pow(qnan, pinf), qnan, DfpField.FLAG_INVALID, "pow #24"); test(DfpMath.pow(qnan, ninf), qnan, DfpField.FLAG_INVALID, "pow #25"); test(DfpMath.pow(qnan, qnan), qnan, DfpField.FLAG_INVALID, "pow #26"); // (x > 1) ^ pinf = pinf, (x < -1) ^ pinf = pinf test(DfpMath.pow(factory.newDfp("2"), pinf), pinf, 0, "pow #27"); test(DfpMath.pow(factory.newDfp("-2"), pinf), pinf, 0, "pow #28"); test(DfpMath.pow(pinf, pinf), pinf, 0, "pow #29"); test(DfpMath.pow(ninf, pinf), pinf, 0, "pow #30"); // (x > 1) ^ ninf = +0, (x < -1) ^ ninf = +0 test(DfpMath.pow(factory.newDfp("2"), ninf), factory.getZero(), 0, "pow #31"); test(DfpMath.pow(factory.newDfp("-2"), ninf), factory.getZero(), 0, "pow #32"); test(DfpMath.pow(pinf, ninf), factory.getZero(), 0, "pow #33"); test(DfpMath.pow(ninf, ninf), factory.getZero(), 0, "pow #34"); // (-1 < x < 1) ^ pinf = 0 test(DfpMath.pow(factory.newDfp("0.5"), pinf), factory.getZero(), 0, "pow #35"); test(DfpMath.pow(factory.newDfp("-0.5"), pinf), factory.getZero(), 0, "pow #36"); // (-1 < x < 1) ^ ninf = pinf test(DfpMath.pow(factory.newDfp("0.5"), ninf), pinf, 0, "pow #37"); test(DfpMath.pow(factory.newDfp("-0.5"), ninf), pinf, 0, "pow #38"); // +/- 1 ^ +/-inf = NaN test(DfpMath.pow(factory.getOne(), pinf), qnan, DfpField.FLAG_INVALID, "pow #39"); test(DfpMath.pow(factory.getOne(), ninf), qnan, DfpField.FLAG_INVALID, "pow #40"); test(DfpMath.pow(factory.newDfp("-1"), pinf), qnan, DfpField.FLAG_INVALID, "pow #41"); test(DfpMath.pow(factory.getOne().negate(), ninf), qnan, DfpField.FLAG_INVALID, "pow #42"); // +0 ^ +anything except 0, NAN = +0 test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")), factory.newDfp("0"), 0, "pow #43"); test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e30")), factory.newDfp("0"), 0, "pow #44"); test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e-30")), factory.newDfp("0"), 0, "pow #45"); test(DfpMath.pow(factory.newDfp("0"), pinf), factory.newDfp("0"), 0, "pow #46"); // -0 ^ +anything except 0, NAN, odd integer = +0 test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("2")), factory.newDfp("0"), 0, "pow #47"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e30")), factory.newDfp("0"), 0, "pow #48"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e-30")), factory.newDfp("0"), DfpField.FLAG_INEXACT, "pow #49"); test(DfpMath.pow(factory.newDfp("-0"), pinf), factory.newDfp("0"), 0, "pow #50"); // +0 ^ -anything except 0, NAN = +INF test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1")), pinf, 0, "pow #51"); test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e30")), pinf, 0, "pow #52"); test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e-30")), pinf, 0, "pow #53"); test(DfpMath.pow(factory.newDfp("0"), ninf), pinf, 0, "pow #54"); // -0 ^ -anything except 0, NAN, odd integer = +INF test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-2")), pinf, 0, "pow #55"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e30")), pinf, 0, "pow #56"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e-30")), pinf, DfpField.FLAG_INEXACT, "pow #57"); test(DfpMath.pow(factory.newDfp("-0"), ninf), pinf, 0, "pow #58"); // -0 ^ -odd integer = -INF test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1")), ninf, DfpField.FLAG_INEXACT, "pow #59"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-12345")), ninf, DfpField.FLAG_INEXACT, "pow #60"); // -0 ^ +odd integer = -0 test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("3")), factory.newDfp("-0"), DfpField.FLAG_INEXACT, "pow #61"); test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("12345")), factory.newDfp("-0"), DfpField.FLAG_INEXACT, "pow #62"); // pinf ^ +anything = pinf test(DfpMath.pow(pinf, factory.newDfp("3")), pinf, 0, "pow #63"); test(DfpMath.pow(pinf, factory.newDfp("1e30")), pinf, 0, "pow #64"); test(DfpMath.pow(pinf, factory.newDfp("1e-30")), pinf, 0, "pow #65"); test(DfpMath.pow(pinf, pinf), pinf, 0, "pow #66"); // pinf ^ -anything = +0 test(DfpMath.pow(pinf, factory.newDfp("-3")), factory.getZero(), 0, "pow #67"); test(DfpMath.pow(pinf, factory.newDfp("-1e30")), factory.getZero(), 0, "pow #68"); test(DfpMath.pow(pinf, factory.newDfp("-1e-30")), factory.getZero(), 0, "pow #69"); test(DfpMath.pow(pinf, ninf), factory.getZero(), 0, "pow #70"); // ninf ^ anything = -0 ^ -anything // ninf ^ -anything except 0, NAN, odd integer = +0 test(DfpMath.pow(ninf, factory.newDfp("-2")), factory.newDfp("0"), 0, "pow #71"); test(DfpMath.pow(ninf, factory.newDfp("-1e30")), factory.newDfp("0"), 0, "pow #72"); test(DfpMath.pow(ninf, factory.newDfp("-1e-30")), factory.newDfp("0"), DfpField.FLAG_INEXACT, "pow #73"); test(DfpMath.pow(ninf, ninf), factory.newDfp("0"), 0, "pow #74"); // ninf ^ +anything except 0, NAN, odd integer = +INF test(DfpMath.pow(ninf, factory.newDfp("2")), pinf, 0, "pow #75"); test(DfpMath.pow(ninf, factory.newDfp("1e30")), pinf, 0, "pow #76"); test(DfpMath.pow(ninf, factory.newDfp("1e-30")), pinf, DfpField.FLAG_INEXACT, "pow #77"); test(DfpMath.pow(ninf, pinf), pinf, 0, "pow #78"); // ninf ^ +odd integer = -INF test(DfpMath.pow(ninf, factory.newDfp("3")), ninf, DfpField.FLAG_INEXACT, "pow #79"); test(DfpMath.pow(ninf, factory.newDfp("12345")), ninf, DfpField.FLAG_INEXACT, "pow #80"); // ninf ^ -odd integer = -0 test(DfpMath.pow(ninf, factory.newDfp("-3")), factory.newDfp("-0"), DfpField.FLAG_INEXACT, "pow #81"); test(DfpMath.pow(ninf, factory.newDfp("-12345")), factory.newDfp("-0"), DfpField.FLAG_INEXACT, "pow #82"); // -anything ^ integer test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("3")), factory.newDfp("-8"), DfpField.FLAG_INEXACT, "pow #83"); test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("16")), factory.newDfp("65536"), 0, "pow #84"); test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-3")), factory.newDfp("-0.125"), DfpField.FLAG_INEXACT, "pow #85"); test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4")), factory.newDfp("0.0625"), 0, "pow #86"); // -anything ^ noninteger = NaN test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4.1")), qnan, DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "pow #87"); // Some fractional cases. test(DfpMath.pow(factory.newDfp("2"),factory.newDfp("1.5")), factory.newDfp("2.8284271247461901"), DfpField.FLAG_INEXACT, "pow #88"); } @Test public void testSin() { test(DfpMath.sin(pinf), nan, DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #1"); test(DfpMath.sin(nan), nan, DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #2"); test(DfpMath.sin(factory.getZero()), factory.getZero(), DfpField.FLAG_INEXACT, "sin #3"); test(DfpMath.sin(factory.getPi()), factory.getZero(), DfpField.FLAG_INEXACT, "sin #4"); test(DfpMath.sin(factory.getPi().negate()), factory.newDfp("-0"), DfpField.FLAG_INEXACT, "sin #5"); test(DfpMath.sin(factory.getPi().multiply(2)), factory.getZero(), DfpField.FLAG_INEXACT, "sin #6"); test(DfpMath.sin(factory.getPi().divide(2)), factory.getOne(), DfpField.FLAG_INEXACT, "sin #7"); test(DfpMath.sin(factory.getPi().divide(2).negate()), factory.getOne().negate(), DfpField.FLAG_INEXACT, "sin #8"); test(DfpMath.sin(DfpMath.atan(factory.getOne())), // pi/4 factory.newDfp("0.5").sqrt(), DfpField.FLAG_INEXACT, "sin #9"); test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(), // -pi/4 factory.newDfp("0.5").sqrt().negate(), DfpField.FLAG_INEXACT, "sin #10"); test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(), // -pi/4 factory.newDfp("0.5").sqrt().negate(), DfpField.FLAG_INEXACT, "sin #11"); test(DfpMath.sin(factory.newDfp("0.1")), factory.newDfp("0.0998334166468281523"), DfpField.FLAG_INEXACT, "sin #12"); test(DfpMath.sin(factory.newDfp("0.2")), factory.newDfp("0.19866933079506121546"), DfpField.FLAG_INEXACT, "sin #13"); test(DfpMath.sin(factory.newDfp("0.3")), factory.newDfp("0.2955202066613395751"), DfpField.FLAG_INEXACT, "sin #14"); test(DfpMath.sin(factory.newDfp("0.4")), factory.newDfp("0.38941834230865049166"), DfpField.FLAG_INEXACT, "sin #15"); test(DfpMath.sin(factory.newDfp("0.5")), factory.newDfp("0.47942553860420300026"), // off by one ULP DfpField.FLAG_INEXACT, "sin #16"); test(DfpMath.sin(factory.newDfp("0.6")), factory.newDfp("0.56464247339503535721"), // off by one ULP DfpField.FLAG_INEXACT, "sin #17"); test(DfpMath.sin(factory.newDfp("0.7")), factory.newDfp("0.64421768723769105367"), DfpField.FLAG_INEXACT, "sin #18"); test(DfpMath.sin(factory.newDfp("0.8")), factory.newDfp("0.71735609089952276163"), DfpField.FLAG_INEXACT, "sin #19"); test(DfpMath.sin(factory.newDfp("0.9")), // off by one ULP factory.newDfp("0.78332690962748338847"), DfpField.FLAG_INEXACT, "sin #20"); test(DfpMath.sin(factory.newDfp("1.0")), factory.newDfp("0.84147098480789650666"), DfpField.FLAG_INEXACT, "sin #21"); test(DfpMath.sin(factory.newDfp("1.1")), factory.newDfp("0.89120736006143533995"), DfpField.FLAG_INEXACT, "sin #22"); test(DfpMath.sin(factory.newDfp("1.2")), factory.newDfp("0.93203908596722634968"), DfpField.FLAG_INEXACT, "sin #23"); test(DfpMath.sin(factory.newDfp("1.3")), factory.newDfp("0.9635581854171929647"), DfpField.FLAG_INEXACT, "sin #24"); test(DfpMath.sin(factory.newDfp("1.4")), factory.newDfp("0.98544972998846018066"), DfpField.FLAG_INEXACT, "sin #25"); test(DfpMath.sin(factory.newDfp("1.5")), factory.newDfp("0.99749498660405443096"), DfpField.FLAG_INEXACT, "sin #26"); test(DfpMath.sin(factory.newDfp("1.6")), factory.newDfp("0.99957360304150516323"), DfpField.FLAG_INEXACT, "sin #27"); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/dfp/DfpTest.java100644 1750 1750 170114 11532241242 25425 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class DfpTest { private DfpField field; private Dfp pinf; private Dfp ninf; private Dfp nan; private Dfp snan; private Dfp qnan; @Before public void setUp() { // Some basic setup. Define some constants and clear the status flags field = new DfpField(20); pinf = field.newDfp("1").divide(field.newDfp("0")); ninf = field.newDfp("-1").divide(field.newDfp("0")); nan = field.newDfp("0").divide(field.newDfp("0")); snan = field.newDfp((byte)1, Dfp.SNAN); qnan = field.newDfp((byte)1, Dfp.QNAN); ninf.getField().clearIEEEFlags(); } @After public void tearDown() { field = null; pinf = null; ninf = null; nan = null; snan = null; qnan = null; } // Generic test function. Takes params x and y and tests them for // equality. Then checks the status flags against the flags argument. // If the test fail, it prints the desc string private void test(Dfp x, Dfp y, int flags, String desc) { boolean b = x.equals(y); if (!x.equals(y) && !x.unequal(y)) // NaNs involved b = (x.toString().equals(y.toString())); if (x.equals(field.newDfp("0"))) // distinguish +/- zero b = (b && (x.toString().equals(y.toString()))); b = (b && x.getField().getIEEEFlags() == flags); if (!b) Assert.assertTrue("assersion failed "+desc+" x = "+x.toString()+" flags = "+x.getField().getIEEEFlags(), b); x.getField().clearIEEEFlags(); } @Test public void testByteConstructor() { Assert.assertEquals("0.", new Dfp(field, (byte) 0).toString()); Assert.assertEquals("1.", new Dfp(field, (byte) 1).toString()); Assert.assertEquals("-1.", new Dfp(field, (byte) -1).toString()); Assert.assertEquals("-128.", new Dfp(field, Byte.MIN_VALUE).toString()); Assert.assertEquals("127.", new Dfp(field, Byte.MAX_VALUE).toString()); } @Test public void testIntConstructor() { Assert.assertEquals("0.", new Dfp(field, 0).toString()); Assert.assertEquals("1.", new Dfp(field, 1).toString()); Assert.assertEquals("-1.", new Dfp(field, -1).toString()); Assert.assertEquals("1234567890.", new Dfp(field, 1234567890).toString()); Assert.assertEquals("-1234567890.", new Dfp(field, -1234567890).toString()); Assert.assertEquals("-2147483648.", new Dfp(field, Integer.MIN_VALUE).toString()); Assert.assertEquals("2147483647.", new Dfp(field, Integer.MAX_VALUE).toString()); } @Test public void testLongConstructor() { Assert.assertEquals("0.", new Dfp(field, 0l).toString()); Assert.assertEquals("1.", new Dfp(field, 1l).toString()); Assert.assertEquals("-1.", new Dfp(field, -1l).toString()); Assert.assertEquals("1234567890.", new Dfp(field, 1234567890l).toString()); Assert.assertEquals("-1234567890.", new Dfp(field, -1234567890l).toString()); Assert.assertEquals("-9223372036854775808.", new Dfp(field, Long.MIN_VALUE).toString()); Assert.assertEquals("9223372036854775807.", new Dfp(field, Long.MAX_VALUE).toString()); } /* * Test addition */ @Test public void testAdd() { test(field.newDfp("1").add(field.newDfp("1")), // Basic tests 1+1 = 2 field.newDfp("2"), 0, "Add #1"); test(field.newDfp("1").add(field.newDfp("-1")), // 1 + (-1) = 0 field.newDfp("0"), 0, "Add #2"); test(field.newDfp("-1").add(field.newDfp("1")), // (-1) + 1 = 0 field.newDfp("0"), 0, "Add #3"); test(field.newDfp("-1").add(field.newDfp("-1")), // (-1) + (-1) = -2 field.newDfp("-2"), 0, "Add #4"); // rounding mode is round half even test(field.newDfp("1").add(field.newDfp("1e-16")), // rounding on add field.newDfp("1.0000000000000001"), 0, "Add #5"); test(field.newDfp("1").add(field.newDfp("1e-17")), // rounding on add field.newDfp("1"), DfpField.FLAG_INEXACT, "Add #6"); test(field.newDfp("0.90999999999999999999").add(field.newDfp("0.1")), // rounding on add field.newDfp("1.01"), DfpField.FLAG_INEXACT, "Add #7"); test(field.newDfp(".10000000000000005000").add(field.newDfp(".9")), // rounding on add field.newDfp("1."), DfpField.FLAG_INEXACT, "Add #8"); test(field.newDfp(".10000000000000015000").add(field.newDfp(".9")), // rounding on add field.newDfp("1.0000000000000002"), DfpField.FLAG_INEXACT, "Add #9"); test(field.newDfp(".10000000000000014999").add(field.newDfp(".9")), // rounding on add field.newDfp("1.0000000000000001"), DfpField.FLAG_INEXACT, "Add #10"); test(field.newDfp(".10000000000000015001").add(field.newDfp(".9")), // rounding on add field.newDfp("1.0000000000000002"), DfpField.FLAG_INEXACT, "Add #11"); test(field.newDfp(".11111111111111111111").add(field.newDfp("11.1111111111111111")), // rounding on add field.newDfp("11.22222222222222222222"), DfpField.FLAG_INEXACT, "Add #12"); test(field.newDfp(".11111111111111111111").add(field.newDfp("1111111111111111.1111")), // rounding on add field.newDfp("1111111111111111.2222"), DfpField.FLAG_INEXACT, "Add #13"); test(field.newDfp(".11111111111111111111").add(field.newDfp("11111111111111111111")), // rounding on add field.newDfp("11111111111111111111"), DfpField.FLAG_INEXACT, "Add #14"); test(field.newDfp("9.9999999999999999999e131071").add(field.newDfp("-1e131052")), // overflow on add field.newDfp("9.9999999999999999998e131071"), 0, "Add #15"); test(field.newDfp("9.9999999999999999999e131071").add(field.newDfp("1e131052")), // overflow on add pinf, DfpField.FLAG_OVERFLOW, "Add #16"); test(field.newDfp("-9.9999999999999999999e131071").add(field.newDfp("-1e131052")), // overflow on add ninf, DfpField.FLAG_OVERFLOW, "Add #17"); test(field.newDfp("-9.9999999999999999999e131071").add(field.newDfp("1e131052")), // overflow on add field.newDfp("-9.9999999999999999998e131071"), 0, "Add #18"); test(field.newDfp("1e-131072").add(field.newDfp("1e-131072")), // underflow on add field.newDfp("2e-131072"), 0, "Add #19"); test(field.newDfp("1.0000000000000001e-131057").add(field.newDfp("-1e-131057")), // underflow on add field.newDfp("1e-131073"), DfpField.FLAG_UNDERFLOW, "Add #20"); test(field.newDfp("1.1e-131072").add(field.newDfp("-1e-131072")), // underflow on add field.newDfp("1e-131073"), DfpField.FLAG_UNDERFLOW, "Add #21"); test(field.newDfp("1.0000000000000001e-131072").add(field.newDfp("-1e-131072")), // underflow on add field.newDfp("1e-131088"), DfpField.FLAG_UNDERFLOW, "Add #22"); test(field.newDfp("1.0000000000000001e-131078").add(field.newDfp("-1e-131078")), // underflow on add field.newDfp("0"), DfpField.FLAG_UNDERFLOW, "Add #23"); test(field.newDfp("1.0").add(field.newDfp("-1e-20")), // loss of precision on alignment? field.newDfp("0.99999999999999999999"), 0, "Add #23.1"); test(field.newDfp("-0.99999999999999999999").add(field.newDfp("1")), // proper normalization? field.newDfp("0.00000000000000000001"), 0, "Add #23.2"); test(field.newDfp("1").add(field.newDfp("0")), // adding zeros field.newDfp("1"), 0, "Add #24"); test(field.newDfp("0").add(field.newDfp("0")), // adding zeros field.newDfp("0"), 0, "Add #25"); test(field.newDfp("-0").add(field.newDfp("0")), // adding zeros field.newDfp("0"), 0, "Add #26"); test(field.newDfp("0").add(field.newDfp("-0")), // adding zeros field.newDfp("0"), 0, "Add #27"); test(field.newDfp("-0").add(field.newDfp("-0")), // adding zeros field.newDfp("-0"), 0, "Add #28"); test(field.newDfp("1e-20").add(field.newDfp("0")), // adding zeros field.newDfp("1e-20"), 0, "Add #29"); test(field.newDfp("1e-40").add(field.newDfp("0")), // adding zeros field.newDfp("1e-40"), 0, "Add #30"); test(pinf.add(ninf), // adding infinities nan, DfpField.FLAG_INVALID, "Add #31"); test(ninf.add(pinf), // adding infinities nan, DfpField.FLAG_INVALID, "Add #32"); test(ninf.add(ninf), // adding infinities ninf, 0, "Add #33"); test(pinf.add(pinf), // adding infinities pinf, 0, "Add #34"); test(pinf.add(field.newDfp("0")), // adding infinities pinf, 0, "Add #35"); test(pinf.add(field.newDfp("-1e131071")), // adding infinities pinf, 0, "Add #36"); test(pinf.add(field.newDfp("1e131071")), // adding infinities pinf, 0, "Add #37"); test(field.newDfp("0").add(pinf), // adding infinities pinf, 0, "Add #38"); test(field.newDfp("-1e131071").add(pinf), // adding infinities pinf, 0, "Add #39"); test(field.newDfp("1e131071").add(pinf), // adding infinities pinf, 0, "Add #40"); test(ninf.add(field.newDfp("0")), // adding infinities ninf, 0, "Add #41"); test(ninf.add(field.newDfp("-1e131071")), // adding infinities ninf, 0, "Add #42"); test(ninf.add(field.newDfp("1e131071")), // adding infinities ninf, 0, "Add #43"); test(field.newDfp("0").add(ninf), // adding infinities ninf, 0, "Add #44"); test(field.newDfp("-1e131071").add(ninf), // adding infinities ninf, 0, "Add #45"); test(field.newDfp("1e131071").add(ninf), // adding infinities ninf, 0, "Add #46"); test(field.newDfp("9.9999999999999999999e131071").add(field.newDfp("5e131051")), // overflow pinf, DfpField.FLAG_OVERFLOW, "Add #47"); test(field.newDfp("9.9999999999999999999e131071").add(field.newDfp("4.9999999999999999999e131051")), // overflow field.newDfp("9.9999999999999999999e131071"), DfpField.FLAG_INEXACT, "Add #48"); test(nan.add(field.newDfp("1")), nan, 0, "Add #49"); test(field.newDfp("1").add(nan), nan, 0, "Add #50"); test(field.newDfp("12345678123456781234").add(field.newDfp("0.12345678123456781234")), field.newDfp("12345678123456781234"), DfpField.FLAG_INEXACT, "Add #51"); test(field.newDfp("12345678123456781234").add(field.newDfp("123.45678123456781234")), field.newDfp("12345678123456781357"), DfpField.FLAG_INEXACT, "Add #52"); test(field.newDfp("123.45678123456781234").add(field.newDfp("12345678123456781234")), field.newDfp("12345678123456781357"), DfpField.FLAG_INEXACT, "Add #53"); test(field.newDfp("12345678123456781234").add(field.newDfp(".00001234567812345678")), field.newDfp("12345678123456781234"), DfpField.FLAG_INEXACT, "Add #54"); test(field.newDfp("12345678123456781234").add(field.newDfp(".00000000123456781234")), field.newDfp("12345678123456781234"), DfpField.FLAG_INEXACT, "Add #55"); test(field.newDfp("-0").add(field.newDfp("-0")), field.newDfp("-0"), 0, "Add #56"); test(field.newDfp("0").add(field.newDfp("-0")), field.newDfp("0"), 0, "Add #57"); test(field.newDfp("-0").add(field.newDfp("0")), field.newDfp("0"), 0, "Add #58"); test(field.newDfp("0").add(field.newDfp("0")), field.newDfp("0"), 0, "Add #59"); } //////////////////////////////////////////////////////////////////////////////////////////////////////// // Test comparisons // utility function to help test comparisons private void cmptst(Dfp a, Dfp b, String op, boolean result, double num) { if (op == "equal") if (a.equals(b) != result) Assert.fail("assersion failed. "+op+" compare #"+num); if (op == "unequal") if (a.unequal(b) != result) Assert.fail("assersion failed. "+op+" compare #"+num); if (op == "lessThan") if (a.lessThan(b) != result) Assert.fail("assersion failed. "+op+" compare #"+num); if (op == "greaterThan") if (a.greaterThan(b) != result) Assert.fail("assersion failed. "+op+" compare #"+num); } @Test public void testCompare() { // test equal() comparison // check zero vs. zero field.clearIEEEFlags(); cmptst(field.newDfp("0"), field.newDfp("0"), "equal", true, 1); // 0 == 0 cmptst(field.newDfp("0"), field.newDfp("-0"), "equal", true, 2); // 0 == -0 cmptst(field.newDfp("-0"), field.newDfp("-0"), "equal", true, 3); // -0 == -0 cmptst(field.newDfp("-0"), field.newDfp("0"), "equal", true, 4); // -0 == 0 // check zero vs normal numbers cmptst(field.newDfp("0"), field.newDfp("1"), "equal", false, 5); // 0 == 1 cmptst(field.newDfp("1"), field.newDfp("0"), "equal", false, 6); // 1 == 0 cmptst(field.newDfp("-1"), field.newDfp("0"), "equal", false, 7); // -1 == 0 cmptst(field.newDfp("0"), field.newDfp("-1"), "equal", false, 8); // 0 == -1 cmptst(field.newDfp("0"), field.newDfp("1e-131072"), "equal", false, 9); // 0 == 1e-131072 // check flags if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0"), field.newDfp("1e-131078"), "equal", false, 10); // 0 == 1e-131078 // check flags -- underflow should be set if (field.getIEEEFlags() != DfpField.FLAG_UNDERFLOW) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); cmptst(field.newDfp("0"), field.newDfp("1e+131071"), "equal", false, 11); // 0 == 1e+131071 // check zero vs infinities cmptst(field.newDfp("0"), pinf, "equal", false, 12); // 0 == pinf cmptst(field.newDfp("0"), ninf, "equal", false, 13); // 0 == ninf cmptst(field.newDfp("-0"), pinf, "equal", false, 14); // -0 == pinf cmptst(field.newDfp("-0"), ninf, "equal", false, 15); // -0 == ninf cmptst(pinf, field.newDfp("0"), "equal", false, 16); // pinf == 0 cmptst(ninf, field.newDfp("0"), "equal", false, 17); // ninf == 0 cmptst(pinf, field.newDfp("-0"), "equal", false, 18); // pinf == -0 cmptst(ninf, field.newDfp("-0"), "equal", false, 19); // ninf == -0 cmptst(ninf, pinf, "equal", false, 19.10); // ninf == pinf cmptst(pinf, ninf, "equal", false, 19.11); // pinf == ninf cmptst(pinf, pinf, "equal", true, 19.12); // pinf == pinf cmptst(ninf, ninf, "equal", true, 19.13); // ninf == ninf // check some normal numbers cmptst(field.newDfp("1"), field.newDfp("1"), "equal", true, 20); // 1 == 1 cmptst(field.newDfp("1"), field.newDfp("-1"), "equal", false, 21); // 1 == -1 cmptst(field.newDfp("-1"), field.newDfp("-1"), "equal", true, 22); // -1 == -1 cmptst(field.newDfp("1"), field.newDfp("1.0000000000000001"), "equal", false, 23); // 1 == 1.0000000000000001 // The tests below checks to ensure that comparisons don't set FLAG_INEXACT // 100000 == 1.0000000000000001 cmptst(field.newDfp("1e20"), field.newDfp("1.0000000000000001"), "equal", false, 24); if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0.000001"), field.newDfp("1e-6"), "equal", true, 25); // check some nans -- nans shouldnt equal anything cmptst(snan, snan, "equal", false, 27); cmptst(qnan, qnan, "equal", false, 28); cmptst(snan, qnan, "equal", false, 29); cmptst(qnan, snan, "equal", false, 30); cmptst(qnan, field.newDfp("0"), "equal", false, 31); cmptst(snan, field.newDfp("0"), "equal", false, 32); cmptst(field.newDfp("0"), snan, "equal", false, 33); cmptst(field.newDfp("0"), qnan, "equal", false, 34); cmptst(qnan, pinf, "equal", false, 35); cmptst(snan, pinf, "equal", false, 36); cmptst(pinf, snan, "equal", false, 37); cmptst(pinf, qnan, "equal", false, 38); cmptst(qnan, ninf, "equal", false, 39); cmptst(snan, ninf, "equal", false, 40); cmptst(ninf, snan, "equal", false, 41); cmptst(ninf, qnan, "equal", false, 42); cmptst(qnan, field.newDfp("-1"), "equal", false, 43); cmptst(snan, field.newDfp("-1"), "equal", false, 44); cmptst(field.newDfp("-1"), snan, "equal", false, 45); cmptst(field.newDfp("-1"), qnan, "equal", false, 46); cmptst(qnan, field.newDfp("1"), "equal", false, 47); cmptst(snan, field.newDfp("1"), "equal", false, 48); cmptst(field.newDfp("1"), snan, "equal", false, 49); cmptst(field.newDfp("1"), qnan, "equal", false, 50); cmptst(snan.negate(), snan, "equal", false, 51); cmptst(qnan.negate(), qnan, "equal", false, 52); // // Tests for un equal -- do it all over again // cmptst(field.newDfp("0"), field.newDfp("0"), "unequal", false, 1); // 0 == 0 cmptst(field.newDfp("0"), field.newDfp("-0"), "unequal", false, 2); // 0 == -0 cmptst(field.newDfp("-0"), field.newDfp("-0"), "unequal", false, 3); // -0 == -0 cmptst(field.newDfp("-0"), field.newDfp("0"), "unequal", false, 4); // -0 == 0 // check zero vs normal numbers cmptst(field.newDfp("0"), field.newDfp("1"), "unequal", true, 5); // 0 == 1 cmptst(field.newDfp("1"), field.newDfp("0"), "unequal", true, 6); // 1 == 0 cmptst(field.newDfp("-1"), field.newDfp("0"), "unequal", true, 7); // -1 == 0 cmptst(field.newDfp("0"), field.newDfp("-1"), "unequal", true, 8); // 0 == -1 cmptst(field.newDfp("0"), field.newDfp("1e-131072"), "unequal", true, 9); // 0 == 1e-131072 // check flags if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0"), field.newDfp("1e-131078"), "unequal", true, 10); // 0 == 1e-131078 // check flags -- underflow should be set if (field.getIEEEFlags() != DfpField.FLAG_UNDERFLOW) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); cmptst(field.newDfp("0"), field.newDfp("1e+131071"), "unequal", true, 11); // 0 == 1e+131071 // check zero vs infinities cmptst(field.newDfp("0"), pinf, "unequal", true, 12); // 0 == pinf cmptst(field.newDfp("0"), ninf, "unequal", true, 13); // 0 == ninf cmptst(field.newDfp("-0"), pinf, "unequal", true, 14); // -0 == pinf cmptst(field.newDfp("-0"), ninf, "unequal", true, 15); // -0 == ninf cmptst(pinf, field.newDfp("0"), "unequal", true, 16); // pinf == 0 cmptst(ninf, field.newDfp("0"), "unequal", true, 17); // ninf == 0 cmptst(pinf, field.newDfp("-0"), "unequal", true, 18); // pinf == -0 cmptst(ninf, field.newDfp("-0"), "unequal", true, 19); // ninf == -0 cmptst(ninf, pinf, "unequal", true, 19.10); // ninf == pinf cmptst(pinf, ninf, "unequal", true, 19.11); // pinf == ninf cmptst(pinf, pinf, "unequal", false, 19.12); // pinf == pinf cmptst(ninf, ninf, "unequal", false, 19.13); // ninf == ninf // check some normal numbers cmptst(field.newDfp("1"), field.newDfp("1"), "unequal", false, 20); // 1 == 1 cmptst(field.newDfp("1"), field.newDfp("-1"), "unequal", true, 21); // 1 == -1 cmptst(field.newDfp("-1"), field.newDfp("-1"), "unequal", false, 22); // -1 == -1 cmptst(field.newDfp("1"), field.newDfp("1.0000000000000001"), "unequal", true, 23); // 1 == 1.0000000000000001 // The tests below checks to ensure that comparisons don't set FLAG_INEXACT // 100000 == 1.0000000000000001 cmptst(field.newDfp("1e20"), field.newDfp("1.0000000000000001"), "unequal", true, 24); if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0.000001"), field.newDfp("1e-6"), "unequal", false, 25); // check some nans -- nans shouldnt be unequal to anything cmptst(snan, snan, "unequal", false, 27); cmptst(qnan, qnan, "unequal", false, 28); cmptst(snan, qnan, "unequal", false, 29); cmptst(qnan, snan, "unequal", false, 30); cmptst(qnan, field.newDfp("0"), "unequal", false, 31); cmptst(snan, field.newDfp("0"), "unequal", false, 32); cmptst(field.newDfp("0"), snan, "unequal", false, 33); cmptst(field.newDfp("0"), qnan, "unequal", false, 34); cmptst(qnan, pinf, "unequal", false, 35); cmptst(snan, pinf, "unequal", false, 36); cmptst(pinf, snan, "unequal", false, 37); cmptst(pinf, qnan, "unequal", false, 38); cmptst(qnan, ninf, "unequal", false, 39); cmptst(snan, ninf, "unequal", false, 40); cmptst(ninf, snan, "unequal", false, 41); cmptst(ninf, qnan, "unequal", false, 42); cmptst(qnan, field.newDfp("-1"), "unequal", false, 43); cmptst(snan, field.newDfp("-1"), "unequal", false, 44); cmptst(field.newDfp("-1"), snan, "unequal", false, 45); cmptst(field.newDfp("-1"), qnan, "unequal", false, 46); cmptst(qnan, field.newDfp("1"), "unequal", false, 47); cmptst(snan, field.newDfp("1"), "unequal", false, 48); cmptst(field.newDfp("1"), snan, "unequal", false, 49); cmptst(field.newDfp("1"), qnan, "unequal", false, 50); cmptst(snan.negate(), snan, "unequal", false, 51); cmptst(qnan.negate(), qnan, "unequal", false, 52); if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare unequal flags = "+field.getIEEEFlags()); // // Tests for lessThan -- do it all over again // cmptst(field.newDfp("0"), field.newDfp("0"), "lessThan", false, 1); // 0 < 0 cmptst(field.newDfp("0"), field.newDfp("-0"), "lessThan", false, 2); // 0 < -0 cmptst(field.newDfp("-0"), field.newDfp("-0"), "lessThan", false, 3); // -0 < -0 cmptst(field.newDfp("-0"), field.newDfp("0"), "lessThan", false, 4); // -0 < 0 // check zero vs normal numbers cmptst(field.newDfp("0"), field.newDfp("1"), "lessThan", true, 5); // 0 < 1 cmptst(field.newDfp("1"), field.newDfp("0"), "lessThan", false, 6); // 1 < 0 cmptst(field.newDfp("-1"), field.newDfp("0"), "lessThan", true, 7); // -1 < 0 cmptst(field.newDfp("0"), field.newDfp("-1"), "lessThan", false, 8); // 0 < -1 cmptst(field.newDfp("0"), field.newDfp("1e-131072"), "lessThan", true, 9); // 0 < 1e-131072 // check flags if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0"), field.newDfp("1e-131078"), "lessThan", true, 10); // 0 < 1e-131078 // check flags -- underflow should be set if (field.getIEEEFlags() != DfpField.FLAG_UNDERFLOW) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); cmptst(field.newDfp("0"), field.newDfp("1e+131071"), "lessThan", true, 11); // 0 < 1e+131071 // check zero vs infinities cmptst(field.newDfp("0"), pinf, "lessThan", true, 12); // 0 < pinf cmptst(field.newDfp("0"), ninf, "lessThan", false, 13); // 0 < ninf cmptst(field.newDfp("-0"), pinf, "lessThan", true, 14); // -0 < pinf cmptst(field.newDfp("-0"), ninf, "lessThan", false, 15); // -0 < ninf cmptst(pinf, field.newDfp("0"), "lessThan", false, 16); // pinf < 0 cmptst(ninf, field.newDfp("0"), "lessThan", true, 17); // ninf < 0 cmptst(pinf, field.newDfp("-0"), "lessThan", false, 18); // pinf < -0 cmptst(ninf, field.newDfp("-0"), "lessThan", true, 19); // ninf < -0 cmptst(ninf, pinf, "lessThan", true, 19.10); // ninf < pinf cmptst(pinf, ninf, "lessThan", false, 19.11); // pinf < ninf cmptst(pinf, pinf, "lessThan", false, 19.12); // pinf < pinf cmptst(ninf, ninf, "lessThan", false, 19.13); // ninf < ninf // check some normal numbers cmptst(field.newDfp("1"), field.newDfp("1"), "lessThan", false, 20); // 1 < 1 cmptst(field.newDfp("1"), field.newDfp("-1"), "lessThan", false, 21); // 1 < -1 cmptst(field.newDfp("-1"), field.newDfp("-1"), "lessThan", false, 22); // -1 < -1 cmptst(field.newDfp("1"), field.newDfp("1.0000000000000001"), "lessThan", true, 23); // 1 < 1.0000000000000001 // The tests below checks to ensure that comparisons don't set FLAG_INEXACT // 100000 < 1.0000000000000001 cmptst(field.newDfp("1e20"), field.newDfp("1.0000000000000001"), "lessThan", false, 24); if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0.000001"), field.newDfp("1e-6"), "lessThan", false, 25); // check some nans -- nans shouldnt be lessThan to anything cmptst(snan, snan, "lessThan", false, 27); cmptst(qnan, qnan, "lessThan", false, 28); cmptst(snan, qnan, "lessThan", false, 29); cmptst(qnan, snan, "lessThan", false, 30); cmptst(qnan, field.newDfp("0"), "lessThan", false, 31); cmptst(snan, field.newDfp("0"), "lessThan", false, 32); cmptst(field.newDfp("0"), snan, "lessThan", false, 33); cmptst(field.newDfp("0"), qnan, "lessThan", false, 34); cmptst(qnan, pinf, "lessThan", false, 35); cmptst(snan, pinf, "lessThan", false, 36); cmptst(pinf, snan, "lessThan", false, 37); cmptst(pinf, qnan, "lessThan", false, 38); cmptst(qnan, ninf, "lessThan", false, 39); cmptst(snan, ninf, "lessThan", false, 40); cmptst(ninf, snan, "lessThan", false, 41); cmptst(ninf, qnan, "lessThan", false, 42); cmptst(qnan, field.newDfp("-1"), "lessThan", false, 43); cmptst(snan, field.newDfp("-1"), "lessThan", false, 44); cmptst(field.newDfp("-1"), snan, "lessThan", false, 45); cmptst(field.newDfp("-1"), qnan, "lessThan", false, 46); cmptst(qnan, field.newDfp("1"), "lessThan", false, 47); cmptst(snan, field.newDfp("1"), "lessThan", false, 48); cmptst(field.newDfp("1"), snan, "lessThan", false, 49); cmptst(field.newDfp("1"), qnan, "lessThan", false, 50); cmptst(snan.negate(), snan, "lessThan", false, 51); cmptst(qnan.negate(), qnan, "lessThan", false, 52); //lessThan compares with nans should raise FLAG_INVALID if (field.getIEEEFlags() != DfpField.FLAG_INVALID) Assert.fail("assersion failed. compare lessThan flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); // // Tests for greaterThan -- do it all over again // cmptst(field.newDfp("0"), field.newDfp("0"), "greaterThan", false, 1); // 0 > 0 cmptst(field.newDfp("0"), field.newDfp("-0"), "greaterThan", false, 2); // 0 > -0 cmptst(field.newDfp("-0"), field.newDfp("-0"), "greaterThan", false, 3); // -0 > -0 cmptst(field.newDfp("-0"), field.newDfp("0"), "greaterThan", false, 4); // -0 > 0 // check zero vs normal numbers cmptst(field.newDfp("0"), field.newDfp("1"), "greaterThan", false, 5); // 0 > 1 cmptst(field.newDfp("1"), field.newDfp("0"), "greaterThan", true, 6); // 1 > 0 cmptst(field.newDfp("-1"), field.newDfp("0"), "greaterThan", false, 7); // -1 > 0 cmptst(field.newDfp("0"), field.newDfp("-1"), "greaterThan", true, 8); // 0 > -1 cmptst(field.newDfp("0"), field.newDfp("1e-131072"), "greaterThan", false, 9); // 0 > 1e-131072 // check flags if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0"), field.newDfp("1e-131078"), "greaterThan", false, 10); // 0 > 1e-131078 // check flags -- underflow should be set if (field.getIEEEFlags() != DfpField.FLAG_UNDERFLOW) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); cmptst(field.newDfp("0"), field.newDfp("1e+131071"), "greaterThan", false, 11); // 0 > 1e+131071 // check zero vs infinities cmptst(field.newDfp("0"), pinf, "greaterThan", false, 12); // 0 > pinf cmptst(field.newDfp("0"), ninf, "greaterThan", true, 13); // 0 > ninf cmptst(field.newDfp("-0"), pinf, "greaterThan", false, 14); // -0 > pinf cmptst(field.newDfp("-0"), ninf, "greaterThan", true, 15); // -0 > ninf cmptst(pinf, field.newDfp("0"), "greaterThan", true, 16); // pinf > 0 cmptst(ninf, field.newDfp("0"), "greaterThan", false, 17); // ninf > 0 cmptst(pinf, field.newDfp("-0"), "greaterThan", true, 18); // pinf > -0 cmptst(ninf, field.newDfp("-0"), "greaterThan", false, 19); // ninf > -0 cmptst(ninf, pinf, "greaterThan", false, 19.10); // ninf > pinf cmptst(pinf, ninf, "greaterThan", true, 19.11); // pinf > ninf cmptst(pinf, pinf, "greaterThan", false, 19.12); // pinf > pinf cmptst(ninf, ninf, "greaterThan", false, 19.13); // ninf > ninf // check some normal numbers cmptst(field.newDfp("1"), field.newDfp("1"), "greaterThan", false, 20); // 1 > 1 cmptst(field.newDfp("1"), field.newDfp("-1"), "greaterThan", true, 21); // 1 > -1 cmptst(field.newDfp("-1"), field.newDfp("-1"), "greaterThan", false, 22); // -1 > -1 cmptst(field.newDfp("1"), field.newDfp("1.0000000000000001"), "greaterThan", false, 23); // 1 > 1.0000000000000001 // The tests below checks to ensure that comparisons don't set FLAG_INEXACT // 100000 > 1.0000000000000001 cmptst(field.newDfp("1e20"), field.newDfp("1.0000000000000001"), "greaterThan", true, 24); if (field.getIEEEFlags() != 0) Assert.fail("assersion failed. compare flags = "+field.getIEEEFlags()); cmptst(field.newDfp("0.000001"), field.newDfp("1e-6"), "greaterThan", false, 25); // check some nans -- nans shouldnt be greaterThan to anything cmptst(snan, snan, "greaterThan", false, 27); cmptst(qnan, qnan, "greaterThan", false, 28); cmptst(snan, qnan, "greaterThan", false, 29); cmptst(qnan, snan, "greaterThan", false, 30); cmptst(qnan, field.newDfp("0"), "greaterThan", false, 31); cmptst(snan, field.newDfp("0"), "greaterThan", false, 32); cmptst(field.newDfp("0"), snan, "greaterThan", false, 33); cmptst(field.newDfp("0"), qnan, "greaterThan", false, 34); cmptst(qnan, pinf, "greaterThan", false, 35); cmptst(snan, pinf, "greaterThan", false, 36); cmptst(pinf, snan, "greaterThan", false, 37); cmptst(pinf, qnan, "greaterThan", false, 38); cmptst(qnan, ninf, "greaterThan", false, 39); cmptst(snan, ninf, "greaterThan", false, 40); cmptst(ninf, snan, "greaterThan", false, 41); cmptst(ninf, qnan, "greaterThan", false, 42); cmptst(qnan, field.newDfp("-1"), "greaterThan", false, 43); cmptst(snan, field.newDfp("-1"), "greaterThan", false, 44); cmptst(field.newDfp("-1"), snan, "greaterThan", false, 45); cmptst(field.newDfp("-1"), qnan, "greaterThan", false, 46); cmptst(qnan, field.newDfp("1"), "greaterThan", false, 47); cmptst(snan, field.newDfp("1"), "greaterThan", false, 48); cmptst(field.newDfp("1"), snan, "greaterThan", false, 49); cmptst(field.newDfp("1"), qnan, "greaterThan", false, 50); cmptst(snan.negate(), snan, "greaterThan", false, 51); cmptst(qnan.negate(), qnan, "greaterThan", false, 52); //greaterThan compares with nans should raise FLAG_INVALID if (field.getIEEEFlags() != DfpField.FLAG_INVALID) Assert.fail("assersion failed. compare greaterThan flags = "+field.getIEEEFlags()); field.clearIEEEFlags(); } // // Test multiplication // @Test public void testMultiply() { test(field.newDfp("1").multiply(field.newDfp("1")), // Basic tests 1*1 = 1 field.newDfp("1"), 0, "Multiply #1"); test(field.newDfp("1").multiply(1), // Basic tests 1*1 = 1 field.newDfp("1"), 0, "Multiply #2"); test(field.newDfp("-1").multiply(field.newDfp("1")), // Basic tests -1*1 = -1 field.newDfp("-1"), 0, "Multiply #3"); test(field.newDfp("-1").multiply(1), // Basic tests -1*1 = -1 field.newDfp("-1"), 0, "Multiply #4"); // basic tests with integers test(field.newDfp("2").multiply(field.newDfp("3")), field.newDfp("6"), 0, "Multiply #5"); test(field.newDfp("2").multiply(3), field.newDfp("6"), 0, "Multiply #6"); test(field.newDfp("-2").multiply(field.newDfp("3")), field.newDfp("-6"), 0, "Multiply #7"); test(field.newDfp("-2").multiply(3), field.newDfp("-6"), 0, "Multiply #8"); test(field.newDfp("2").multiply(field.newDfp("-3")), field.newDfp("-6"), 0, "Multiply #9"); test(field.newDfp("-2").multiply(field.newDfp("-3")), field.newDfp("6"), 0, "Multiply #10"); //multiply by zero test(field.newDfp("-2").multiply(field.newDfp("0")), field.newDfp("-0"), 0, "Multiply #11"); test(field.newDfp("-2").multiply(0), field.newDfp("-0"), 0, "Multiply #12"); test(field.newDfp("2").multiply(field.newDfp("0")), field.newDfp("0"), 0, "Multiply #13"); test(field.newDfp("2").multiply(0), field.newDfp("0"), 0, "Multiply #14"); test(field.newDfp("2").multiply(pinf), pinf, 0, "Multiply #15"); test(field.newDfp("2").multiply(ninf), ninf, 0, "Multiply #16"); test(field.newDfp("-2").multiply(pinf), ninf, 0, "Multiply #17"); test(field.newDfp("-2").multiply(ninf), pinf, 0, "Multiply #18"); test(ninf.multiply(field.newDfp("-2")), pinf, 0, "Multiply #18.1"); test(field.newDfp("5e131071").multiply(2), pinf, DfpField.FLAG_OVERFLOW, "Multiply #19"); test(field.newDfp("5e131071").multiply(field.newDfp("1.999999999999999")), field.newDfp("9.9999999999999950000e131071"), 0, "Multiply #20"); test(field.newDfp("-5e131071").multiply(2), ninf, DfpField.FLAG_OVERFLOW, "Multiply #22"); test(field.newDfp("-5e131071").multiply(field.newDfp("1.999999999999999")), field.newDfp("-9.9999999999999950000e131071"), 0, "Multiply #23"); test(field.newDfp("1e-65539").multiply(field.newDfp("1e-65539")), field.newDfp("1e-131078"), DfpField.FLAG_UNDERFLOW, "Multiply #24"); test(field.newDfp("1").multiply(nan), nan, 0, "Multiply #25"); test(nan.multiply(field.newDfp("1")), nan, 0, "Multiply #26"); test(nan.multiply(pinf), nan, 0, "Multiply #27"); test(pinf.multiply(nan), nan, 0, "Multiply #27"); test(pinf.multiply(field.newDfp("0")), nan, DfpField.FLAG_INVALID, "Multiply #28"); test(field.newDfp("0").multiply(pinf), nan, DfpField.FLAG_INVALID, "Multiply #29"); test(pinf.multiply(pinf), pinf, 0, "Multiply #30"); test(ninf.multiply(pinf), ninf, 0, "Multiply #31"); test(pinf.multiply(ninf), ninf, 0, "Multiply #32"); test(ninf.multiply(ninf), pinf, 0, "Multiply #33"); test(pinf.multiply(1), pinf, 0, "Multiply #34"); test(pinf.multiply(0), nan, DfpField.FLAG_INVALID, "Multiply #35"); test(nan.multiply(1), nan, 0, "Multiply #36"); test(field.newDfp("1").multiply(10000), // out of range nan, DfpField.FLAG_INVALID, "Multiply #37"); test(field.newDfp("1").multiply(-1), // out of range nan, DfpField.FLAG_INVALID, "Multiply #38"); } @Test public void testDivide() { test(field.newDfp("1").divide(nan), // divide by NaN = NaN nan, 0, "Divide #1"); test(nan.divide(field.newDfp("1")), // NaN / number = NaN nan, 0, "Divide #2"); test(pinf.divide(field.newDfp("1")), pinf, 0, "Divide #3"); test(pinf.divide(field.newDfp("-1")), ninf, 0, "Divide #4"); test(pinf.divide(pinf), nan, DfpField.FLAG_INVALID, "Divide #5"); test(ninf.divide(pinf), nan, DfpField.FLAG_INVALID, "Divide #6"); test(pinf.divide(ninf), nan, DfpField.FLAG_INVALID, "Divide #7"); test(ninf.divide(ninf), nan, DfpField.FLAG_INVALID, "Divide #8"); test(field.newDfp("0").divide(field.newDfp("0")), nan, DfpField.FLAG_DIV_ZERO, "Divide #9"); test(field.newDfp("1").divide(field.newDfp("0")), pinf, DfpField.FLAG_DIV_ZERO, "Divide #10"); test(field.newDfp("1").divide(field.newDfp("-0")), ninf, DfpField.FLAG_DIV_ZERO, "Divide #11"); test(field.newDfp("-1").divide(field.newDfp("0")), ninf, DfpField.FLAG_DIV_ZERO, "Divide #12"); test(field.newDfp("-1").divide(field.newDfp("-0")), pinf, DfpField.FLAG_DIV_ZERO, "Divide #13"); test(field.newDfp("1").divide(field.newDfp("3")), field.newDfp("0.33333333333333333333"), DfpField.FLAG_INEXACT, "Divide #14"); test(field.newDfp("1").divide(field.newDfp("6")), field.newDfp("0.16666666666666666667"), DfpField.FLAG_INEXACT, "Divide #15"); test(field.newDfp("10").divide(field.newDfp("6")), field.newDfp("1.6666666666666667"), DfpField.FLAG_INEXACT, "Divide #16"); test(field.newDfp("100").divide(field.newDfp("6")), field.newDfp("16.6666666666666667"), DfpField.FLAG_INEXACT, "Divide #17"); test(field.newDfp("1000").divide(field.newDfp("6")), field.newDfp("166.6666666666666667"), DfpField.FLAG_INEXACT, "Divide #18"); test(field.newDfp("10000").divide(field.newDfp("6")), field.newDfp("1666.6666666666666667"), DfpField.FLAG_INEXACT, "Divide #19"); test(field.newDfp("1").divide(field.newDfp("1")), field.newDfp("1"), 0, "Divide #20"); test(field.newDfp("1").divide(field.newDfp("-1")), field.newDfp("-1"), 0, "Divide #21"); test(field.newDfp("-1").divide(field.newDfp("1")), field.newDfp("-1"), 0, "Divide #22"); test(field.newDfp("-1").divide(field.newDfp("-1")), field.newDfp("1"), 0, "Divide #23"); test(field.newDfp("1e-65539").divide(field.newDfp("1e65539")), field.newDfp("1e-131078"), DfpField.FLAG_UNDERFLOW, "Divide #24"); test(field.newDfp("1e65539").divide(field.newDfp("1e-65539")), pinf, DfpField.FLAG_OVERFLOW, "Divide #24"); test(field.newDfp("2").divide(field.newDfp("1.5")), // test trial-divisor too high field.newDfp("1.3333333333333333"), DfpField.FLAG_INEXACT, "Divide #25"); test(field.newDfp("2").divide(pinf), field.newDfp("0"), 0, "Divide #26"); test(field.newDfp("2").divide(ninf), field.newDfp("-0"), 0, "Divide #27"); test(field.newDfp("0").divide(field.newDfp("1")), field.newDfp("0"), 0, "Divide #28"); } @Test public void testDivideInt() { test(nan.divide(1), // NaN / number = NaN nan, 0, "DivideInt #1"); test(pinf.divide(1), pinf, 0, "DivideInt #2"); test(field.newDfp("0").divide(0), nan, DfpField.FLAG_DIV_ZERO, "DivideInt #3"); test(field.newDfp("1").divide(0), pinf, DfpField.FLAG_DIV_ZERO, "DivideInt #4"); test(field.newDfp("-1").divide(0), ninf, DfpField.FLAG_DIV_ZERO, "DivideInt #5"); test(field.newDfp("1").divide(3), field.newDfp("0.33333333333333333333"), DfpField.FLAG_INEXACT, "DivideInt #6"); test(field.newDfp("1").divide(6), field.newDfp("0.16666666666666666667"), DfpField.FLAG_INEXACT, "DivideInt #7"); test(field.newDfp("10").divide(6), field.newDfp("1.6666666666666667"), DfpField.FLAG_INEXACT, "DivideInt #8"); test(field.newDfp("100").divide(6), field.newDfp("16.6666666666666667"), DfpField.FLAG_INEXACT, "DivideInt #9"); test(field.newDfp("1000").divide(6), field.newDfp("166.6666666666666667"), DfpField.FLAG_INEXACT, "DivideInt #10"); test(field.newDfp("10000").divide(6), field.newDfp("1666.6666666666666667"), DfpField.FLAG_INEXACT, "DivideInt #20"); test(field.newDfp("1").divide(1), field.newDfp("1"), 0, "DivideInt #21"); test(field.newDfp("1e-131077").divide(10), field.newDfp("1e-131078"), DfpField.FLAG_UNDERFLOW, "DivideInt #22"); test(field.newDfp("0").divide(1), field.newDfp("0"), 0, "DivideInt #23"); test(field.newDfp("1").divide(10000), nan, DfpField.FLAG_INVALID, "DivideInt #24"); test(field.newDfp("1").divide(-1), nan, DfpField.FLAG_INVALID, "DivideInt #25"); } @Test public void testNextAfter() { test(field.newDfp("1").nextAfter(pinf), field.newDfp("1.0000000000000001"), 0, "NextAfter #1"); test(field.newDfp("1.0000000000000001").nextAfter(ninf), field.newDfp("1"), 0, "NextAfter #1.5"); test(field.newDfp("1").nextAfter(ninf), field.newDfp("0.99999999999999999999"), 0, "NextAfter #2"); test(field.newDfp("0.99999999999999999999").nextAfter(field.newDfp("2")), field.newDfp("1"), 0, "NextAfter #3"); test(field.newDfp("-1").nextAfter(ninf), field.newDfp("-1.0000000000000001"), 0, "NextAfter #4"); test(field.newDfp("-1").nextAfter(pinf), field.newDfp("-0.99999999999999999999"), 0, "NextAfter #5"); test(field.newDfp("-0.99999999999999999999").nextAfter(field.newDfp("-2")), field.newDfp("-1"), 0, "NextAfter #6"); test(field.newDfp("2").nextAfter(field.newDfp("2")), field.newDfp("2"), 0, "NextAfter #7"); test(field.newDfp("0").nextAfter(field.newDfp("0")), field.newDfp("0"), 0, "NextAfter #8"); test(field.newDfp("-2").nextAfter(field.newDfp("-2")), field.newDfp("-2"), 0, "NextAfter #9"); test(field.newDfp("0").nextAfter(field.newDfp("1")), field.newDfp("1e-131092"), DfpField.FLAG_UNDERFLOW, "NextAfter #10"); test(field.newDfp("0").nextAfter(field.newDfp("-1")), field.newDfp("-1e-131092"), DfpField.FLAG_UNDERFLOW, "NextAfter #11"); test(field.newDfp("-1e-131092").nextAfter(pinf), field.newDfp("-0"), DfpField.FLAG_UNDERFLOW|DfpField.FLAG_INEXACT, "Next After #12"); test(field.newDfp("1e-131092").nextAfter(ninf), field.newDfp("0"), DfpField.FLAG_UNDERFLOW|DfpField.FLAG_INEXACT, "Next After #13"); test(field.newDfp("9.9999999999999999999e131078").nextAfter(pinf), pinf, DfpField.FLAG_OVERFLOW|DfpField.FLAG_INEXACT, "Next After #14"); } @Test public void testToString() { Assert.assertEquals("toString #1", "Infinity", pinf.toString()); Assert.assertEquals("toString #2", "-Infinity", ninf.toString()); Assert.assertEquals("toString #3", "NaN", nan.toString()); Assert.assertEquals("toString #4", "NaN", field.newDfp((byte) 1, Dfp.QNAN).toString()); Assert.assertEquals("toString #5", "NaN", field.newDfp((byte) 1, Dfp.SNAN).toString()); Assert.assertEquals("toString #6", "1.2300000000000000e100", field.newDfp("1.23e100").toString()); Assert.assertEquals("toString #7", "-1.2300000000000000e100", field.newDfp("-1.23e100").toString()); Assert.assertEquals("toString #8", "12345678.1234", field.newDfp("12345678.1234").toString()); Assert.assertEquals("toString #9", "0.00001234", field.newDfp("0.00001234").toString()); } @Test public void testRound() { field.setRoundingMode(DfpField.RoundingMode.ROUND_DOWN); // Round down test(field.newDfp("12345678901234567890").add(field.newDfp("0.9")), field.newDfp("12345678901234567890"), DfpField.FLAG_INEXACT, "Round #1"); test(field.newDfp("12345678901234567890").add(field.newDfp("0.99999999")), field.newDfp("12345678901234567890"), DfpField.FLAG_INEXACT, "Round #2"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.99999999")), field.newDfp("-12345678901234567890"), DfpField.FLAG_INEXACT, "Round #3"); field.setRoundingMode(DfpField.RoundingMode.ROUND_UP); // Round up test(field.newDfp("12345678901234567890").add(field.newDfp("0.1")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #4"); test(field.newDfp("12345678901234567890").add(field.newDfp("0.0001")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #5"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.1")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #6"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.0001")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #7"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_UP); // Round half up test(field.newDfp("12345678901234567890").add(field.newDfp("0.4999")), field.newDfp("12345678901234567890"), DfpField.FLAG_INEXACT, "Round #8"); test(field.newDfp("12345678901234567890").add(field.newDfp("0.5000")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #9"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.4999")), field.newDfp("-12345678901234567890"), DfpField.FLAG_INEXACT, "Round #10"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.5000")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #11"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_DOWN); // Round half down test(field.newDfp("12345678901234567890").add(field.newDfp("0.5001")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #12"); test(field.newDfp("12345678901234567890").add(field.newDfp("0.5000")), field.newDfp("12345678901234567890"), DfpField.FLAG_INEXACT, "Round #13"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.5001")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #14"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.5000")), field.newDfp("-12345678901234567890"), DfpField.FLAG_INEXACT, "Round #15"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_ODD); // Round half odd test(field.newDfp("12345678901234567890").add(field.newDfp("0.5000")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #16"); test(field.newDfp("12345678901234567891").add(field.newDfp("0.5000")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #17"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.5000")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #18"); test(field.newDfp("-12345678901234567891").add(field.newDfp("-0.5000")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #19"); field.setRoundingMode(DfpField.RoundingMode.ROUND_CEIL); // Round ceil test(field.newDfp("12345678901234567890").add(field.newDfp("0.0001")), field.newDfp("12345678901234567891"), DfpField.FLAG_INEXACT, "Round #20"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.9999")), field.newDfp("-12345678901234567890"), DfpField.FLAG_INEXACT, "Round #21"); field.setRoundingMode(DfpField.RoundingMode.ROUND_FLOOR); // Round floor test(field.newDfp("12345678901234567890").add(field.newDfp("0.9999")), field.newDfp("12345678901234567890"), DfpField.FLAG_INEXACT, "Round #22"); test(field.newDfp("-12345678901234567890").add(field.newDfp("-0.0001")), field.newDfp("-12345678901234567891"), DfpField.FLAG_INEXACT, "Round #23"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_EVEN); // reset } @Test public void testCeil() { test(field.newDfp("1234.0000000000000001").ceil(), field.newDfp("1235"), DfpField.FLAG_INEXACT, "Ceil #1"); } @Test public void testFloor() { test(field.newDfp("1234.9999999999999999").floor(), field.newDfp("1234"), DfpField.FLAG_INEXACT, "Floor #1"); } @Test public void testRint() { test(field.newDfp("1234.50000000001").rint(), field.newDfp("1235"), DfpField.FLAG_INEXACT, "Rint #1"); test(field.newDfp("1234.5000").rint(), field.newDfp("1234"), DfpField.FLAG_INEXACT, "Rint #2"); test(field.newDfp("1235.5000").rint(), field.newDfp("1236"), DfpField.FLAG_INEXACT, "Rint #3"); } @Test public void testCopySign() { test(Dfp.copysign(field.newDfp("1234."), field.newDfp("-1")), field.newDfp("-1234"), 0, "CopySign #1"); test(Dfp.copysign(field.newDfp("-1234."), field.newDfp("-1")), field.newDfp("-1234"), 0, "CopySign #2"); test(Dfp.copysign(field.newDfp("-1234."), field.newDfp("1")), field.newDfp("1234"), 0, "CopySign #3"); test(Dfp.copysign(field.newDfp("1234."), field.newDfp("1")), field.newDfp("1234"), 0, "CopySign #4"); } @Test public void testIntValue() { Assert.assertEquals("intValue #1", 1234, field.newDfp("1234").intValue()); Assert.assertEquals("intValue #2", -1234, field.newDfp("-1234").intValue()); Assert.assertEquals("intValue #3", 1234, field.newDfp("1234.5").intValue()); Assert.assertEquals("intValue #4", 1235, field.newDfp("1234.500001").intValue()); Assert.assertEquals("intValue #5", 2147483647, field.newDfp("1e1000").intValue()); Assert.assertEquals("intValue #6", -2147483648, field.newDfp("-1e1000").intValue()); } @Test public void testLog10K() { Assert.assertEquals("log10K #1", 1, field.newDfp("123456").log10K()); Assert.assertEquals("log10K #2", 2, field.newDfp("123456789").log10K()); Assert.assertEquals("log10K #3", 0, field.newDfp("2").log10K()); Assert.assertEquals("log10K #3", 0, field.newDfp("1").log10K()); Assert.assertEquals("log10K #4", -1, field.newDfp("0.1").log10K()); } @Test public void testPower10K() { Dfp d = field.newDfp(); test(d.power10K(0), field.newDfp("1"), 0, "Power10 #1"); test(d.power10K(1), field.newDfp("10000"), 0, "Power10 #2"); test(d.power10K(2), field.newDfp("100000000"), 0, "Power10 #3"); test(d.power10K(-1), field.newDfp("0.0001"), 0, "Power10 #4"); test(d.power10K(-2), field.newDfp("0.00000001"), 0, "Power10 #5"); test(d.power10K(-3), field.newDfp("0.000000000001"), 0, "Power10 #6"); } @Test public void testLog10() { Assert.assertEquals("log10 #1", 1, field.newDfp("12").log10()); Assert.assertEquals("log10 #2", 2, field.newDfp("123").log10()); Assert.assertEquals("log10 #3", 3, field.newDfp("1234").log10()); Assert.assertEquals("log10 #4", 4, field.newDfp("12345").log10()); Assert.assertEquals("log10 #5", 5, field.newDfp("123456").log10()); Assert.assertEquals("log10 #6", 6, field.newDfp("1234567").log10()); Assert.assertEquals("log10 #6", 7, field.newDfp("12345678").log10()); Assert.assertEquals("log10 #7", 8, field.newDfp("123456789").log10()); Assert.assertEquals("log10 #8", 9, field.newDfp("1234567890").log10()); Assert.assertEquals("log10 #9", 10, field.newDfp("12345678901").log10()); Assert.assertEquals("log10 #10", 11, field.newDfp("123456789012").log10()); Assert.assertEquals("log10 #11", 12, field.newDfp("1234567890123").log10()); Assert.assertEquals("log10 #12", 0, field.newDfp("2").log10()); Assert.assertEquals("log10 #13", 0, field.newDfp("1").log10()); Assert.assertEquals("log10 #14", -1, field.newDfp("0.12").log10()); Assert.assertEquals("log10 #15", -2, field.newDfp("0.012").log10()); } @Test public void testPower10() { Dfp d = field.newDfp(); test(d.power10(0), field.newDfp("1"), 0, "Power10 #1"); test(d.power10(1), field.newDfp("10"), 0, "Power10 #2"); test(d.power10(2), field.newDfp("100"), 0, "Power10 #3"); test(d.power10(3), field.newDfp("1000"), 0, "Power10 #4"); test(d.power10(4), field.newDfp("10000"), 0, "Power10 #5"); test(d.power10(5), field.newDfp("100000"), 0, "Power10 #6"); test(d.power10(6), field.newDfp("1000000"), 0, "Power10 #7"); test(d.power10(7), field.newDfp("10000000"), 0, "Power10 #8"); test(d.power10(8), field.newDfp("100000000"), 0, "Power10 #9"); test(d.power10(9), field.newDfp("1000000000"), 0, "Power10 #10"); test(d.power10(-1), field.newDfp(".1"), 0, "Power10 #11"); test(d.power10(-2), field.newDfp(".01"), 0, "Power10 #12"); test(d.power10(-3), field.newDfp(".001"), 0, "Power10 #13"); test(d.power10(-4), field.newDfp(".0001"), 0, "Power10 #14"); test(d.power10(-5), field.newDfp(".00001"), 0, "Power10 #15"); test(d.power10(-6), field.newDfp(".000001"), 0, "Power10 #16"); test(d.power10(-7), field.newDfp(".0000001"), 0, "Power10 #17"); test(d.power10(-8), field.newDfp(".00000001"), 0, "Power10 #18"); test(d.power10(-9), field.newDfp(".000000001"), 0, "Power10 #19"); test(d.power10(-10), field.newDfp(".0000000001"), 0, "Power10 #20"); } @Test public void testRemainder() { test(field.newDfp("10").remainder(field.newDfp("3")), field.newDfp("1"), DfpField.FLAG_INEXACT, "Remainder #1"); test(field.newDfp("9").remainder(field.newDfp("3")), field.newDfp("0"), 0, "Remainder #2"); test(field.newDfp("-9").remainder(field.newDfp("3")), field.newDfp("-0"), 0, "Remainder #3"); } @Test public void testSqrt() { test(field.newDfp("0").sqrt(), field.newDfp("0"), 0, "Sqrt #1"); test(field.newDfp("-0").sqrt(), field.newDfp("-0"), 0, "Sqrt #2"); test(field.newDfp("1").sqrt(), field.newDfp("1"), 0, "Sqrt #3"); test(field.newDfp("2").sqrt(), field.newDfp("1.4142135623730950"), DfpField.FLAG_INEXACT, "Sqrt #4"); test(field.newDfp("3").sqrt(), field.newDfp("1.7320508075688773"), DfpField.FLAG_INEXACT, "Sqrt #5"); test(field.newDfp("5").sqrt(), field.newDfp("2.2360679774997897"), DfpField.FLAG_INEXACT, "Sqrt #6"); test(field.newDfp("500").sqrt(), field.newDfp("22.3606797749978970"), DfpField.FLAG_INEXACT, "Sqrt #6.2"); test(field.newDfp("50000").sqrt(), field.newDfp("223.6067977499789696"), DfpField.FLAG_INEXACT, "Sqrt #6.3"); test(field.newDfp("-1").sqrt(), nan, DfpField.FLAG_INVALID, "Sqrt #7"); test(pinf.sqrt(), pinf, 0, "Sqrt #8"); test(field.newDfp((byte) 1, Dfp.QNAN).sqrt(), nan, 0, "Sqrt #9"); test(field.newDfp((byte) 1, Dfp.SNAN).sqrt(), nan, DfpField.FLAG_INVALID, "Sqrt #9"); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/dfp/DfpDecTest.java100644 1750 1750 56001 11532241242 26017 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class DfpDecTest { private DfpField field; private Dfp pinf; private Dfp ninf; @Before public void setUp() { // Some basic setup. Define some constants and clear the status flags field = new DfpField(20); pinf = new DfpDec(field, 1).divide(new DfpDec(field, 0)); ninf = new DfpDec(field, -1).divide(new DfpDec(field, 0)); ninf.getField().clearIEEEFlags(); } @After public void tearDown() { field = null; pinf = null; ninf = null; } // Generic test function. Takes params x and y and tests them for // equality. Then checks the status flags against the flags argument. // If the test fail, it prints the desc string private void test(Dfp x, Dfp y, int flags, String desc) { boolean b = x.equals(y); if (!x.equals(y) && !x.unequal(y)) // NaNs involved b = (x.toString().equals(y.toString())); if (x.equals(new DfpDec(field, 0))) // distinguish +/- zero b = (b && (x.toString().equals(y.toString()))); b = (b && x.getField().getIEEEFlags() == flags); if (!b) Assert.assertTrue("assersion failed "+desc+" x = "+x.toString()+" flags = "+x.getField().getIEEEFlags(), b); x.getField().clearIEEEFlags(); } @Test public void testRound() { field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_EVEN); test(new DfpDec(field, "12345678901234567890"), new DfpDec(field, "12345678901234568000"), DfpField.FLAG_INEXACT, "Round #1"); test(new DfpDec(field, "0.12345678901234567890"), new DfpDec(field, "0.12345678901234568"), DfpField.FLAG_INEXACT, "Round #2"); test(new DfpDec(field, "0.12345678901234567500"), new DfpDec(field, "0.12345678901234568"), DfpField.FLAG_INEXACT, "Round #3"); test(new DfpDec(field, "0.12345678901234568500"), new DfpDec(field, "0.12345678901234568"), DfpField.FLAG_INEXACT, "Round #4"); test(new DfpDec(field, "0.12345678901234568501"), new DfpDec(field, "0.12345678901234569"), DfpField.FLAG_INEXACT, "Round #5"); test(new DfpDec(field, "0.12345678901234568499"), new DfpDec(field, "0.12345678901234568"), DfpField.FLAG_INEXACT, "Round #6"); test(new DfpDec(field, "1.2345678901234567890"), new DfpDec(field, "1.2345678901234568"), DfpField.FLAG_INEXACT, "Round #7"); test(new DfpDec(field, "1.2345678901234567500"), new DfpDec(field, "1.2345678901234568"), DfpField.FLAG_INEXACT, "Round #8"); test(new DfpDec(field, "1.2345678901234568500"), new DfpDec(field, "1.2345678901234568"), DfpField.FLAG_INEXACT, "Round #9"); test(new DfpDec(field, "1.2345678901234568000").add(new DfpDec(field, ".0000000000000000501")), new DfpDec(field, "1.2345678901234569"), DfpField.FLAG_INEXACT, "Round #10"); test(new DfpDec(field, "1.2345678901234568499"), new DfpDec(field, "1.2345678901234568"), DfpField.FLAG_INEXACT, "Round #11"); test(new DfpDec(field, "12.345678901234567890"), new DfpDec(field, "12.345678901234568"), DfpField.FLAG_INEXACT, "Round #12"); test(new DfpDec(field, "12.345678901234567500"), new DfpDec(field, "12.345678901234568"), DfpField.FLAG_INEXACT, "Round #13"); test(new DfpDec(field, "12.345678901234568500"), new DfpDec(field, "12.345678901234568"), DfpField.FLAG_INEXACT, "Round #14"); test(new DfpDec(field, "12.345678901234568").add(new DfpDec(field, ".000000000000000501")), new DfpDec(field, "12.345678901234569"), DfpField.FLAG_INEXACT, "Round #15"); test(new DfpDec(field, "12.345678901234568499"), new DfpDec(field, "12.345678901234568"), DfpField.FLAG_INEXACT, "Round #16"); test(new DfpDec(field, "123.45678901234567890"), new DfpDec(field, "123.45678901234568"), DfpField.FLAG_INEXACT, "Round #17"); test(new DfpDec(field, "123.45678901234567500"), new DfpDec(field, "123.45678901234568"), DfpField.FLAG_INEXACT, "Round #18"); test(new DfpDec(field, "123.45678901234568500"), new DfpDec(field, "123.45678901234568"), DfpField.FLAG_INEXACT, "Round #19"); test(new DfpDec(field, "123.456789012345685").add(new DfpDec(field, ".00000000000000501")), new DfpDec(field, "123.45678901234569"), DfpField.FLAG_INEXACT, "Round #20"); test(new DfpDec(field, "123.45678901234568499"), new DfpDec(field, "123.45678901234568"), DfpField.FLAG_INEXACT, "Round #21"); field.setRoundingMode(DfpField.RoundingMode.ROUND_DOWN); // Round down test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.9")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #22"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.99999999")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #23"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.99999999")), new DfpDec(field, "-12345678901234567"), DfpField.FLAG_INEXACT, "Round #24"); field.setRoundingMode(DfpField.RoundingMode.ROUND_UP); // Round up test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.1")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #25"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.0001")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #26"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.1")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #27"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.0001")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #28"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "0")), new DfpDec(field, "-12345678901234567"), 0, "Round #28.5"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_UP); // Round half up test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.499999999999")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #29"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.50000001")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #30"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.5")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #30.5"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.499999999999")), new DfpDec(field, "-12345678901234567"), DfpField.FLAG_INEXACT, "Round #31"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.50000001")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #32"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_DOWN); // Round half down test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.5001")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #33"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.5000")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #34"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.5001")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #35"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.6")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #35.5"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.5000")), new DfpDec(field, "-12345678901234567"), DfpField.FLAG_INEXACT, "Round #36"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_ODD); // Round half odd test(new DfpDec(field, "12345678901234568").add(new DfpDec(field, "0.5000")), new DfpDec(field, "12345678901234569"), DfpField.FLAG_INEXACT, "Round #37"); test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.5000")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #38"); test(new DfpDec(field, "-12345678901234568").add(new DfpDec(field, "-0.5000")), new DfpDec(field, "-12345678901234569"), DfpField.FLAG_INEXACT, "Round #39"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.5000")), new DfpDec(field, "-12345678901234567"), DfpField.FLAG_INEXACT, "Round #40"); field.setRoundingMode(DfpField.RoundingMode.ROUND_CEIL); // Round ceil test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.0001")), new DfpDec(field, "12345678901234568"), DfpField.FLAG_INEXACT, "Round #41"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.9999")), new DfpDec(field, "-12345678901234567"), DfpField.FLAG_INEXACT, "Round #42"); field.setRoundingMode(DfpField.RoundingMode.ROUND_FLOOR); // Round floor test(new DfpDec(field, "12345678901234567").add(new DfpDec(field, "0.9999")), new DfpDec(field, "12345678901234567"), DfpField.FLAG_INEXACT, "Round #43"); test(new DfpDec(field, "-12345678901234567").add(new DfpDec(field, "-0.0001")), new DfpDec(field, "-12345678901234568"), DfpField.FLAG_INEXACT, "Round #44"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_EVEN); // reset } @Test public void testRoundDecimal10() { field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_EVEN); test(new Decimal10(field, "1234567891234567890"), new Decimal10(field, "1234567891000000000"), DfpField.FLAG_INEXACT, "RoundDecimal10 #1"); test(new Decimal10(field, "0.1234567891634567890"), new Decimal10(field, "0.1234567892"), DfpField.FLAG_INEXACT, "RoundDecimal10 #2"); test(new Decimal10(field, "0.1234567891500000000"), new Decimal10(field, "0.1234567892"), DfpField.FLAG_INEXACT, "RoundDecimal10 #3"); test(new Decimal10(field, "0.1234567890500"), new Decimal10(field, "0.1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #4"); test(new Decimal10(field, "0.1234567890501"), new Decimal10(field, "0.1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #5"); test(new Decimal10(field, "0.1234567890499"), new Decimal10(field, "0.1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #6"); test(new Decimal10(field, "1.234567890890"), new Decimal10(field, "1.234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #7"); test(new Decimal10(field, "1.234567891500"), new Decimal10(field, "1.234567892"), DfpField.FLAG_INEXACT, "RoundDecimal10 #8"); test(new Decimal10(field, "1.234567890500"), new Decimal10(field, "1.234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #9"); test(new Decimal10(field, "1.234567890000").add(new Decimal10(field, ".000000000501")), new Decimal10(field, "1.234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #10"); test(new Decimal10(field, "1.234567890499"), new Decimal10(field, "1.234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #11"); test(new Decimal10(field, "12.34567890890"), new Decimal10(field, "12.34567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #12"); test(new Decimal10(field, "12.34567891500"), new Decimal10(field, "12.34567892"), DfpField.FLAG_INEXACT, "RoundDecimal10 #13"); test(new Decimal10(field, "12.34567890500"), new Decimal10(field, "12.34567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #14"); test(new Decimal10(field, "12.34567890").add(new Decimal10(field, ".00000000501")), new Decimal10(field, "12.34567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #15"); test(new Decimal10(field, "12.34567890499"), new Decimal10(field, "12.34567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #16"); test(new Decimal10(field, "123.4567890890"), new Decimal10(field, "123.4567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #17"); test(new Decimal10(field, "123.4567891500"), new Decimal10(field, "123.4567892"), DfpField.FLAG_INEXACT, "RoundDecimal10 #18"); test(new Decimal10(field, "123.4567890500"), new Decimal10(field, "123.4567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #19"); test(new Decimal10(field, "123.4567890").add(new Decimal10(field, ".0000000501")), new Decimal10(field, "123.4567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #20"); test(new Decimal10(field, "123.4567890499"), new Decimal10(field, "123.4567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #21"); field.setRoundingMode(DfpField.RoundingMode.ROUND_DOWN); // RoundDecimal10 down test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.9")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #22"); test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.99999999")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #23"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.99999999")), new Decimal10(field, "-1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #24"); field.setRoundingMode(DfpField.RoundingMode.ROUND_UP); // RoundDecimal10 up test(new Decimal10(field, 1234567890).add(new Decimal10(field, "0.1")), new Decimal10(field, 1234567891l), DfpField.FLAG_INEXACT, "RoundDecimal10 #25"); test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.0001")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #26"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.1")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #27"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.0001")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #28"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "0")), new Decimal10(field, "-1234567890"), 0, "RoundDecimal10 #28.5"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_UP); // RoundDecimal10 half up test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.4999999999")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #29"); test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.50000001")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #30"); test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.5")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #30.5"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.4999999999")), new Decimal10(field, "-1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #31"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.50000001")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #32"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_DOWN); // RoundDecimal10 half down test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.5001")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #33"); test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.5000")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #34"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.5001")), new Decimal10(field, "-1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #35"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.6")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #35.5"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.5000")), new Decimal10(field, "-1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #36"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_ODD); // RoundDecimal10 half odd test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.5000")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #37"); test(new Decimal10(field, "1234567891").add(new Decimal10(field, "0.5000")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #38"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.5000")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #39"); test(new Decimal10(field, "-1234567891").add(new Decimal10(field, "-0.5000")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #40"); field.setRoundingMode(DfpField.RoundingMode.ROUND_CEIL); // RoundDecimal10 ceil test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.0001")), new Decimal10(field, "1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #41"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.9999")), new Decimal10(field, "-1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #42"); field.setRoundingMode(DfpField.RoundingMode.ROUND_FLOOR); // RoundDecimal10 floor test(new Decimal10(field, "1234567890").add(new Decimal10(field, "0.9999")), new Decimal10(field, "1234567890"), DfpField.FLAG_INEXACT, "RoundDecimal10 #43"); test(new Decimal10(field, "-1234567890").add(new Decimal10(field, "-0.0001")), new Decimal10(field, "-1234567891"), DfpField.FLAG_INEXACT, "RoundDecimal10 #44"); field.setRoundingMode(DfpField.RoundingMode.ROUND_HALF_EVEN); // reset } @Test public void testNextAfter() { test(new DfpDec(field, 1).nextAfter(pinf), new DfpDec(field, "1.0000000000000001"), 0, "NextAfter #1"); test(new DfpDec(field, "1.0000000000000001").nextAfter(ninf), new DfpDec(field, 1), 0, "NextAfter #1.5"); test(new DfpDec(field, 1).nextAfter(ninf), new DfpDec(field, "0.99999999999999999"), 0, "NextAfter #2"); test(new DfpDec(field, "0.99999999999999999").nextAfter(new DfpDec(field, 2)), new DfpDec(field, 1), 0, "NextAfter #3"); test(new DfpDec(field, -1).nextAfter(ninf), new DfpDec(field, "-1.0000000000000001"), 0, "NextAfter #4"); test(new DfpDec(field, -1).nextAfter(pinf), new DfpDec(field, "-0.99999999999999999"), 0, "NextAfter #5"); test(new DfpDec(field, "-0.99999999999999999").nextAfter(new DfpDec(field, -2)), new DfpDec(field, (byte) -1), 0, "NextAfter #6"); test(new DfpDec(field, (byte) 2).nextAfter(new DfpDec(field, 2)), new DfpDec(field, 2l), 0, "NextAfter #7"); test(new DfpDec(field, 0).nextAfter(new DfpDec(field, 0)), new DfpDec(field, 0), 0, "NextAfter #8"); test(new DfpDec(field, -2).nextAfter(new DfpDec(field, -2)), new DfpDec(field, -2), 0, "NextAfter #9"); test(new DfpDec(field, 0).nextAfter(new DfpDec(field, 1)), new DfpDec(field, "1e-131092"), DfpField.FLAG_UNDERFLOW, "NextAfter #10"); test(new DfpDec(field, 0).nextAfter(new DfpDec(field, -1)), new DfpDec(field, "-1e-131092"), DfpField.FLAG_UNDERFLOW, "NextAfter #11"); test(new DfpDec(field, "-1e-131092").nextAfter(pinf), new DfpDec(field, "-0"), DfpField.FLAG_UNDERFLOW|DfpField.FLAG_INEXACT, "Next After #12"); test(new DfpDec(field, "1e-131092").nextAfter(ninf), new DfpDec(field, "0"), DfpField.FLAG_UNDERFLOW|DfpField.FLAG_INEXACT, "Next After #13"); test(new DfpDec(field, "9.9999999999999999e131078").nextAfter(pinf), pinf, DfpField.FLAG_OVERFLOW|DfpField.FLAG_INEXACT, "Next After #14"); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/dfp/Decimal10.java100644 1750 1750 4765 11532241242 25523 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; public class Decimal10 extends DfpDec { Decimal10(final DfpField factory) { super(factory); } Decimal10(final DfpField factory, final byte x) { super(factory, x); } Decimal10(final DfpField factory, final int x) { super(factory, x); } Decimal10(final DfpField factory, final long x) { super(factory, x); } Decimal10(final DfpField factory, final double x) { super(factory, x); } public Decimal10(final Dfp d) { super(d); } public Decimal10(final DfpField factory, final String s) { super(factory, s); } protected Decimal10(final DfpField factory, final byte sign, final byte nans) { super(factory, sign, nans); } @Override public Dfp newInstance() { return new Decimal10(getField()); } @Override public Dfp newInstance(final byte x) { return new Decimal10(getField(), x); } @Override public Dfp newInstance(final int x) { return new Decimal10(getField(), x); } @Override public Dfp newInstance(final long x) { return new Decimal10(getField(), x); } @Override public Dfp newInstance(final double x) { return new Decimal10(getField(), x); } @Override public Dfp newInstance(final Dfp d) { return new Decimal10(d); } @Override public Dfp newInstance(final String s) { return new Decimal10(getField(), s); } @Override public Dfp newInstance(final byte sign, final byte nans) { return new Decimal10(getField(), sign, nans); } @Override protected int getDecimalDigits() { return 10; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/PascalDistributionTest.java100644 1750 1750 13051 11532241241 32440 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for PascalDistribution. * Extends IntegerDistributionAbstractTest. See class javadoc for * IntegerDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class PascalDistributionTest extends IntegerDistributionAbstractTest { /** * Constructor for PascalDistributionTest. * @param name */ public PascalDistributionTest(String name) { super(name); } // --------------------- Override tolerance -------------- protected double defaultTolerance = NormalDistributionImpl.DEFAULT_INVERSE_ABSOLUTE_ACCURACY; @Override protected void setUp() throws Exception { super.setUp(); setTolerance(defaultTolerance); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default discrete distribution instance to use in tests. */ @Override public IntegerDistribution makeDistribution() { return new PascalDistributionImpl(10,0.70); } /** Creates the default probability density test input values */ @Override public int[] makeDensityTestPoints() { return new int[] {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0, 0.0282475249, 0.0847425747, 0.139825248255, 0.167790297906, 0.163595540458, 0.137420253985, 0.103065190489, 0.070673273478, 0.0450542118422, 0.0270325271053, 0.0154085404500, 0.0084046584273}; } /** Creates the default cumulative probability density test input values */ @Override public int[] makeCumulativeTestPoints() { return makeDensityTestPoints(); } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0, 0.0282475249, 0.1129900996, 0.252815347855, 0.420605645761, 0.584201186219, 0.721621440204, 0.824686630693, 0.895359904171, 0.940414116013, 0.967446643119, 0.982855183569, 0.991259841996}; } /** Creates the default inverse cumulative probability test input values */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] {0, 0.001d, 0.010d, 0.025d, 0.050d, 0.100d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1}; } /** Creates the default inverse cumulative probability density test expected values */ @Override public int[] makeInverseCumulativeTestValues() { return new int[] {-1, -1, -1, -1, 0, 0, 13, 10, 9, 8, 7, Integer.MAX_VALUE}; } //----------------- Additional test cases --------------------------------- /** Test degenerate case p = 0 */ public void testDegenerate0() throws Exception { setDistribution(new PascalDistributionImpl(5,0.0d)); setCumulativeTestPoints(new int[] {-1, 0, 1, 5, 10 }); setCumulativeTestValues(new double[] {0d, 0d, 0d, 0d, 0d}); setDensityTestPoints(new int[] {-1, 0, 1, 10, 11}); setDensityTestValues(new double[] {0d, 0d, 0d, 0d, 0d}); setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d}); setInverseCumulativeTestValues(new int[] {Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 1}); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } /** Test degenerate case p = 1 */ public void testDegenerate1() throws Exception { setDistribution(new PascalDistributionImpl(5,1.0d)); setCumulativeTestPoints(new int[] {-1, 0, 1, 2, 5, 10 }); setCumulativeTestValues(new double[] {0d, 1d, 1d, 1d, 1d, 1d}); setDensityTestPoints(new int[] {-1, 0, 1, 2, 5, 10}); setDensityTestValues(new double[] {0d, 1d, 0d, 0d, 0d, 0d}); setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d}); setInverseCumulativeTestValues(new int[] {-1, -1}); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } public void testMomonts() { final double tol = 1e-9; PascalDistributionImpl dist; dist = new PascalDistributionImpl(10, 0.5); assertEquals(dist.getNumericalMean(), ( 10d * 0.5d ) / 0.5d, tol); assertEquals(dist.getNumericalVariance(), ( 10d * 0.5d ) / (0.5d * 0.5d), tol); dist.setNumberOfSuccesses(25); dist.setProbabilityOfSuccess(0.3); assertEquals(dist.getNumericalMean(), ( 25d * 0.3d ) / 0.7d, tol); assertEquals(dist.getNumericalVariance(), ( 25d * 0.3d ) / (0.7d * 0.7d), tol); } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ContinuousDistributionAbstractTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ContinuousDistributionAbstra100644 1750 1750 33122 11532241241 32761 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; /** * Abstract base class for {@link ContinuousDistribution} tests. *

                  * To create a concrete test class for a continuous distribution * implementation, first implement makeDistribution() to return a distribution * instance to use in tests. Then implement each of the test data generation * methods below. In each case, the test points and test values arrays * returned represent parallel arrays of inputs and expected values for the * distribution returned by makeDistribution(). Default implementations * are provided for the makeInverseXxx methods that just invert the mapping * defined by the arrays returned by the makeCumulativeXxx methods. *

                  * makeCumulativeTestPoints() -- arguments used to test cumulative probabilities * makeCumulativeTestValues() -- expected cumulative probabilites * makeDensityTestValues() -- expected density values at cumulativeTestPoints * makeInverseCumulativeTestPoints() -- arguments used to test inverse cdf * makeInverseCumulativeTestValues() -- expected inverse cdf values *

                  * To implement additional test cases with different distribution instances and * test data, use the setXxx methods for the instance data in test cases and * call the verifyXxx methods to verify results. *

                  * Error tolerance can be overriden by implementing getTolerance(). *

                  * Test data should be validated against reference tables or other packages * where possible, and the source of the reference data and/or validation * should be documented in the test cases. A framework for validating * distribution data against R is included in the /src/test/R source tree. *

                  * See {@link NormalDistributionTest} and {@link ChiSquareDistributionTest} * for examples. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class ContinuousDistributionAbstractTest extends TestCase { //-------------------- Private test instance data ------------------------- /** Distribution instance used to perform tests */ private ContinuousDistribution distribution; /** Tolerance used in comparing expected and returned values */ private double tolerance = 1E-4; /** Arguments used to test cumulative probability density calculations */ private double[] cumulativeTestPoints; /** Values used to test cumulative probability density calculations */ private double[] cumulativeTestValues; /** Arguments used to test inverse cumulative probability density calculations */ private double[] inverseCumulativeTestPoints; /** Values used to test inverse cumulative probability density calculations */ private double[] inverseCumulativeTestValues; /** Values used to test density calculations */ private double[] densityTestValues; //------------------------------------------------------------------------- /** * Constructor for ContinuousDistributionAbstractTest. * @param name */ public ContinuousDistributionAbstractTest(String name) { super(name); } //-------------------- Abstract methods ----------------------------------- /** Creates the default continuous distribution instance to use in tests. */ public abstract ContinuousDistribution makeDistribution(); /** Creates the default cumulative probability test input values */ public abstract double[] makeCumulativeTestPoints(); /** Creates the default cumulative probability test expected values */ public abstract double[] makeCumulativeTestValues(); /** Creates the default density test expected values */ public abstract double[] makeDensityTestValues(); //---- Default implementations of inverse test data generation methods ---- /** Creates the default inverse cumulative probability test input values */ public double[] makeInverseCumulativeTestPoints() { return makeCumulativeTestValues(); } /** Creates the default inverse cumulative probability density test expected values */ public double[] makeInverseCumulativeTestValues() { return makeCumulativeTestPoints(); } //-------------------- Setup / tear down ---------------------------------- /** * Setup sets all test instance data to default values */ @Override protected void setUp() throws Exception { super.setUp(); distribution = makeDistribution(); cumulativeTestPoints = makeCumulativeTestPoints(); cumulativeTestValues = makeCumulativeTestValues(); inverseCumulativeTestPoints = makeInverseCumulativeTestPoints(); inverseCumulativeTestValues = makeInverseCumulativeTestValues(); densityTestValues = makeDensityTestValues(); } /** * Cleans up test instance data */ @Override protected void tearDown() throws Exception { super.tearDown(); distribution = null; cumulativeTestPoints = null; cumulativeTestValues = null; inverseCumulativeTestPoints = null; inverseCumulativeTestValues = null; densityTestValues = null; } //-------------------- Verification methods ------------------------------- /** * Verifies that cumulative probability density calculations match expected values * using current test instance data */ protected void verifyCumulativeProbabilities() throws Exception { for (int i = 0; i < cumulativeTestPoints.length; i++) { TestUtils.assertEquals("Incorrect cumulative probability value returned for " + cumulativeTestPoints[i], cumulativeTestValues[i], distribution.cumulativeProbability(cumulativeTestPoints[i]), getTolerance()); } } /** * Verifies that inverse cumulative probability density calculations match expected values * using current test instance data */ protected void verifyInverseCumulativeProbabilities() throws Exception { for (int i = 0; i < inverseCumulativeTestPoints.length; i++) { TestUtils.assertEquals("Incorrect inverse cumulative probability value returned for " + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i], distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i]), getTolerance()); } } /** * Verifies that density calculations match expected values */ protected void verifyDensities() throws Exception { for (int i = 0; i < cumulativeTestPoints.length; i++) { TestUtils.assertEquals("Incorrect probability density value returned for " + cumulativeTestPoints[i], densityTestValues[i], //TODO: remove cast when density(double) is added to ContinuousDistribution ((AbstractContinuousDistribution) distribution).density(cumulativeTestPoints[i]), getTolerance()); } } //------------------------ Default test cases ----------------------------- /** * Verifies that cumulative probability density calculations match expected values * using default test instance data */ public void testCumulativeProbabilities() throws Exception { verifyCumulativeProbabilities(); } /** * Verifies that inverse cumulative probability density calculations match expected values * using default test instance data */ public void testInverseCumulativeProbabilities() throws Exception { verifyInverseCumulativeProbabilities(); } /** * Verifies that density calculations return expected values * for default test instance data */ public void testDensities() throws Exception { verifyDensities(); } /** * Verifies that probability computations are consistent */ public void testConsistency() throws Exception { for (int i=1; i < cumulativeTestPoints.length; i++) { // check that cdf(x, x) = 0 TestUtils.assertEquals(0d, distribution.cumulativeProbability (cumulativeTestPoints[i], cumulativeTestPoints[i]), tolerance); // check that P(a < X < b) = P(X < b) - P(X < a) double upper = FastMath.max(cumulativeTestPoints[i], cumulativeTestPoints[i -1]); double lower = FastMath.min(cumulativeTestPoints[i], cumulativeTestPoints[i -1]); double diff = distribution.cumulativeProbability(upper) - distribution.cumulativeProbability(lower); double direct = distribution.cumulativeProbability(lower, upper); TestUtils.assertEquals("Inconsistent cumulative probabilities for (" + lower + "," + upper + ")", diff, direct, tolerance); } } /** * Verifies that illegal arguments are correctly handled */ public void testIllegalArguments() throws Exception { try { distribution.cumulativeProbability(1, 0); fail("Expecting IllegalArgumentException for bad cumulativeProbability interval"); } catch (IllegalArgumentException ex) { // expected } try { distribution.inverseCumulativeProbability(-1); fail("Expecting IllegalArgumentException for p = -1"); } catch (IllegalArgumentException ex) { // expected } try { distribution.inverseCumulativeProbability(2); fail("Expecting IllegalArgumentException for p = 2"); } catch (IllegalArgumentException ex) { // expected } } /** * Test sampling */ public void testSampling() throws Exception { AbstractContinuousDistribution dist = (AbstractContinuousDistribution) makeDistribution(); final int sampleSize = 1000; double[] sample = dist.sample(sampleSize); double[] quartiles = TestUtils.getDistributionQuartiles(dist); double[] expected = {250, 250, 250, 250}; long[] counts = new long[4]; dist.reseedRandomGenerator(1000); // Use fixed seed for (int i = 0; i < sampleSize; i++) { TestUtils.updateCounts(sample[i], counts, quartiles); } TestUtils.assertChiSquareAccept(expected, counts, 0.001); } //------------------ Getters / Setters for test instance data ----------- /** * @return Returns the cumulativeTestPoints. */ protected double[] getCumulativeTestPoints() { return cumulativeTestPoints; } /** * @param cumulativeTestPoints The cumulativeTestPoints to set. */ protected void setCumulativeTestPoints(double[] cumulativeTestPoints) { this.cumulativeTestPoints = cumulativeTestPoints; } /** * @return Returns the cumulativeTestValues. */ protected double[] getCumulativeTestValues() { return cumulativeTestValues; } /** * @param cumulativeTestValues The cumulativeTestValues to set. */ protected void setCumulativeTestValues(double[] cumulativeTestValues) { this.cumulativeTestValues = cumulativeTestValues; } protected double[] getDensityTestValues() { return densityTestValues; } protected void setDensityTestValues(double[] densityTestValues) { this.densityTestValues = densityTestValues; } /** * @return Returns the distribution. */ protected ContinuousDistribution getDistribution() { return distribution; } /** * @param distribution The distribution to set. */ protected void setDistribution(AbstractContinuousDistribution distribution) { this.distribution = distribution; } /** * @return Returns the inverseCumulativeTestPoints. */ protected double[] getInverseCumulativeTestPoints() { return inverseCumulativeTestPoints; } /** * @param inverseCumulativeTestPoints The inverseCumulativeTestPoints to set. */ protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) { this.inverseCumulativeTestPoints = inverseCumulativeTestPoints; } /** * @return Returns the inverseCumulativeTestValues. */ protected double[] getInverseCumulativeTestValues() { return inverseCumulativeTestValues; } /** * @param inverseCumulativeTestValues The inverseCumulativeTestValues to set. */ protected void setInverseCumulativeTestValues(double[] inverseCumulativeTestValues) { this.inverseCumulativeTestValues = inverseCumulativeTestValues; } /** * @return Returns the tolerance. */ protected double getTolerance() { return tolerance; } /** * @param tolerance The tolerance to set. */ protected void setTolerance(double tolerance) { this.tolerance = tolerance; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ZipfDistributionTest.java100644 1750 1750 6535 11532241241 32136 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.util.FastMath; /** * Test cases for {@link ZipfDistribution}. * Extends IntegerDistributionAbstractTest. See class javadoc for * IntegerDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class ZipfDistributionTest extends IntegerDistributionAbstractTest { public ZipfDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default discrete distribution instance to use in tests. */ @Override public IntegerDistribution makeDistribution() { return new ZipfDistributionImpl(10, 1); } /** Creates the default probability density test input values */ @Override public int[] makeDensityTestPoints() { return new int[] {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0d, 0d, 0.3414d, 0.1707d, 0.1138d, 0.0854d, 0.0683d, 0.0569d, 0.0488d, 0.0427d, 0.0379d, 0.0341d, 0d}; } /** Creates the default cumulative probability density test input values */ @Override public int[] makeCumulativeTestPoints() { return makeDensityTestPoints(); } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0d, 0.0000d, 0.3414d, 0.5121d, 0.6259d, 0.7113d, 0.7796d, 0.8365d, 0.8852d, 0.9279d, 0.9659d, 1d, 1d}; } /** Creates the default inverse cumulative probability test input values */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] {0, 0.001d, 0.010d, 0.025d, 0.050d, 0.3414d, 0.3415d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1}; } /** Creates the default inverse cumulative probability density test expected values */ @Override public int[] makeInverseCumulativeTestValues() { return new int[] {0, 0, 0, 0, 0, 0, 1, 9, 9, 9, 8, 7, 10}; } public void testMomonts() { final double tol = 1e-9; ZipfDistributionImpl dist; dist = new ZipfDistributionImpl(2, 0.5); assertEquals(dist.getNumericalMean(), FastMath.sqrt(2), tol); assertEquals(dist.getNumericalVariance(), 0.24264068711928521, tol); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ChiSquareDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ChiSquareDistributionTest.ja100644 1750 1750 14420 11532241241 32573 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for ChiSquareDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class ChiSquareDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for ChiSquareDistributionTest. * @param name */ public ChiSquareDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public ChiSquaredDistribution makeDistribution() { return new ChiSquaredDistributionImpl(5.0); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {0.210212602629, 0.554298076728, 0.831211613487, 1.14547622606, 1.61030798696, 20.5150056524, 15.0862724694, 12.8325019940, 11.0704976935, 9.23635689978}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default inverse cumulative probability test input values */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] {0, 0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1}; } /** Creates the default inverse cumulative probability density test expected values */ @Override public double[] makeInverseCumulativeTestValues() { return new double[] {0, 0.210212602629, 0.554298076728, 0.831211613487, 1.14547622606, 1.61030798696, 20.5150056524, 15.0862724694, 12.8325019940, 11.0704976935, 9.23635689978, Double.POSITIVE_INFINITY}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.0115379817652, 0.0415948507811, 0.0665060119842, 0.0919455953114, 0.121472591024, 0.000433630076361, 0.00412780610309, 0.00999340341045, 0.0193246438937, 0.0368460089216}; } // --------------------- Override tolerance -------------- @Override protected void setUp() throws Exception { super.setUp(); setTolerance(1e-9); } //---------------------------- Additional test cases ------------------------- public void testSmallDf() throws Exception { setDistribution(new ChiSquaredDistributionImpl(0.1d)); setTolerance(1E-4); // quantiles computed using R version 1.8.1 (linux version) setCumulativeTestPoints(new double[] {1.168926E-60, 1.168926E-40, 1.063132E-32, 1.144775E-26, 1.168926E-20, 5.472917, 2.175255, 1.13438, 0.5318646, 0.1526342}); setInverseCumulativeTestValues(getCumulativeTestPoints()); setInverseCumulativeTestPoints(getCumulativeTestValues()); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } public void testDfAccessors() { ChiSquaredDistribution distribution = (ChiSquaredDistribution) getDistribution(); assertEquals(5d, distribution.getDegreesOfFreedom(), Double.MIN_VALUE); distribution.setDegreesOfFreedom(4d); assertEquals(4d, distribution.getDegreesOfFreedom(), Double.MIN_VALUE); try { distribution.setDegreesOfFreedom(0d); fail("Expecting IllegalArgumentException for df = 0"); } catch (IllegalArgumentException ex) { // expected } } public void testDensity() { double[] x = new double[]{-0.1, 1e-6, 0.5, 1, 2, 5}; //R 2.5: print(dchisq(x, df=1), digits=10) checkDensity(1, x, new double[]{0.00000000000, 398.94208093034, 0.43939128947, 0.24197072452, 0.10377687436, 0.01464498256}); //R 2.5: print(dchisq(x, df=0.1), digits=10) checkDensity(0.1, x, new double[]{0.000000000e+00, 2.486453997e+04, 7.464238732e-02, 3.009077718e-02, 9.447299159e-03, 8.827199396e-04}); //R 2.5: print(dchisq(x, df=2), digits=10) checkDensity(2, x, new double[]{0.00000000000, 0.49999975000, 0.38940039154, 0.30326532986, 0.18393972059, 0.04104249931}); //R 2.5: print(dchisq(x, df=10), digits=10) checkDensity(10, x, new double[]{0.000000000e+00, 1.302082682e-27, 6.337896998e-05, 7.897534632e-04, 7.664155024e-03, 6.680094289e-02}); } private void checkDensity(double df, double[] x, double[] expected) { ChiSquaredDistribution d = new ChiSquaredDistributionImpl(df); for (int i = 0; i < x.length; i++) { assertEquals(expected[i], d.density(x[i]), 1e-5); } } public void testMomonts() { final double tol = 1e-9; ChiSquaredDistributionImpl dist; dist = new ChiSquaredDistributionImpl(1500); assertEquals(dist.getNumericalMean(), 1500, tol); assertEquals(dist.getNumericalVariance(), 3000, tol); dist.setDegreesOfFreedom(1.12); assertEquals(dist.getNumericalMean(), 1.12, tol); assertEquals(dist.getNumericalVariance(), 2.24, tol); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/FDistributionTest.java100644 1750 1750 14021 11532241241 31420 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for FDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class FDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for FDistributionTest. * @param name */ public FDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public FDistribution makeDistribution() { return new FDistributionImpl(5.0, 6.0); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {0.0346808448626, 0.0937009113303, 0.143313661184, 0.202008445998, 0.293728320107, 20.8026639595, 8.74589525602, 5.98756512605, 4.38737418741, 3.10751166664}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.0689156576706, 0.236735653193, 0.364074131941, 0.481570789649, 0.595880479994, 0.000133443915657, 0.00286681303403, 0.00969192007502, 0.0242883861471, 0.0605491314658}; } // --------------------- Override tolerance -------------- @Override protected void setUp() throws Exception { super.setUp(); setTolerance(1e-9); } //---------------------------- Additional test cases ------------------------- public void testCumulativeProbabilityExtremes() throws Exception { setCumulativeTestPoints(new double[] {-2, 0}); setCumulativeTestValues(new double[] {0, 0}); verifyCumulativeProbabilities(); } public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0, 1}); setInverseCumulativeTestValues(new double[] {0, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testDfAccessors() { FDistribution distribution = (FDistribution) getDistribution(); assertEquals(5d, distribution.getNumeratorDegreesOfFreedom(), Double.MIN_VALUE); distribution.setNumeratorDegreesOfFreedom(4d); assertEquals(4d, distribution.getNumeratorDegreesOfFreedom(), Double.MIN_VALUE); assertEquals(6d, distribution.getDenominatorDegreesOfFreedom(), Double.MIN_VALUE); distribution.setDenominatorDegreesOfFreedom(4d); assertEquals(4d, distribution.getDenominatorDegreesOfFreedom(), Double.MIN_VALUE); try { distribution.setNumeratorDegreesOfFreedom(0d); fail("Expecting IllegalArgumentException for df = 0"); } catch (IllegalArgumentException ex) { // expected } try { distribution.setDenominatorDegreesOfFreedom(0d); fail("Expecting IllegalArgumentException for df = 0"); } catch (IllegalArgumentException ex) { // expected } } public void testLargeDegreesOfFreedom() throws Exception { org.apache.commons.math.distribution.FDistributionImpl fd = new org.apache.commons.math.distribution.FDistributionImpl( 100000., 100000.); double p = fd.cumulativeProbability(.999); double x = fd.inverseCumulativeProbability(p); assertEquals(.999, x, 1.0e-5); } public void testSmallDegreesOfFreedom() throws Exception { org.apache.commons.math.distribution.FDistributionImpl fd = new org.apache.commons.math.distribution.FDistributionImpl( 1.0, 1.0); double p = fd.cumulativeProbability(0.975); double x = fd.inverseCumulativeProbability(p); assertEquals(0.975, x, 1.0e-5); fd.setDenominatorDegreesOfFreedom(2.0); p = fd.cumulativeProbability(0.975); x = fd.inverseCumulativeProbability(p); assertEquals(0.975, x, 1.0e-5); } public void testMomonts() { final double tol = 1e-9; FDistributionImpl dist; dist = new FDistributionImpl(1, 2); assertTrue(Double.isNaN(dist.getNumericalMean())); assertTrue(Double.isNaN(dist.getNumericalVariance())); dist.setNumeratorDegreesOfFreedom(1); dist.setDenominatorDegreesOfFreedom(3); assertEquals(dist.getNumericalMean(), 3d / (3d - 2d), tol); assertTrue(Double.isNaN(dist.getNumericalVariance())); dist.setNumeratorDegreesOfFreedom(1); dist.setDenominatorDegreesOfFreedom(5); assertEquals(dist.getNumericalMean(), 5d / (5d - 2d), tol); assertEquals(dist.getNumericalVariance(), (2d * 5d * 5d * 4d) / 9d, tol); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java100644 1750 1750 22750 11532241241 32473 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; import org.apache.commons.math.util.FastMath; /** * Test cases for NormalDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class NormalDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for NormalDistributionTest. * @param arg0 */ public NormalDistributionTest(String arg0) { super(arg0); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public NormalDistribution makeDistribution() { return new NormalDistributionImpl(2.1, 1.4); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R return new double[] {-2.226325228634938d, -1.156887023657177d, -0.643949578356075d, -0.2027950777320613d, 0.305827808237559d, 6.42632522863494d, 5.35688702365718d, 4.843949578356074d, 4.40279507773206d, 3.89417219176244d}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380, 0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380}; } // --------------------- Override tolerance -------------- protected double defaultTolerance = NormalDistributionImpl.DEFAULT_INVERSE_ABSOLUTE_ACCURACY; @Override protected void setUp() throws Exception { super.setUp(); setTolerance(defaultTolerance); } //---------------------------- Additional test cases ------------------------- private void verifyQuantiles() throws Exception { NormalDistribution distribution = (NormalDistribution) getDistribution(); double mu = distribution.getMean(); double sigma = distribution.getStandardDeviation(); setCumulativeTestPoints( new double[] {mu - 2 *sigma, mu - sigma, mu, mu + sigma, mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, mu + 5 * sigma}); // Quantiles computed using R (same as Mathematica) setCumulativeTestValues(new double[] {0.02275013194817921, 0.158655253931457, 0.5, 0.841344746068543, 0.977249868051821, 0.99865010196837, 0.999968328758167, 0.999999713348428}); verifyCumulativeProbabilities(); } public void testQuantiles() throws Exception { setDensityTestValues(new double[] {0.0385649760808, 0.172836231799, 0.284958771715, 0.172836231799, 0.0385649760808, 0.00316560600853, 9.55930184035e-05, 1.06194251052e-06}); verifyQuantiles(); verifyDensities(); setDistribution(new NormalDistributionImpl(0, 1)); setDensityTestValues(new double[] {0.0539909665132, 0.241970724519, 0.398942280401, 0.241970724519, 0.0539909665132, 0.00443184841194, 0.000133830225765, 1.48671951473e-06}); verifyQuantiles(); verifyDensities(); setDistribution(new NormalDistributionImpl(0, 0.1)); setDensityTestValues(new double[] {0.539909665132, 2.41970724519, 3.98942280401, 2.41970724519, 0.539909665132, 0.0443184841194, 0.00133830225765, 1.48671951473e-05}); verifyQuantiles(); verifyDensities(); } public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0, 1}); setInverseCumulativeTestValues( new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testGetMean() { NormalDistribution distribution = (NormalDistribution) getDistribution(); assertEquals(2.1, distribution.getMean(), 0); } public void testSetMean() throws Exception { double mu = FastMath.random(); NormalDistribution distribution = (NormalDistribution) getDistribution(); distribution.setMean(mu); verifyQuantiles(); } public void testGetStandardDeviation() { NormalDistribution distribution = (NormalDistribution) getDistribution(); assertEquals(1.4, distribution.getStandardDeviation(), 0); } public void testSetStandardDeviation() throws Exception { double sigma = 0.1d + FastMath.random(); NormalDistribution distribution = (NormalDistribution) getDistribution(); distribution.setStandardDeviation(sigma); assertEquals(sigma, distribution.getStandardDeviation(), 0); verifyQuantiles(); try { distribution.setStandardDeviation(0); fail("Expecting IllegalArgumentException for sd = 0"); } catch (IllegalArgumentException ex) { // Expected } } public void testDensity() { double [] x = new double[]{-2, -1, 0, 1, 2}; // R 2.5: print(dnorm(c(-2,-1,0,1,2)), digits=10) checkDensity(0, 1, x, new double[]{0.05399096651, 0.24197072452, 0.39894228040, 0.24197072452, 0.05399096651}); // R 2.5: print(dnorm(c(-2,-1,0,1,2), mean=1.1), digits=10) checkDensity(1.1, 1, x, new double[]{0.003266819056,0.043983595980,0.217852177033,0.396952547477,0.266085249899}); } private void checkDensity(double mean, double sd, double[] x, double[] expected) { NormalDistribution d = new NormalDistributionImpl(mean, sd); for (int i = 0; i < x.length; i++) { assertEquals(expected[i], d.density(x[i]), 1e-9); } } /** * Check to make sure top-coding of extreme values works correctly. * Verifies fixes for JIRA MATH-167, MATH-414 */ public void testExtremeValues() throws Exception { NormalDistribution distribution = (NormalDistribution) getDistribution(); distribution.setMean(0); distribution.setStandardDeviation(1); for (int i = 0; i < 100; i++) { // make sure no convergence exception double lowerTail = distribution.cumulativeProbability(-i); double upperTail = distribution.cumulativeProbability(i); if (i < 9) { // make sure not top-coded // For i = 10, due to bad tail precision in erf (MATH-364), 1 is returned // TODO: once MATH-364 is resolved, replace 9 with 30 assertTrue(lowerTail > 0.0d); assertTrue(upperTail < 1.0d); } else { // make sure top coding not reversed assertTrue(lowerTail < 0.00001); assertTrue(upperTail > 0.99999); } } assertEquals(distribution.cumulativeProbability(Double.MAX_VALUE), 1, 0); assertEquals(distribution.cumulativeProbability(-Double.MAX_VALUE), 0, 0); assertEquals(distribution.cumulativeProbability(Double.POSITIVE_INFINITY), 1, 0); assertEquals(distribution.cumulativeProbability(Double.NEGATIVE_INFINITY), 0, 0); } public void testMath280() throws MathException { NormalDistribution normal = new NormalDistributionImpl(0,1); double result = normal.inverseCumulativeProbability(0.9986501019683698); assertEquals(3.0, result, defaultTolerance); result = normal.inverseCumulativeProbability(0.841344746068543); assertEquals(1.0, result, defaultTolerance); result = normal.inverseCumulativeProbability(0.9999683287581673); assertEquals(4.0, result, defaultTolerance); result = normal.inverseCumulativeProbability(0.9772498680518209); assertEquals(2.0, result, defaultTolerance); } public void testMomonts() { final double tol = 1e-9; NormalDistributionImpl dist; dist = new NormalDistributionImpl(0, 1); assertEquals(dist.getNumericalVariance(), 1, tol); dist.setMean(2.2); dist.setStandardDeviation(1.4); assertEquals(dist.getNumericalVariance(), 1.4 * 1.4, tol); dist.setMean(-2000.9); dist.setStandardDeviation(10.4); assertEquals(dist.getNumericalVariance(), 10.4 * 10.4, tol); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/TDistributionTest.java100644 1750 1750 12727 11532241241 31451 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for TDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class TDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for TDistributionTest. * @param name */ public TDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public TDistribution makeDistribution() { return new TDistributionImpl(5.0); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {-5.89342953136, -3.36492999891, -2.57058183564, -2.01504837333, -1.47588404882, 5.89342953136, 3.36492999891, 2.57058183564, 2.01504837333, 1.47588404882}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005, 0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005}; } // --------------------- Override tolerance -------------- @Override protected void setUp() throws Exception { super.setUp(); setTolerance(1E-9); } //---------------------------- Additional test cases ------------------------- /** * @see * Bug report that prompted this unit test. */ public void testCumulativeProbabilityAgaintStackOverflow() throws Exception { TDistributionImpl td = new TDistributionImpl(5.); td.cumulativeProbability(.1); td.cumulativeProbability(.01); } public void testSmallDf() throws Exception { setDistribution(new TDistributionImpl(1d)); // quantiles computed using R version 2.9.2 setCumulativeTestPoints(new double[] {-318.308838986, -31.8205159538, -12.7062047362, -6.31375151468, -3.07768353718, 318.308838986, 31.8205159538, 12.7062047362, 6.31375151468, 3.07768353718}); setDensityTestValues(new double[] {3.14158231817e-06, 0.000314055924703, 0.00195946145194, 0.00778959736375, 0.0303958893917, 3.14158231817e-06, 0.000314055924703, 0.00195946145194, 0.00778959736375, 0.0303958893917}); setInverseCumulativeTestValues(getCumulativeTestPoints()); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); verifyDensities(); } public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0, 1}); setInverseCumulativeTestValues( new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testDfAccessors() { TDistribution distribution = (TDistribution) getDistribution(); assertEquals(5d, distribution.getDegreesOfFreedom(), Double.MIN_VALUE); distribution.setDegreesOfFreedom(4d); assertEquals(4d, distribution.getDegreesOfFreedom(), Double.MIN_VALUE); try { distribution.setDegreesOfFreedom(0d); fail("Expecting IllegalArgumentException for df = 0"); } catch (IllegalArgumentException ex) { // expected } } public void testMomonts() { final double tol = 1e-9; TDistributionImpl dist; dist = new TDistributionImpl(1); assertTrue(Double.isNaN(dist.getNumericalMean())); assertTrue(Double.isNaN(dist.getNumericalVariance())); dist.setDegreesOfFreedom(1.5); assertEquals(dist.getNumericalMean(), 0, tol); assertTrue(Double.isInfinite(dist.getNumericalVariance())); dist.setDegreesOfFreedom(5); assertEquals(dist.getNumericalMean(), 0, tol); assertEquals(dist.getNumericalVariance(), 5d / (5d - 2d), tol); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/CauchyDistributionTest.java100644 1750 1750 11443 11532241241 32454 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.util.FastMath; /** * Test cases for CauchyDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class CauchyDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for CauchyDistributionTest. * @param arg0 */ public CauchyDistributionTest(String arg0) { super(arg0); } // --------------------- Override tolerance -------------- protected double defaultTolerance = NormalDistributionImpl.DEFAULT_INVERSE_ABSOLUTE_ACCURACY; @Override protected void setUp() throws Exception { super.setUp(); setTolerance(defaultTolerance); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public CauchyDistribution makeDistribution() { return new CauchyDistributionImpl(1.2, 2.1); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R 2.9.2 return new double[] {-667.24856187, -65.6230835029, -25.4830299460, -12.0588781808, -5.26313542807, 669.64856187, 68.0230835029, 27.8830299460, 14.4588781808, 7.66313542807}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {1.49599158008e-06, 0.000149550440335, 0.000933076881878, 0.00370933207799, 0.0144742330437, 1.49599158008e-06, 0.000149550440335, 0.000933076881878, 0.00370933207799, 0.0144742330437}; } //---------------------------- Additional test cases ------------------------- public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0.0, 1.0}); setInverseCumulativeTestValues( new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testMedian() { CauchyDistribution distribution = (CauchyDistribution) getDistribution(); double expected = FastMath.random(); distribution.setMedian(expected); assertEquals(expected, distribution.getMedian(), 0.0); } public void testScale() { CauchyDistribution distribution = (CauchyDistribution) getDistribution(); double expected = FastMath.random(); distribution.setScale(expected); assertEquals(expected, distribution.getScale(), 0.0); } public void testSetScale() { CauchyDistribution distribution = (CauchyDistribution) getDistribution(); try { distribution.setScale(0.0); fail("Can not have 0.0 scale."); } catch (IllegalArgumentException ex) { // success } try { distribution.setScale(-1.0); fail("Can not have negative scale."); } catch (IllegalArgumentException ex) { // success } } public void testMomonts() { CauchyDistributionImpl dist; dist = new CauchyDistributionImpl(10.2, 0.15); assertTrue(Double.isNaN(dist.getNumericalMean())); assertTrue(Double.isNaN(dist.getNumericalVariance())); dist.setMedian(23.12); dist.setScale(2.12); assertTrue(Double.isNaN(dist.getNumericalMean())); assertTrue(Double.isNaN(dist.getNumericalVariance())); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/GammaDistributionTest.java100644 1750 1750 17077 11532241241 32273 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for GammaDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class GammaDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for GammaDistributionTest. * @param name */ public GammaDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public GammaDistribution makeDistribution() { return new GammaDistributionImpl(4d, 2d); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {0.857104827257, 1.64649737269, 2.17973074725, 2.7326367935, 3.48953912565, 26.1244815584, 20.0902350297, 17.5345461395, 15.5073130559, 13.3615661365}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.00427280075546, 0.0204117166709, 0.0362756163658, 0.0542113174239, 0.0773195272491, 0.000394468852816, 0.00366559696761, 0.00874649473311, 0.0166712508128, 0.0311798227954}; } // --------------------- Override tolerance -------------- @Override protected void setUp() throws Exception { super.setUp(); setTolerance(1e-9); } //---------------------------- Additional test cases ------------------------- public void testParameterAccessors() { GammaDistribution distribution = (GammaDistribution) getDistribution(); assertEquals(4d, distribution.getAlpha(), 0); distribution.setAlpha(3d); assertEquals(3d, distribution.getAlpha(), 0); assertEquals(2d, distribution.getBeta(), 0); distribution.setBeta(4d); assertEquals(4d, distribution.getBeta(), 0); try { distribution.setAlpha(0d); fail("Expecting IllegalArgumentException for alpha = 0"); } catch (IllegalArgumentException ex) { // expected } try { distribution.setBeta(0d); fail("Expecting IllegalArgumentException for beta = 0"); } catch (IllegalArgumentException ex) { // expected } } public void testProbabilities() throws Exception { testProbability(-1.000, 4.0, 2.0, .0000); testProbability(15.501, 4.0, 2.0, .9499); testProbability(0.504, 4.0, 1.0, .0018); testProbability(10.011, 1.0, 2.0, .9933); testProbability(5.000, 2.0, 2.0, .7127); } public void testValues() throws Exception { testValue(15.501, 4.0, 2.0, .9499); testValue(0.504, 4.0, 1.0, .0018); testValue(10.011, 1.0, 2.0, .9933); testValue(5.000, 2.0, 2.0, .7127); } private void testProbability(double x, double a, double b, double expected) throws Exception { GammaDistribution distribution = new GammaDistributionImpl( a, b ); double actual = distribution.cumulativeProbability(x); assertEquals("probability for " + x, expected, actual, 10e-4); } private void testValue(double expected, double a, double b, double p) throws Exception { GammaDistribution distribution = new GammaDistributionImpl( a, b ); double actual = distribution.inverseCumulativeProbability(p); assertEquals("critical value for " + p, expected, actual, 10e-4); } public void testDensity() { double[] x = new double[]{-0.1, 1e-6, 0.5, 1, 2, 5}; // R2.5: print(dgamma(x, shape=1, rate=1), digits=10) checkDensity(1, 1, x, new double[]{0.000000000000, 0.999999000001, 0.606530659713, 0.367879441171, 0.135335283237, 0.006737946999}); // R2.5: print(dgamma(x, shape=2, rate=1), digits=10) checkDensity(2, 1, x, new double[]{0.000000000000, 0.000000999999, 0.303265329856, 0.367879441171, 0.270670566473, 0.033689734995}); // R2.5: print(dgamma(x, shape=4, rate=1), digits=10) checkDensity(4, 1, x, new double[]{0.000000000e+00, 1.666665000e-19, 1.263605541e-02, 6.131324020e-02, 1.804470443e-01, 1.403738958e-01}); // R2.5: print(dgamma(x, shape=4, rate=10), digits=10) checkDensity(4, 10, x, new double[]{0.000000000e+00, 1.666650000e-15, 1.403738958e+00, 7.566654960e-02, 2.748204830e-05, 4.018228850e-17}); // R2.5: print(dgamma(x, shape=.1, rate=10), digits=10) checkDensity(0.1, 10, x, new double[]{0.000000000e+00, 3.323953832e+04, 1.663849010e-03, 6.007786726e-06, 1.461647647e-10, 5.996008322e-24}); // R2.5: print(dgamma(x, shape=.1, rate=20), digits=10) checkDensity(0.1, 20, x, new double[]{0.000000000e+00, 3.562489883e+04, 1.201557345e-05, 2.923295295e-10, 3.228910843e-19, 1.239484589e-45}); // R2.5: print(dgamma(x, shape=.1, rate=4), digits=10) checkDensity(0.1, 4, x, new double[]{0.000000000e+00, 3.032938388e+04, 3.049322494e-02, 2.211502311e-03, 2.170613371e-05, 5.846590589e-11}); // R2.5: print(dgamma(x, shape=.1, rate=1), digits=10) checkDensity(0.1, 1, x, new double[]{0.000000000e+00, 2.640334143e+04, 1.189704437e-01, 3.866916944e-02, 7.623306235e-03, 1.663849010e-04}); } private void checkDensity(double alpha, double rate, double[] x, double[] expected) { GammaDistribution d = new GammaDistributionImpl(alpha, 1 / rate); for (int i = 0; i < x.length; i++) { assertEquals(expected[i], d.density(x[i]), 1e-5); } } public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0, 1}); setInverseCumulativeTestValues(new double[] {0, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testMomonts() { final double tol = 1e-9; GammaDistributionImpl dist; dist = new GammaDistributionImpl(1, 2); assertEquals(dist.getNumericalMean(), 2, tol); assertEquals(dist.getNumericalVariance(), 4, tol); dist.setAlpha(1.1); dist.setBeta(4.2); assertEquals(dist.getNumericalMean(), 1.1d * 4.2d, tol); assertEquals(dist.getNumericalVariance(), 1.1d * 4.2d * 4.2d, tol); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ExponentialDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/ExponentialDistributionTest.100644 1750 1750 12413 11532241241 32662 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.util.FastMath; /** * Test cases for ExponentialDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class ExponentialDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for ExponentialDistributionTest. * @param name */ public ExponentialDistributionTest(String name) { super(name); } // --------------------- Override tolerance -------------- @Override protected void setUp() throws Exception { super.setUp(); setTolerance(1E-9); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public ExponentialDistribution makeDistribution() { return new ExponentialDistributionImpl(5.0); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {0.00500250166792, 0.0502516792675, 0.126589039921, 0.256466471938, 0.526802578289, 34.5387763949, 23.0258509299, 18.4443972706, 14.9786613678, 11.5129254650}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.1998, 0.198, 0.195, 0.19, 0.18, 0.000200000000000, 0.00200000000002, 0.00499999999997, 0.00999999999994, 0.0199999999999}; } //------------ Additional tests ------------------------------------------- public void testCumulativeProbabilityExtremes() throws Exception { setCumulativeTestPoints(new double[] {-2, 0}); setCumulativeTestValues(new double[] {0, 0}); verifyCumulativeProbabilities(); } public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0, 1}); setInverseCumulativeTestValues(new double[] {0, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testCumulativeProbability2() throws Exception { double actual = getDistribution().cumulativeProbability(0.25, 0.75); assertEquals(0.0905214, actual, 10e-4); } public void testDensity() { ExponentialDistribution d1 = new ExponentialDistributionImpl(1); assertEquals(0.0, d1.density(-1e-9)); assertEquals(1.0, d1.density(0.0)); assertEquals(0.0, d1.density(1000.0)); assertEquals(FastMath.exp(-1), d1.density(1.0)); assertEquals(FastMath.exp(-2), d1.density(2.0)); ExponentialDistribution d2 = new ExponentialDistributionImpl(3); assertEquals(1/3.0, d2.density(0.0)); // computed using print(dexp(1, rate=1/3), digits=10) in R 2.5 assertEquals(0.2388437702, d2.density(1.0), 1e-8); // computed using print(dexp(2, rate=1/3), digits=10) in R 2.5 assertEquals(0.1711390397, d2.density(2.0), 1e-8); } public void testMeanAccessors() { ExponentialDistribution distribution = (ExponentialDistribution) getDistribution(); assertEquals(5d, distribution.getMean(), Double.MIN_VALUE); distribution.setMean(2d); assertEquals(2d, distribution.getMean(), Double.MIN_VALUE); try { distribution.setMean(0); fail("Expecting IllegalArgumentException for 0 mean"); } catch (IllegalArgumentException ex) { // expected } } public void testMomonts() { final double tol = 1e-9; ExponentialDistributionImpl dist; dist = new ExponentialDistributionImpl(11d); assertEquals(dist.getNumericalMean(), 11d, tol); assertEquals(dist.getNumericalVariance(), 11d * 11d, tol); dist.setMean(10.5d); assertEquals(dist.getNumericalMean(), 10.5d, tol); assertEquals(dist.getNumericalVariance(), 10.5d * 10.5d, tol); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/PoissonDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/PoissonDistributionTest.java100644 1750 1750 20401 11532241241 32664 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; import org.apache.commons.math.util.FastMath; /** * PoissonDistributionTest * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class PoissonDistributionTest extends IntegerDistributionAbstractTest { /** * Poisson parameter value for the test distribution. */ private static final double DEFAULT_TEST_POISSON_PARAMETER = 4.0; /** * Constructor. * @param name */ public PoissonDistributionTest(String name) { super(name); setTolerance(1e-12); } /** * Creates the default discrete distribution instance to use in tests. */ @Override public IntegerDistribution makeDistribution() { return new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER); } /** * Creates the default probability density test input values. */ @Override public int[] makeDensityTestPoints() { return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20}; } /** * Creates the default probability density test expected values. * These and all other test values are generated by R, version 1.8.1 */ @Override public double[] makeDensityTestValues() { return new double[] { 0d, 0.0183156388887d, 0.073262555555d, 0.14652511111d, 0.195366814813d, 0.195366814813, 0.156293451851d, 0.00529247667642d, 8.27746364655e-09}; } /** * Creates the default cumulative probability density test input values. */ @Override public int[] makeCumulativeTestPoints() { return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20 }; } /** * Creates the default cumulative probability density test expected values. */ @Override public double[] makeCumulativeTestValues() { return new double[] { 0d, 0.0183156388887d, 0.0915781944437d, 0.238103305554d, 0.433470120367d, 0.62883693518, 0.78513038703d, 0.99716023388d, 0.999999998077 }; } /** * Creates the default inverse cumulative probability test input values. * Increased 3rd and 7th values slightly as computed cumulative * probabilities for corresponding values exceeds the target value (still * within tolerance). */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] { 0d, 0.018315638889d, 0.0915781944437d, 0.238103305554d, 0.433470120367d, 0.62883693518, 0.78513038704d, 0.99716023388d, 0.999999998077 }; } /** * Creates the default inverse cumulative probability density test expected values. */ @Override public int[] makeInverseCumulativeTestValues() { return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20}; } /** * Test the normal approximation of the Poisson distribution by * calculating P(90 ≤ X ≤ 110) for X = Po(100) and * P(9900 ≤ X ≤ 10200) for X = Po(10000) */ public void testNormalApproximateProbability() throws Exception { PoissonDistribution dist = new PoissonDistributionImpl(100); double result = dist.normalApproximateProbability(110) - dist.normalApproximateProbability(89); assertEquals(0.706281887248, result, 1E-10); dist.setMean(10000); result = dist.normalApproximateProbability(10200) - dist.normalApproximateProbability(9899); assertEquals(0.820070051552, result, 1E-10); } /** * Test the degenerate cases of a 0.0 and 1.0 inverse cumulative probability. * @throws Exception */ public void testDegenerateInverseCumulativeProbability() throws Exception { PoissonDistribution dist = new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER); assertEquals(Integer.MAX_VALUE, dist.inverseCumulativeProbability(1.0d)); assertEquals(-1, dist.inverseCumulativeProbability(0d)); } public void testMean() { PoissonDistribution dist = new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER); try { dist.setMean(-1); fail("negative mean. IllegalArgumentException expected"); } catch(IllegalArgumentException ex) { } dist.setMean(10.0); assertEquals(10.0, dist.getMean(), 0.0); } public void testLargeMeanCumulativeProbability() { PoissonDistribution dist = new PoissonDistributionImpl(1.0); double mean = 1.0; while (mean <= 10000000.0) { dist.setMean(mean); double x = mean * 2.0; double dx = x / 10.0; double p = Double.NaN; double sigma = FastMath.sqrt(mean); while (x >= 0) { try { p = dist.cumulativeProbability(x); assertFalse("NaN cumulative probability returned for mean = " + mean + " x = " + x,Double.isNaN(p)); if (x > mean - 2 * sigma) { assertTrue("Zero cum probaility returned for mean = " + mean + " x = " + x, p > 0); } } catch (MathException ex) { fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage()); } x -= dx; } mean *= 10.0; } } /** * JIRA: MATH-282 */ public void testCumulativeProbabilitySpecial() throws Exception { PoissonDistribution dist = new PoissonDistributionImpl(1.0); dist.setMean(9120); checkProbability(dist, 9075); checkProbability(dist, 9102); dist.setMean(5058); checkProbability(dist, 5044); dist.setMean(6986); checkProbability(dist, 6950); } private void checkProbability(PoissonDistribution dist, double x) throws Exception { double p = dist.cumulativeProbability(x); assertFalse("NaN cumulative probability returned for mean = " + dist.getMean() + " x = " + x, Double.isNaN(p)); assertTrue("Zero cum probability returned for mean = " + dist.getMean() + " x = " + x, p > 0); } public void testLargeMeanInverseCumulativeProbability() throws Exception { PoissonDistribution dist = new PoissonDistributionImpl(1.0); double mean = 1.0; while (mean <= 100000.0) { // Extended test value: 1E7. Reduced to limit run time. dist.setMean(mean); double p = 0.1; double dp = p; while (p < .99) { double ret = Double.NaN; try { ret = dist.inverseCumulativeProbability(p); // Verify that returned value satisties definition assertTrue(p >= dist.cumulativeProbability(ret)); assertTrue(p < dist.cumulativeProbability(ret + 1)); } catch (MathException ex) { fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage()); } p += dp; } mean *= 10.0; } } public void testMomonts() { final double tol = 1e-9; PoissonDistributionImpl dist; dist = new PoissonDistributionImpl(1); assertEquals(dist.getNumericalVariance(), 1, tol); dist.setMean(11.23); assertEquals(dist.getNumericalVariance(), 11.23, tol); } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/IntegerDistributionAbstractTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/IntegerDistributionAbstractT100644 1750 1750 36265 11532241241 32676 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Abstract base class for {@link IntegerDistribution} tests. *

                  * To create a concrete test class for an integer distribution implementation, * implement makeDistribution() to return a distribution instance to use in * tests and each of the test data generation methods below. In each case, the * test points and test values arrays returned represent parallel arrays of * inputs and expected values for the distribution returned by makeDistribution(). *

                  * makeDensityTestPoints() -- arguments used to test probability density calculation * makeDensityTestValues() -- expected probability densities * makeCumulativeTestPoints() -- arguments used to test cumulative probabilities * makeCumulativeTestValues() -- expected cumulative probabilites * makeInverseCumulativeTestPoints() -- arguments used to test inverse cdf evaluation * makeInverseCumulativeTestValues() -- expected inverse cdf values *

                  * To implement additional test cases with different distribution instances and test data, * use the setXxx methods for the instance data in test cases and call the verifyXxx methods * to verify results. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class IntegerDistributionAbstractTest extends TestCase { //-------------------- Private test instance data ------------------------- /** Discrete distribution instance used to perform tests */ private IntegerDistribution distribution; /** Tolerance used in comparing expected and returned values */ private double tolerance = 1E-4; /** Arguments used to test probability density calculations */ private int[] densityTestPoints; /** Values used to test probability density calculations */ private double[] densityTestValues; /** Arguments used to test cumulative probability density calculations */ private int[] cumulativeTestPoints; /** Values used to test cumulative probability density calculations */ private double[] cumulativeTestValues; /** Arguments used to test inverse cumulative probability density calculations */ private double[] inverseCumulativeTestPoints; /** Values used to test inverse cumulative probability density calculations */ private int[] inverseCumulativeTestValues; //------------------------------------------------------------------------- /** * Constructor for IntegerDistributionAbstractTest. * @param name */ public IntegerDistributionAbstractTest(String name) { super(name); } //-------------------- Abstract methods ----------------------------------- /** Creates the default discrete distribution instance to use in tests. */ public abstract IntegerDistribution makeDistribution(); /** Creates the default probability density test input values */ public abstract int[] makeDensityTestPoints(); /** Creates the default probability density test expected values */ public abstract double[] makeDensityTestValues(); /** Creates the default cumulative probability density test input values */ public abstract int[] makeCumulativeTestPoints(); /** Creates the default cumulative probability density test expected values */ public abstract double[] makeCumulativeTestValues(); /** Creates the default inverse cumulative probability test input values */ public abstract double[] makeInverseCumulativeTestPoints(); /** Creates the default inverse cumulative probability density test expected values */ public abstract int[] makeInverseCumulativeTestValues(); //-------------------- Setup / tear down ---------------------------------- /** * Setup sets all test instance data to default values */ @Override protected void setUp() throws Exception { super.setUp(); distribution = makeDistribution(); densityTestPoints = makeDensityTestPoints(); densityTestValues = makeDensityTestValues(); cumulativeTestPoints = makeCumulativeTestPoints(); cumulativeTestValues = makeCumulativeTestValues(); inverseCumulativeTestPoints = makeInverseCumulativeTestPoints(); inverseCumulativeTestValues = makeInverseCumulativeTestValues(); } /** * Cleans up test instance data */ @Override protected void tearDown() throws Exception { super.tearDown(); distribution = null; densityTestPoints = null; densityTestValues = null; cumulativeTestPoints = null; cumulativeTestValues = null; inverseCumulativeTestPoints = null; inverseCumulativeTestValues = null; } //-------------------- Verification methods ------------------------------- /** * Verifies that probability density calculations match expected values * using current test instance data */ protected void verifyDensities() throws Exception { for (int i = 0; i < densityTestPoints.length; i++) { assertEquals("Incorrect density value returned for " + densityTestPoints[i], densityTestValues[i], distribution.probability(densityTestPoints[i]), tolerance); } } /** * Verifies that cumulative probability density calculations match expected values * using current test instance data */ protected void verifyCumulativeProbabilities() throws Exception { for (int i = 0; i < cumulativeTestPoints.length; i++) { assertEquals("Incorrect cumulative probability value returned for " + cumulativeTestPoints[i], cumulativeTestValues[i], distribution.cumulativeProbability(cumulativeTestPoints[i]), tolerance); } } /** * Verifies that inverse cumulative probability density calculations match expected values * using current test instance data */ protected void verifyInverseCumulativeProbabilities() throws Exception { for (int i = 0; i < inverseCumulativeTestPoints.length; i++) { assertEquals("Incorrect inverse cumulative probability value returned for " + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i], distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i])); } } //------------------------ Default test cases ----------------------------- /** * Verifies that probability density calculations match expected values * using default test instance data */ public void testDensities() throws Exception { verifyDensities(); } /** * Verifies that cumulative probability density calculations match expected values * using default test instance data */ public void testCumulativeProbabilities() throws Exception { verifyCumulativeProbabilities(); } /** * Verifies that floating point arguments are correctly handled by * cumulativeProbablility(-,-) * JIRA: MATH-184 */ public void testFloatingPointArguments() throws Exception { for (int i = 0; i < cumulativeTestPoints.length; i++) { double arg = cumulativeTestPoints[i]; assertEquals( "Incorrect cumulative probability value returned for " + cumulativeTestPoints[i], cumulativeTestValues[i], distribution.cumulativeProbability(arg), tolerance); if (i < cumulativeTestPoints.length - 1) { double arg2 = cumulativeTestPoints[i + 1]; assertEquals("Inconsistent probability for discrete range " + "[ " + arg + "," + arg2 + " ]", distribution.cumulativeProbability( cumulativeTestPoints[i], cumulativeTestPoints[i + 1]), distribution.cumulativeProbability(arg, arg2), tolerance); arg = arg - FastMath.random(); arg2 = arg2 + FastMath.random(); assertEquals("Inconsistent probability for discrete range " + "[ " + arg + "," + arg2 + " ]", distribution.cumulativeProbability( cumulativeTestPoints[i], cumulativeTestPoints[i + 1]), distribution.cumulativeProbability(arg, arg2), tolerance); } } int one = 1; int ten = 10; int two = 2; double oned = one; double twod = two; double tend = ten; assertEquals(distribution.cumulativeProbability(one, two), distribution.cumulativeProbability(oned, twod), tolerance); assertEquals(distribution.cumulativeProbability(one, two), distribution.cumulativeProbability(oned - tolerance, twod + 0.9), tolerance); assertEquals(distribution.cumulativeProbability(two, ten), distribution.cumulativeProbability(twod, tend), tolerance); assertEquals(distribution.cumulativeProbability(two, ten), distribution.cumulativeProbability(twod - tolerance, tend + 0.9), tolerance); } /** * Verifies that inverse cumulative probability density calculations match expected values * using default test instance data */ public void testInverseCumulativeProbabilities() throws Exception { verifyInverseCumulativeProbabilities(); } /** * Verifies that illegal arguments are correctly handled */ public void testIllegalArguments() throws Exception { try { distribution.cumulativeProbability(1, 0); fail("Expecting IllegalArgumentException for bad cumulativeProbability interval"); } catch (IllegalArgumentException ex) { // expected } try { distribution.inverseCumulativeProbability(-1); fail("Expecting IllegalArgumentException for p = -1"); } catch (IllegalArgumentException ex) { // expected } try { distribution.inverseCumulativeProbability(2); fail("Expecting IllegalArgumentException for p = 2"); } catch (IllegalArgumentException ex) { // expected } } /** * Test sampling */ public void testSampling() throws Exception { int[] densityPoints = makeDensityTestPoints(); double[] densityValues = makeDensityTestValues(); int sampleSize = 1000; int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues); AbstractIntegerDistribution distribution = (AbstractIntegerDistribution) makeDistribution(); double[] expectedCounts = new double[length]; long[] observedCounts = new long[length]; for (int i = 0; i < length; i++) { expectedCounts[i] = sampleSize * densityValues[i]; } distribution.reseedRandomGenerator(1000); // Use fixed seed int[] sample = distribution.sample(sampleSize); for (int i = 0; i < sampleSize; i++) { for (int j = 0; j < length; j++) { if (sample[i] == densityPoints[j]) { observedCounts[j]++; } } } TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001); } //------------------ Getters / Setters for test instance data ----------- /** * @return Returns the cumulativeTestPoints. */ protected int[] getCumulativeTestPoints() { return cumulativeTestPoints; } /** * @param cumulativeTestPoints The cumulativeTestPoints to set. */ protected void setCumulativeTestPoints(int[] cumulativeTestPoints) { this.cumulativeTestPoints = cumulativeTestPoints; } /** * @return Returns the cumulativeTestValues. */ protected double[] getCumulativeTestValues() { return cumulativeTestValues; } /** * @param cumulativeTestValues The cumulativeTestValues to set. */ protected void setCumulativeTestValues(double[] cumulativeTestValues) { this.cumulativeTestValues = cumulativeTestValues; } /** * @return Returns the densityTestPoints. */ protected int[] getDensityTestPoints() { return densityTestPoints; } /** * @param densityTestPoints The densityTestPoints to set. */ protected void setDensityTestPoints(int[] densityTestPoints) { this.densityTestPoints = densityTestPoints; } /** * @return Returns the densityTestValues. */ protected double[] getDensityTestValues() { return densityTestValues; } /** * @param densityTestValues The densityTestValues to set. */ protected void setDensityTestValues(double[] densityTestValues) { this.densityTestValues = densityTestValues; } /** * @return Returns the distribution. */ protected IntegerDistribution getDistribution() { return distribution; } /** * @param distribution The distribution to set. */ protected void setDistribution(IntegerDistribution distribution) { this.distribution = distribution; } /** * @return Returns the inverseCumulativeTestPoints. */ protected double[] getInverseCumulativeTestPoints() { return inverseCumulativeTestPoints; } /** * @param inverseCumulativeTestPoints The inverseCumulativeTestPoints to set. */ protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) { this.inverseCumulativeTestPoints = inverseCumulativeTestPoints; } /** * @return Returns the inverseCumulativeTestValues. */ protected int[] getInverseCumulativeTestValues() { return inverseCumulativeTestValues; } /** * @param inverseCumulativeTestValues The inverseCumulativeTestValues to set. */ protected void setInverseCumulativeTestValues(int[] inverseCumulativeTestValues) { this.inverseCumulativeTestValues = inverseCumulativeTestValues; } /** * @return Returns the tolerance. */ protected double getTolerance() { return tolerance; } /** * @param tolerance The tolerance to set. */ protected void setTolerance(double tolerance) { this.tolerance = tolerance; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/WeibullDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/WeibullDistributionTest.java100644 1750 1750 12732 11532241241 32645 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.FastMath; /** * Test cases for WeibullDistribution. * Extends ContinuousDistributionAbstractTest. See class javadoc for * ContinuousDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class WeibullDistributionTest extends ContinuousDistributionAbstractTest { /** * Constructor for CauchyDistributionTest. * @param arg0 */ public WeibullDistributionTest(String arg0) { super(arg0); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default continuous distribution instance to use in tests. */ @Override public WeibullDistribution makeDistribution() { return new WeibullDistributionImpl(1.2, 2.1); } /** Creates the default cumulative probability distribution test input values */ @Override public double[] makeCumulativeTestPoints() { // quantiles computed using R version 2.9.2 return new double[] {0.00664355180993, 0.0454328283309, 0.0981162737374, 0.176713524579, 0.321946865392, 10.5115496887, 7.4976304671, 6.23205600701, 5.23968436955, 4.2079028257}; } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999, 0.990, 0.975, 0.950, 0.900}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0.180535929306, 0.262801138133, 0.301905425199, 0.330899152971, 0.353441418887, 0.000788590320203, 0.00737060094841, 0.0177576041516, 0.0343043442574, 0.065664589369}; } //---------------------------- Additional test cases ------------------------- public void testInverseCumulativeProbabilityExtremes() throws Exception { setInverseCumulativeTestPoints(new double[] {0.0, 1.0}); setInverseCumulativeTestValues( new double[] {0.0, Double.POSITIVE_INFINITY}); verifyInverseCumulativeProbabilities(); } public void testAlpha() { WeibullDistribution distribution = (WeibullDistribution) getDistribution(); double expected = FastMath.random(); distribution.setShape(expected); assertEquals(expected, distribution.getShape(), 0.0); } public void testBeta() { WeibullDistribution distribution = (WeibullDistribution) getDistribution(); double expected = FastMath.random(); distribution.setScale(expected); assertEquals(expected, distribution.getScale(), 0.0); } public void testSetAlpha() { WeibullDistribution distribution = (WeibullDistribution) getDistribution(); try { distribution.setShape(0.0); fail("Can not have 0.0 alpha."); } catch (IllegalArgumentException ex) { // success } try { distribution.setShape(-1.0); fail("Can not have negative alpha."); } catch (IllegalArgumentException ex) { // success } } public void testSetBeta() { WeibullDistribution distribution = (WeibullDistribution) getDistribution(); try { distribution.setScale(0.0); fail("Can not have 0.0 beta."); } catch (IllegalArgumentException ex) { // success } try { distribution.setScale(-1.0); fail("Can not have negative beta."); } catch (IllegalArgumentException ex) { // success } } public void testMomonts() { final double tol = 1e-9; WeibullDistributionImpl dist; dist = new WeibullDistributionImpl(2.5, 3.5); // In R: 3.5*gamma(1+(1/2.5)) (or emperically: mean(rweibull(10000, 2.5, 3.5))) assertEquals(dist.getNumericalMean(), 3.5 * FastMath.exp(Gamma.logGamma(1 + (1 / 2.5))), tol); assertEquals(dist.getNumericalVariance(), (3.5 * 3.5) * FastMath.exp(Gamma.logGamma(1 + (2 / 2.5))) - (dist.getNumericalMean() * dist.getNumericalMean()), tol); dist.setShape(10.4); dist.setScale(2.222); assertEquals(dist.getNumericalMean(), 2.222 * FastMath.exp(Gamma.logGamma(1 + (1 / 10.4))), tol); assertEquals(dist.getNumericalVariance(), (2.222 * 2.222) * FastMath.exp(Gamma.logGamma(1 + (2 / 10.4))) - (dist.getNumericalMean() * dist.getNumericalMean()), tol); } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/BinomialDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/BinomialDistributionTest.jav100644 1750 1750 12152 11532241241 32627 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.distribution; /** * Test cases for BinomialDistribution. Extends IntegerDistributionAbstractTest. * See class javadoc for IntegerDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2009-09-05 12:36:48 -0500 (Sat, 05 Sep * 2009) $ */ public class BinomialDistributionTest extends IntegerDistributionAbstractTest { /** * Constructor for BinomialDistributionTest. * * @param name */ public BinomialDistributionTest(String name) { super(name); } // -------------- Implementations for abstract methods // ----------------------- /** Creates the default discrete distribution instance to use in tests. */ @Override public IntegerDistribution makeDistribution() { return new BinomialDistributionImpl(10, 0.70); } /** Creates the default probability density test input values */ @Override public int[] makeDensityTestPoints() { return new int[] { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] { 0d, 0.0000059049d, 0.000137781d, 0.0014467d, 0.00900169d, 0.0367569d, 0.102919d, 0.200121d, 0.266828d, 0.233474d, 0.121061d, 0.0282475d, 0d }; } /** Creates the default cumulative probability density test input values */ @Override public int[] makeCumulativeTestPoints() { return makeDensityTestPoints(); } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] { 0d, 0.0000d, 0.0001d, 0.0016d, 0.0106d, 0.0473d, 0.1503d, 0.3504d, 0.6172d, 0.8507d, 0.9718d, 1d, 1d }; } /** Creates the default inverse cumulative probability test input values */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] { 0, 0.001d, 0.010d, 0.025d, 0.050d, 0.100d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1 }; } /** * Creates the default inverse cumulative probability density test expected * values */ @Override public int[] makeInverseCumulativeTestValues() { return new int[] { -1, 1, 2, 3, 4, 4, 9, 9, 9, 8, 8, Integer.MAX_VALUE }; } // ----------------- Additional test cases --------------------------------- /** Test degenerate case p = 0 */ public void testDegenerate0() throws Exception { setDistribution(new BinomialDistributionImpl(5, 0.0d)); setCumulativeTestPoints(new int[] { -1, 0, 1, 5, 10 }); setCumulativeTestValues(new double[] { 0d, 1d, 1d, 1d, 1d }); setDensityTestPoints(new int[] { -1, 0, 1, 10, 11 }); setDensityTestValues(new double[] { 0d, 1d, 0d, 0d, 0d }); setInverseCumulativeTestPoints(new double[] { 0.1d, 0.5d }); setInverseCumulativeTestValues(new int[] { -1, -1 }); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } /** Test degenerate case p = 1 */ public void testDegenerate1() throws Exception { setDistribution(new BinomialDistributionImpl(5, 1.0d)); setCumulativeTestPoints(new int[] { -1, 0, 1, 2, 5, 10 }); setCumulativeTestValues(new double[] { 0d, 0d, 0d, 0d, 1d, 1d }); setDensityTestPoints(new int[] { -1, 0, 1, 2, 5, 10 }); setDensityTestValues(new double[] { 0d, 0d, 0d, 0d, 1d, 0d }); setInverseCumulativeTestPoints(new double[] { 0.1d, 0.5d }); setInverseCumulativeTestValues(new int[] { 4, 4 }); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } public void testMomonts() { final double tol = 1e-9; BinomialDistributionImpl dist; dist = new BinomialDistributionImpl(10, 0.5); assertEquals(dist.getNumericalMean(), 10d * 0.5d, tol); assertEquals(dist.getNumericalVariance(), 10d * 0.5d * 0.5d, tol); dist.setNumberOfTrials(30); dist.setProbabilityOfSuccess(0.3); assertEquals(dist.getNumericalMean(), 30d * 0.3d, tol); assertEquals(dist.getNumericalVariance(), 30d * 0.3d * (1d - 0.3d), tol); } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/HypergeometricDistributionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/HypergeometricDistributionTe100644 1750 1750 24663 11532241241 32747 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.TestUtils; /** * Test cases for HyperGeometriclDistribution. * Extends IntegerDistributionAbstractTest. See class javadoc for * IntegerDistributionAbstractTest for details. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class HypergeometricDistributionTest extends IntegerDistributionAbstractTest { /** * Constructor for ChiSquareDistributionTest. * @param name */ public HypergeometricDistributionTest(String name) { super(name); } //-------------- Implementations for abstract methods ----------------------- /** Creates the default discrete distribution instance to use in tests. */ @Override public IntegerDistribution makeDistribution() { return new HypergeometricDistributionImpl(10,5, 5); } /** Creates the default probability density test input values */ @Override public int[] makeDensityTestPoints() { return new int[] {-1, 0, 1, 2, 3, 4, 5, 10}; } /** Creates the default probability density test expected values */ @Override public double[] makeDensityTestValues() { return new double[] {0d, 0.003968d, 0.099206d, 0.396825d, 0.396825d, 0.099206d, 0.003968d, 0d}; } /** Creates the default cumulative probability density test input values */ @Override public int[] makeCumulativeTestPoints() { return makeDensityTestPoints(); } /** Creates the default cumulative probability density test expected values */ @Override public double[] makeCumulativeTestValues() { return new double[] {0d, .003968d, .103175d, .50000d, .896825d, .996032d, 1.00000d, 1d}; } /** Creates the default inverse cumulative probability test input values */ @Override public double[] makeInverseCumulativeTestPoints() { return new double[] {0d, 0.001d, 0.010d, 0.025d, 0.050d, 0.100d, 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1d}; } /** Creates the default inverse cumulative probability density test expected values */ @Override public int[] makeInverseCumulativeTestValues() { return new int[] {-1, -1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 5}; } //-------------------- Additional test cases ------------------------------ /** Verify that if there are no failures, mass is concentrated on sampleSize */ public void testDegenerateNoFailures() throws Exception { setDistribution(new HypergeometricDistributionImpl(5,5,3)); setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 }); setCumulativeTestValues(new double[] {0d, 0d, 0d, 1d, 1d}); setDensityTestPoints(new int[] {-1, 0, 1, 3, 10}); setDensityTestValues(new double[] {0d, 0d, 0d, 1d, 0d}); setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d}); setInverseCumulativeTestValues(new int[] {2, 2}); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } /** Verify that if there are no successes, mass is concentrated on 0 */ public void testDegenerateNoSuccesses() throws Exception { setDistribution(new HypergeometricDistributionImpl(5,0,3)); setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 }); setCumulativeTestValues(new double[] {0d, 1d, 1d, 1d, 1d}); setDensityTestPoints(new int[] {-1, 0, 1, 3, 10}); setDensityTestValues(new double[] {0d, 1d, 0d, 0d, 0d}); setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d}); setInverseCumulativeTestValues(new int[] {-1, -1}); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } /** Verify that if sampleSize = populationSize, mass is concentrated on numberOfSuccesses */ public void testDegenerateFullSample() throws Exception { setDistribution(new HypergeometricDistributionImpl(5,3,5)); setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 }); setCumulativeTestValues(new double[] {0d, 0d, 0d, 1d, 1d}); setDensityTestPoints(new int[] {-1, 0, 1, 3, 10}); setDensityTestValues(new double[] {0d, 0d, 0d, 1d, 0d}); setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d}); setInverseCumulativeTestValues(new int[] {2, 2}); verifyDensities(); verifyCumulativeProbabilities(); verifyInverseCumulativeProbabilities(); } public void testPopulationSize() { HypergeometricDistribution dist = new HypergeometricDistributionImpl(5,3,5); try { dist.setPopulationSize(-1); fail("negative population size. IllegalArgumentException expected"); } catch(IllegalArgumentException ex) { } dist.setPopulationSize(10); assertEquals(10, dist.getPopulationSize()); } public void testLargeValues() { int populationSize = 3456; int sampleSize = 789; int numberOfSucceses = 101; double[][] data = { {0.0, 2.75646034603961e-12, 2.75646034603961e-12, 1.0}, {1.0, 8.55705370142386e-11, 8.83269973602783e-11, 0.999999999997244}, {2.0, 1.31288129219665e-9, 1.40120828955693e-9, 0.999999999911673}, {3.0, 1.32724172984193e-8, 1.46736255879763e-8, 0.999999998598792}, {4.0, 9.94501711734089e-8, 1.14123796761385e-7, 0.999999985326375}, {5.0, 5.89080768883643e-7, 7.03204565645028e-7, 0.999999885876203}, {20.0, 0.0760051397707708, 0.27349758476299, 0.802507555007781}, {21.0, 0.087144222047629, 0.360641806810619, 0.72650241523701}, {22.0, 0.0940378846881819, 0.454679691498801, 0.639358193189381}, {23.0, 0.0956897500614809, 0.550369441560282, 0.545320308501199}, {24.0, 0.0919766921922999, 0.642346133752582, 0.449630558439718}, {25.0, 0.083641637261095, 0.725987771013677, 0.357653866247418}, {96.0, 5.93849188852098e-57, 1.0, 6.01900244560712e-57}, {97.0, 7.96593036832547e-59, 1.0, 8.05105570861321e-59}, {98.0, 8.44582921934367e-61, 1.0, 8.5125340287733e-61}, {99.0, 6.63604297068222e-63, 1.0, 6.670480942963e-63}, {100.0, 3.43501099007557e-65, 1.0, 3.4437972280786e-65}, {101.0, 8.78623800302957e-68, 1.0, 8.78623800302957e-68}, }; testHypergeometricDistributionProbabilities(populationSize, sampleSize, numberOfSucceses, data); } private void testHypergeometricDistributionProbabilities(int populationSize, int sampleSize, int numberOfSucceses, double[][] data) { HypergeometricDistributionImpl dist = new HypergeometricDistributionImpl(populationSize, numberOfSucceses, sampleSize); for (int i = 0; i < data.length; ++i) { int x = (int)data[i][0]; double pdf = data[i][1]; double actualPdf = dist.probability(x); TestUtils.assertRelativelyEquals("Expected equals for <"+x+"> pdf",pdf, actualPdf, 1.0e-9); double cdf = data[i][2]; double actualCdf = dist.cumulativeProbability(x); TestUtils.assertRelativelyEquals("Expected equals for <"+x+"> cdf",cdf, actualCdf, 1.0e-9); double cdf1 = data[i][3]; double actualCdf1 = dist.upperCumulativeProbability(x); TestUtils.assertRelativelyEquals("Expected equals for <"+x+"> cdf1",cdf1, actualCdf1, 1.0e-9); } } public void testMoreLargeValues() { int populationSize = 26896; int sampleSize = 895; int numberOfSucceses = 55; double[][] data = { {0.0, 0.155168304750504, 0.155168304750504, 1.0}, {1.0, 0.29437545000746, 0.449543754757964, 0.844831695249496}, {2.0, 0.273841321577003, 0.723385076334967, 0.550456245242036}, {3.0, 0.166488572570786, 0.889873648905753, 0.276614923665033}, {4.0, 0.0743969744713231, 0.964270623377076, 0.110126351094247}, {5.0, 0.0260542785784855, 0.990324901955562, 0.0357293766229237}, {20.0, 3.57101101678792e-16, 1.0, 3.78252101622096e-16}, {21.0, 2.00551638598312e-17, 1.0, 2.11509999433041e-17}, {22.0, 1.04317070180562e-18, 1.0, 1.09583608347287e-18}, {23.0, 5.03153504903308e-20, 1.0, 5.266538166725e-20}, {24.0, 2.2525984149695e-21, 1.0, 2.35003117691919e-21}, {25.0, 9.3677424515947e-23, 1.0, 9.74327619496943e-23}, {50.0, 9.83633962945521e-69, 1.0, 9.8677629437617e-69}, {51.0, 3.13448949497553e-71, 1.0, 3.14233143064882e-71}, {52.0, 7.82755221928122e-74, 1.0, 7.84193567329055e-74}, {53.0, 1.43662126065532e-76, 1.0, 1.43834540093295e-76}, {54.0, 1.72312692517348e-79, 1.0, 1.7241402776278e-79}, {55.0, 1.01335245432581e-82, 1.0, 1.01335245432581e-82}, }; testHypergeometricDistributionProbabilities(populationSize, sampleSize, numberOfSucceses, data); } public void testMomonts() { final double tol = 1e-9; HypergeometricDistributionImpl dist; dist = new HypergeometricDistributionImpl(1500, 40, 100); assertEquals(dist.getNumericalMean(), 40d * 100d / 1500d, tol); assertEquals(dist.getNumericalVariance(), ( 100d * 40d * (1500d - 100d) * (1500d - 40d) ) / ( (1500d * 1500d * 1499d) ), tol); dist.setPopulationSize(3000); dist.setNumberOfSuccesses(55); dist.setSampleSize(200); assertEquals(dist.getNumericalMean(), 55d * 200d / 3000d, tol); assertEquals(dist.getNumericalVariance(), ( 200d * 55d * (3000d - 200d) * (3000d - 55d) ) / ( (3000d * 3000d * 2999d) ), tol); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/distribution/BetaDistributionTest.java100644 1750 1750 37051 11532241241 32116 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import junit.framework.TestCase; import org.apache.commons.math.MathException; public class BetaDistributionTest extends TestCase { public void testCumulative() throws MathException { double[] x = new double[]{-0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1}; // all test data computed using R 2.5 checkCumulative(0.1, 0.1, x, new double[]{ 0.0000000000, 0.0000000000, 0.4063850939, 0.4397091902, 0.4628041861, 0.4821200456, 0.5000000000, 0.5178799544, 0.5371958139, 0.5602908098, 0.5936149061, 1.0000000000, 1.0000000000}); checkCumulative(0.1, 0.5, x, new double[]{ 0.0000000000, 0.0000000000, 0.7048336221, 0.7593042194, 0.7951765304, 0.8234948385, 0.8480017124, 0.8706034370, 0.8926585878, 0.9156406404, 0.9423662883, 1.0000000000, 1.0000000000}); checkCumulative(0.1, 1.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.7943282347, 0.8513399225, 0.8865681506, 0.9124435366, 0.9330329915, 0.9502002165, 0.9649610951, 0.9779327685, 0.9895192582, 1.0000000000, 1.0000000000}); checkCumulative(0.1, 2.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.8658177758, 0.9194471163, 0.9486279211, 0.9671901487, 0.9796846411, 0.9882082252, 0.9939099280, 0.9974914239, 0.9994144508, 1.0000000000, 1.0000000000}); checkCumulative(0.1, 4.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.9234991121, 0.9661958941, 0.9842285085, 0.9928444112, 0.9970040660, 0.9989112804, 0.9996895625, 0.9999440793, 0.9999967829, 1.0000000000, 1.0000000000}); checkCumulative(0.5, 0.1, x, new double[]{ 0.00000000000, 0.00000000000, 0.05763371168, 0.08435935962, 0.10734141216, 0.12939656302, 0.15199828760, 0.17650516146, 0.20482346963, 0.24069578055, 0.29516637795, 1.00000000000, 1.00000000000}); checkCumulative(0.5, 0.5, x, new double[]{ 0.0000000000, 0.0000000000, 0.2048327647, 0.2951672353, 0.3690101196, 0.4359057832, 0.5000000000, 0.5640942168, 0.6309898804, 0.7048327647, 0.7951672353, 1.0000000000, 1.0000000000}); checkCumulative(0.5, 1.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.3162277660, 0.4472135955, 0.5477225575, 0.6324555320, 0.7071067812, 0.7745966692, 0.8366600265, 0.8944271910, 0.9486832981, 1.0000000000, 1.0000000000}); checkCumulative(0.5, 2.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.4585302607, 0.6260990337, 0.7394254526, 0.8221921916, 0.8838834765, 0.9295160031, 0.9621590305, 0.9838699101, 0.9961174630, 1.0000000000, 1.0000000000}); checkCumulative(0.5, 4.0, x, new double[]{ 0.0000000000, 0.0000000000, 0.6266250826, 0.8049844719, 0.8987784842, 0.9502644369, 0.9777960959, 0.9914837366, 0.9974556254, 0.9995223859, 0.9999714889, 1.0000000000, 1.0000000000}); checkCumulative(1.0, 0.1, x, new double[]{ 0.00000000000, 0.00000000000, 0.01048074179, 0.02206723146, 0.03503890488, 0.04979978349, 0.06696700846, 0.08755646344, 0.11343184943, 0.14866007748, 0.20567176528, 1.00000000000, 1.00000000000}); checkCumulative(1.0, 0.5, x, new double[]{ 0.00000000000, 0.00000000000, 0.05131670195, 0.10557280900, 0.16333997347, 0.22540333076, 0.29289321881, 0.36754446797, 0.45227744249, 0.55278640450, 0.68377223398, 1.00000000000, 1.00000000000}); checkCumulative(1, 1, x, new double[]{ 0.0, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0}); checkCumulative(1, 2, x, new double[]{ 0.00, 0.00, 0.19, 0.36, 0.51, 0.64, 0.75, 0.84, 0.91, 0.96, 0.99, 1.00, 1.00}); checkCumulative(1, 4, x, new double[]{ 0.0000, 0.0000, 0.3439, 0.5904, 0.7599, 0.8704, 0.9375, 0.9744, 0.9919, 0.9984, 0.9999, 1.0000, 1.0000}); checkCumulative(2.0, 0.1, x, new double[]{ 0.0000000000000, 0.0000000000000, 0.0005855492117, 0.0025085760862, 0.0060900720266, 0.0117917748341, 0.0203153588864, 0.0328098512512, 0.0513720788952, 0.0805528836776, 0.1341822241505, 1.0000000000000, 1.0000000000000}); checkCumulative(2, 1, x, new double[]{ 0.00, 0.00, 0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1.00, 1.00}); checkCumulative(2.0, 0.5, x, new double[]{ 0.000000000000, 0.000000000000, 0.003882537047, 0.016130089900, 0.037840969486, 0.070483996910, 0.116116523517, 0.177807808356, 0.260574547368, 0.373900966300, 0.541469739276, 1.000000000000, 1.000000000000}); checkCumulative(2, 2, x, new double[]{ 0.000, 0.000, 0.028, 0.104, 0.216, 0.352, 0.500, 0.648, 0.784, 0.896, 0.972, 1.000, 1.000}); checkCumulative(2, 4, x, new double[]{ 0.00000, 0.00000, 0.08146, 0.26272, 0.47178, 0.66304, 0.81250, 0.91296, 0.96922, 0.99328, 0.99954, 1.00000, 1.00000}); checkCumulative(4.0, 0.1, x, new double[]{ 0.000000000e+00, 0.000000000e+00, 3.217128269e-06, 5.592070271e-05, 3.104375474e-04, 1.088719595e-03, 2.995933981e-03, 7.155588777e-03, 1.577149153e-02, 3.380410585e-02, 7.650088789e-02, 1.000000000e+00, 1.000000000e+00}); checkCumulative(4.0, 0.5, x, new double[]{ 0.000000000e+00, 0.000000000e+00, 2.851114863e-05, 4.776140576e-04, 2.544374616e-03, 8.516263371e-03, 2.220390414e-02, 4.973556312e-02, 1.012215158e-01, 1.950155281e-01, 3.733749174e-01, 1.000000000e+00, 1.000000000e+00}); checkCumulative(4, 1, x, new double[]{ 0.0000, 0.0000, 0.0001, 0.0016, 0.0081, 0.0256, 0.0625, 0.1296, 0.2401, 0.4096, 0.6561, 1.0000, 1.0000}); checkCumulative(4, 2, x, new double[]{ 0.00000, 0.00000, 0.00046, 0.00672, 0.03078, 0.08704, 0.18750, 0.33696, 0.52822, 0.73728, 0.91854, 1.00000, 1.00000}); checkCumulative(4, 4, x, new double[]{ 0.000000, 0.000000, 0.002728, 0.033344, 0.126036, 0.289792, 0.500000, 0.710208, 0.873964, 0.966656, 0.997272, 1.000000, 1.000000}); } private void checkCumulative(double alpha, double beta, double[] x, double[] cumes) throws MathException { BetaDistribution d = new BetaDistributionImpl(alpha, beta); for (int i = 0; i < x.length; i++) { assertEquals(cumes[i], d.cumulativeProbability(x[i]), 1e-8); } for (int i = 1; i < x.length - 1; i++) { assertEquals(x[i], d.inverseCumulativeProbability(cumes[i]), 1e-5); } } public void testDensity() throws MathException { double[] x = new double[]{1e-6, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; checkDensity(0.1, 0.1, x, new double[]{ 12741.2357380649, 0.4429889586665234, 2.639378715e-01, 2.066393611e-01, 1.832401831e-01, 1.766302780e-01, 1.832404579e-01, 2.066400696e-01, 2.639396531e-01, 4.429925026e-01}); checkDensity(0.1, 0.5, x, new double[]{ 2.218377102e+04, 7.394524202e-01, 4.203020268e-01, 3.119435533e-01, 2.600787829e-01, 2.330648626e-01, 2.211408259e-01, 2.222728708e-01, 2.414013907e-01, 3.070567405e-01}); checkDensity(0.1, 1.0, x, new double[]{ 2.511886432e+04, 7.943210858e-01, 4.256680458e-01, 2.955218303e-01, 2.281103709e-01, 1.866062624e-01, 1.583664652e-01, 1.378514078e-01, 1.222414585e-01, 1.099464743e-01}); checkDensity(0.1, 2.0, x, new double[]{ 2.763072312e+04, 7.863770012e-01, 3.745874120e-01, 2.275514842e-01, 1.505525939e-01, 1.026332391e-01, 6.968107049e-02, 4.549081293e-02, 2.689298641e-02, 1.209399123e-02}); checkDensity(0.1, 4.0, x, new double[]{ 2.997927462e+04, 6.911058917e-01, 2.601128486e-01, 1.209774010e-01, 5.880564714e-02, 2.783915474e-02, 1.209657335e-02, 4.442148268e-03, 1.167143939e-03, 1.312171805e-04}); checkDensity(0.5, 0.1, x, new double[]{ 88.3152184726, 0.3070542841, 0.2414007269, 0.2222727015, 0.2211409364, 0.2330652355, 0.2600795198, 0.3119449793, 0.4203052841, 0.7394649088}); checkDensity(0.5, 0.5, x, new double[]{ 318.3100453389, 1.0610282383, 0.7957732234, 0.6946084565, 0.6497470636, 0.6366197724, 0.6497476051, 0.6946097796, 0.7957762075, 1.0610376697}); checkDensity(0.5, 1.0, x, new double[]{ 500.0000000000, 1.5811309244, 1.1180311937, 0.9128694077, 0.7905684268, 0.7071060741, 0.6454966865, 0.5976138778, 0.5590166450, 0.5270459839}); checkDensity(0.5, 2.0, x, new double[]{ 749.99925000000, 2.134537420613655, 1.34163575536, 0.95851150881, 0.71151039830, 0.53032849490, 0.38729704363, 0.26892534859, 0.16770415497, 0.07905610701}); checkDensity(0.5, 4.0, x, new double[]{ 1.093746719e+03, 2.52142232809988, 1.252190241e+00, 6.849343920e-01, 3.735417140e-01, 1.933481570e-01, 9.036885833e-02, 3.529621669e-02, 9.782644546e-03, 1.152878503e-03}); checkDensity(1.0, 0.1, x, new double[]{ 0.1000000900, 0.1099466942, 0.1222417336, 0.1378517623, 0.1583669403, 0.1866069342, 0.2281113974, 0.2955236034, 0.4256718768, 0.7943353837}); checkDensity(1.0, 0.5, x, new double[]{ 0.5000002500, 0.5270465695, 0.5590173438, 0.5976147315, 0.6454977623, 0.7071074883, 0.7905704033, 0.9128724506, 1.1180367838, 1.5811467358}); checkDensity(1, 1, x, new double[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}); checkDensity(1, 2, x, new double[]{ 1.999998, 1.799998, 1.599998, 1.399998, 1.199998, 0.999998, 0.799998, 0.599998, 0.399998, 0.199998}); checkDensity(1, 4, x, new double[]{ 3.999988000012, 2.915990280011, 2.047992320010, 1.371994120008, 0.863995680007, 0.499997000006, 0.255998080005, 0.107998920004, 0.031999520002, 0.003999880001}); checkDensity(2.0, 0.1, x, new double[]{ 1.100000990e-07, 1.209425730e-02, 2.689331586e-02, 4.549123318e-02, 6.968162794e-02, 1.026340191e-01, 1.505537732e-01, 2.275534997e-01, 3.745917198e-01, 7.863929037e-01}); checkDensity(2.0, 0.5, x, new double[]{ 7.500003750e-07, 7.905777599e-02, 1.677060417e-01, 2.689275256e-01, 3.872996256e-01, 5.303316769e-01, 7.115145488e-01, 9.585174425e-01, 1.341645818e+00, 2.134537420613655}); checkDensity(2, 1, x, new double[]{ 0.000002, 0.200002, 0.400002, 0.600002, 0.800002, 1.000002, 1.200002, 1.400002, 1.600002, 1.800002}); checkDensity(2, 2, x, new double[]{ 5.9999940e-06, 5.4000480e-01, 9.6000360e-01, 1.2600024e+00, 1.4400012e+00, 1.5000000e+00, 1.4399988e+00, 1.2599976e+00, 9.5999640e-01, 5.3999520e-01}); checkDensity(2, 4, x, new double[]{ 0.00001999994, 1.45800971996, 2.04800255997, 2.05799803998, 1.72799567999, 1.24999500000, 0.76799552000, 0.37799676001, 0.12799824001, 0.01799948000}); checkDensity(4.0, 0.1, x, new double[]{ 1.193501074e-19, 1.312253162e-04, 1.167181580e-03, 4.442248535e-03, 1.209679109e-02, 2.783958903e-02, 5.880649983e-02, 1.209791638e-01, 2.601171405e-01, 6.911229392e-01}); checkDensity(4.0, 0.5, x, new double[]{ 1.093750547e-18, 1.152948959e-03, 9.782950259e-03, 3.529697305e-02, 9.037036449e-02, 1.933508639e-01, 3.735463833e-01, 6.849425461e-01, 1.252205894e+00, 2.52142232809988}); checkDensity(4, 1, x, new double[]{ 4.000000000e-18, 4.000120001e-03, 3.200048000e-02, 1.080010800e-01, 2.560019200e-01, 5.000030000e-01, 8.640043200e-01, 1.372005880e+00, 2.048007680e+00, 2.916009720e+00}); checkDensity(4, 2, x, new double[]{ 1.999998000e-17, 1.800052000e-02, 1.280017600e-01, 3.780032400e-01, 7.680044800e-01, 1.250005000e+00, 1.728004320e+00, 2.058001960e+00, 2.047997440e+00, 1.457990280e+00}); checkDensity(4, 4, x, new double[]{ 1.399995800e-16, 1.020627216e-01, 5.734464512e-01, 1.296547409e+00, 1.935364838e+00, 2.187500000e+00, 1.935355162e+00, 1.296532591e+00, 5.734335488e-01, 1.020572784e-01}); } private void checkDensity(double alpha, double beta, double[] x, double[] expected) throws MathException { BetaDistribution d = new BetaDistributionImpl(alpha, beta); for (int i = 0; i < x.length; i++) { assertEquals(String.format("density at x=%.1f for alpha=%.1f, beta=%.1f", x[i], alpha, beta), expected[i], d.density(x[i]), 1e-5); } } public void testMomonts() { final double tol = 1e-9; BetaDistributionImpl dist; dist = new BetaDistributionImpl(1, 1); assertEquals(dist.getNumericalMean(), 0.5, tol); assertEquals(dist.getNumericalVariance(), 1.0 / 12.0, tol); dist.setAlpha(2); dist.setBeta(5); assertEquals(dist.getNumericalMean(), 2.0 / 7.0, tol); assertEquals(dist.getNumericalVariance(), 10.0 / (49.0 * 8.0), tol); } } ././@LongLink100644 0 0 176 11532242443 10257 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInter100644 1750 1750 42150 11532241241 32567 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathException; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.analysis.BivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the bicubic function. * * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (Sun, 04 Oct 2009) $ */ public final class BicubicSplineInterpolatingFunctionTest { /** * Test preconditions. */ @Test public void testPreconditions() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[][] zval = new double[xval.length][yval.length]; @SuppressWarnings("unused") BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, zval, zval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { bcf = new BicubicSplineInterpolatingFunction(wxval, yval, zval, zval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -1, -1, 2.5}; try { bcf = new BicubicSplineInterpolatingFunction(xval, wyval, zval, zval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][] wzval = new double[xval.length][yval.length - 1]; try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, wzval, zval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, wzval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, wzval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, zval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length - 1][yval.length]; try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, wzval, zval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, wzval, zval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, wzval, zval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, zval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } Assert.assertNotNull(bcf); // Avoid Findbugs "dead store" warning } /** * Test for a plane. *

                  * z = 2 x - 3 y + 5 */ @Test public void testPlane() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; // Function values BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x - 3 * y + 5; } }; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } // Partial derivatives with respect to x double[][] dZdX = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdX[i][j] = 2; } } // Partial derivatives with respect to y double[][] dZdY = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdY[i][j] = -3; } } // Partial cross-derivatives double[][] dZdXdY = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdXdY[i][j] = 0; } } BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, dZdX, dZdY, dZdXdY); double x, y; double expected, result; x = 4; y = -3; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("Half-way between sample points (middle of the patch)", expected, result, 0.3); x = 3.5; y = -3.5; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("Half-way between sample points (border of the patch)", expected, result, 0.3); } /** * Test for a paraboloid. *

                  * z = 2 x2 - 3 y2 + 4 x y - 5 */ @Test public void testParaboloid() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; // Function values BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x * x - 3 * y * y + 4 * x * y - 5; } }; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } // Partial derivatives with respect to x double[][] dZdX = new double[xval.length][yval.length]; BivariateRealFunction dfdX = new BivariateRealFunction() { public double value(double x, double y) { return 4 * (x + y); } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdX[i][j] = dfdX.value(xval[i], yval[j]); } } // Partial derivatives with respect to y double[][] dZdY = new double[xval.length][yval.length]; BivariateRealFunction dfdY = new BivariateRealFunction() { public double value(double x, double y) { return 4 * x - 6 * y; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdY[i][j] = dfdY.value(xval[i], yval[j]); } } // Partial cross-derivatives double[][] dZdXdY = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { dZdXdY[i][j] = 4; } } BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, dZdX, dZdY, dZdXdY); double x, y; double expected, result; x = 4; y = -3; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("Half-way between sample points (middle of the patch)", expected, result, 2); x = 3.5; y = -3.5; expected = f.value(x, y); result = bcf.value(x, y); Assert.assertEquals("Half-way between sample points (border of the patch)", expected, result, 2); } /** * Test for partial derivatives of {@link BicubicSplineFunction}. *

                  * f(x, y) = ΣiΣj (i+1) (j+2) xi yj */ @Test public void testSplinePartialDerivatives() throws FunctionEvaluationException { final int N = 4; final double[] coeff = new double[16]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { coeff[i + N * j] = (i + 1) * (j + 2); } } final BicubicSplineFunction f = new BicubicSplineFunction(coeff); BivariateRealFunction derivative; final double x = 0.435; final double y = 0.776; final double tol = 1e-13; derivative = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double y2 = y * y; final double y3 = y2 * y; final double yFactor = 2 + 3 * y + 4 * y2 + 5 * y3; return yFactor * (2 + 6 * x + 12 * x2); } }; Assert.assertEquals("dFdX", derivative.value(x, y), f.partialDerivativeX().value(x, y), tol); derivative = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double x3 = x2 * x; final double y2 = y * y; final double xFactor = 1 + 2 * x + 3 * x2 + 4 * x3; return xFactor * (3 + 8 * y + 15 * y2); } }; Assert.assertEquals("dFdY", derivative.value(x, y), f.partialDerivativeY().value(x, y), tol); derivative = new BivariateRealFunction() { public double value(double x, double y) { final double y2 = y * y; final double y3 = y2 * y; final double yFactor = 2 + 3 * y + 4 * y2 + 5 * y3; return yFactor * (6 + 24 * x); } }; Assert.assertEquals("d2FdX2", derivative.value(x, y), f.partialDerivativeXX().value(x, y), tol); derivative = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double x3 = x2 * x; final double xFactor = 1 + 2 * x + 3 * x2 + 4 * x3; return xFactor * (8 + 30 * y); } }; Assert.assertEquals("d2FdY2", derivative.value(x, y), f.partialDerivativeYY().value(x, y), tol); derivative = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double y2 = y * y; final double yFactor = 3 + 8 * y + 15 * y2; return yFactor * (2 + 6 * x + 12 * x2); } }; Assert.assertEquals("d2FdXdY", derivative.value(x, y), f.partialDerivativeXY().value(x, y), tol); } /** * Test that the partial derivatives computed from a * {@link BicubicSplineInterpolatingFunction} match the input data. *

                  * f(x, y) = 5 * - 3 x + 2 y * - x y + 2 x2 - 3 y2 * + 4 x2 y - x y2 - 3 x3 + y3 */ @Test public void testMatchingPartialDerivatives() throws MathException { final int sz = 21; double[] val = new double[sz]; // Coordinate values final double delta = 1d / (sz - 1); for (int i = 0; i < sz; i++) { val[i] = i * delta; } // Function values BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double x3 = x2 * x; final double y2 = y * y; final double y3 = y2 * y; return 5 - 3 * x + 2 * y - x * y + 2 * x2 - 3 * y2 + 4 * x2 * y - x * y2 - 3 * x3 + y3; } }; double[][] fval = new double[sz][sz]; for (int i = 0; i < sz; i++) { for (int j = 0; j < sz; j++) { fval[i][j] = f.value(val[i], val[j]); } } // Partial derivatives with respect to x double[][] dFdX = new double[sz][sz]; BivariateRealFunction dfdX = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double y2 = y * y; return - 3 - y + 4 * x + 8 * x * y - y2 - 9 * x2; } }; for (int i = 0; i < sz; i++) { for (int j = 0; j < sz; j++) { dFdX[i][j] = dfdX.value(val[i], val[j]); } } // Partial derivatives with respect to y double[][] dFdY = new double[sz][sz]; BivariateRealFunction dfdY = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double y2 = y * y; return 2 - x - 6 * y + 4 * x2 - 2 * x * y + 3 * y2; } }; for (int i = 0; i < sz; i++) { for (int j = 0; j < sz; j++) { dFdY[i][j] = dfdY.value(val[i], val[j]); } } // Partial cross-derivatives double[][] d2FdXdY = new double[sz][sz]; BivariateRealFunction d2fdXdY = new BivariateRealFunction() { public double value(double x, double y) { return -1 + 8 * x - 2 * y; } }; for (int i = 0; i < sz; i++) { for (int j = 0; j < sz; j++) { d2FdXdY[i][j] = d2fdXdY.value(val[i], val[j]); } } BicubicSplineInterpolatingFunction bcf = new BicubicSplineInterpolatingFunction(val, val, fval, dFdX, dFdY, d2FdXdY); double x, y; double expected, result; final double tol = 1e-12; for (int i = 0; i < sz; i++) { x = val[i]; for (int j = 0; j < sz; j++) { y = val[j]; expected = dfdX.value(x, y); result = bcf.partialDerivativeX(x, y); Assert.assertEquals(x + " " + y + " dFdX", expected, result, tol); expected = dfdY.value(x, y); result = bcf.partialDerivativeY(x, y); Assert.assertEquals(x + " " + y + " dFdY", expected, result, tol); expected = d2fdXdY.value(x, y); result = bcf.partialDerivativeXY(x, y); Assert.assertEquals(x + " " + y + " d2FdXdY", expected, result, tol); } } } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolato100644 1750 1750 12642 11532241241 32674 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.Expm1Function; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Neville interpolator. *

                  * The error of polynomial interpolation is * f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n! * where f^(n) is the n-th derivative of the approximated function and * zeta is some point in the interval determined by x[] and z. *

                  * Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound * it and use the absolute value upper bound for estimates. For reference, * see Introduction to Numerical Analysis, ISBN 038795452X, chapter 2. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ */ public final class NevilleInterpolatorTest extends TestCase { /** * Test of interpolator for the sine function. *

                  * |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI] */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealInterpolator interpolator = new NevilleInterpolator(); double x[], y[], z, expected, result, tolerance; // 6 interpolating points on interval [0, 2*PI] int n = 6; double min = 0.0, max = 2 * FastMath.PI; x = new double[n]; y = new double[n]; for (int i = 0; i < n; i++) { x[i] = min + i * (max - min) / n; y[i] = f.value(x[i]); } double derivativebound = 1.0; UnivariateRealFunction p = interpolator.interpolate(x, y); z = FastMath.PI / 4; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = FastMath.PI * 1.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); } /** * Test of interpolator for the exponential function. *

                  * |expm1^(n)(zeta)| <= e, zeta in [-1, 1] */ public void testExpm1Function() throws MathException { UnivariateRealFunction f = new Expm1Function(); UnivariateRealInterpolator interpolator = new NevilleInterpolator(); double x[], y[], z, expected, result, tolerance; // 5 interpolating points on interval [-1, 1] int n = 5; double min = -1.0, max = 1.0; x = new double[n]; y = new double[n]; for (int i = 0; i < n; i++) { x[i] = min + i * (max - min) / n; y[i] = f.value(x[i]); } double derivativebound = FastMath.E; UnivariateRealFunction p = interpolator.interpolate(x, y); z = 0.0; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = 0.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = -0.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); } /** * Test of parameters for the interpolator. */ public void testParameters() throws Exception { UnivariateRealInterpolator interpolator = new NevilleInterpolator(); try { // bad abscissas array double x[] = { 1.0, 2.0, 2.0, 4.0 }; double y[] = { 0.0, 4.0, 4.0, 2.5 }; UnivariateRealFunction p = interpolator.interpolate(x, y); p.value(0.0); fail("Expecting FunctionEvaluationException - bad abscissas array"); } catch (FunctionEvaluationException ex) { // expected } } /** * Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n! */ protected double partialerror(double x[], double z) throws IllegalArgumentException { if (x.length < 1) { throw new IllegalArgumentException ("Interpolation array cannot be empty."); } double out = 1; for (int i = 0; i < x.length; i++) { out *= (z - x[i]) / (i + 1); } return out; } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator100644 1750 1750 14127 11532241241 32672 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.NonMonotonousSequenceException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.junit.Assert; import org.junit.Test; /** * Test the LinearInterpolator. */ public class LinearInterpolatorTest { /** error tolerance for spline interpolator value at knot points */ protected double knotTolerance = 1E-12; /** error tolerance for interpolating polynomial coefficients */ protected double coefficientTolerance = 1E-6; /** error tolerance for interpolated values */ protected double interpolationTolerance = 1E-12; @Test public void testInterpolateLinearDegenerateTwoSegment() throws Exception { double x[] = { 0.0, 0.5, 1.0 }; double y[] = { 0.0, 0.5, 1.0 }; UnivariateRealInterpolator i = new LinearInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 1d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); // Check interpolation Assert.assertEquals(0.0,f.value(0.0), interpolationTolerance); Assert.assertEquals(0.4,f.value(0.4), interpolationTolerance); Assert.assertEquals(1.0,f.value(1.0), interpolationTolerance); } @Test public void testInterpolateLinearDegenerateThreeSegment() throws Exception { double x[] = { 0.0, 0.5, 1.0, 1.5 }; double y[] = { 0.0, 0.5, 1.0, 1.5 }; UnivariateRealInterpolator i = new LinearInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 1d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); target = new double[]{y[2], 1d}; TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance); // Check interpolation Assert.assertEquals(0,f.value(0), interpolationTolerance); Assert.assertEquals(1.4,f.value(1.4), interpolationTolerance); Assert.assertEquals(1.5,f.value(1.5), interpolationTolerance); } @Test public void testInterpolateLinear() throws Exception { double x[] = { 0.0, 0.5, 1.0 }; double y[] = { 0.0, 0.5, 0.0 }; UnivariateRealInterpolator i = new LinearInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], -1d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); } @Test public void testIllegalArguments() throws MathException { // Data set arrays of different size. UnivariateRealInterpolator i = new LinearInterpolator(); try { double xval[] = { 0.0, 1.0 }; double yval[] = { 0.0, 1.0, 2.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect data set array with different sizes."); } catch (DimensionMismatchException iae) { // Expected. } // X values not sorted. try { double xval[] = { 0.0, 1.0, 0.5 }; double yval[] = { 0.0, 1.0, 2.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect unsorted arguments."); } catch (NonMonotonousSequenceException iae) { // Expected. } // Not enough data to interpolate. try { double xval[] = { 0.0 }; double yval[] = { 0.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect unsorted arguments."); } catch (NumberIsTooSmallException iae) { // Expected. } } /** * verifies that f(x[i]) = y[i] for i = 0..n-1 where n is common length. */ protected void verifyInterpolation(UnivariateRealFunction f, double x[], double y[]) throws Exception{ for (int i = 0; i < x.length; i++) { Assert.assertEquals(f.value(x[i]), y[i], knotTolerance); } } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/LoessInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/LoessInterpolatorT100644 1750 1750 22060 11532241241 32664 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; /** * Test of the LoessInterpolator class. */ public class LoessInterpolatorTest { @Test public void testOnOnePoint() throws MathException { double[] xval = {0.5}; double[] yval = {0.7}; double[] res = new LoessInterpolator().smooth(xval, yval); Assert.assertEquals(1, res.length); Assert.assertEquals(0.7, res[0], 0.0); } @Test public void testOnTwoPoints() throws MathException { double[] xval = {0.5, 0.6}; double[] yval = {0.7, 0.8}; double[] res = new LoessInterpolator().smooth(xval, yval); Assert.assertEquals(2, res.length); Assert.assertEquals(0.7, res[0], 0.0); Assert.assertEquals(0.8, res[1], 0.0); } @Test public void testOnStraightLine() throws MathException { double[] xval = {1,2,3,4,5}; double[] yval = {2,4,6,8,10}; LoessInterpolator li = new LoessInterpolator(0.6, 2, 1e-12); double[] res = li.smooth(xval, yval); Assert.assertEquals(5, res.length); for(int i = 0; i < 5; ++i) { Assert.assertEquals(yval[i], res[i], 1e-8); } } @Test public void testOnDistortedSine() throws MathException { int numPoints = 100; double[] xval = new double[numPoints]; double[] yval = new double[numPoints]; double xnoise = 0.1; double ynoise = 0.2; generateSineData(xval, yval, xnoise, ynoise); LoessInterpolator li = new LoessInterpolator(0.3, 4, 1e-12); double[] res = li.smooth(xval, yval); // Check that the resulting curve differs from // the "real" sine less than the jittered one double noisyResidualSum = 0; double fitResidualSum = 0; for(int i = 0; i < numPoints; ++i) { double expected = FastMath.sin(xval[i]); double noisy = yval[i]; double fit = res[i]; noisyResidualSum += FastMath.pow(noisy - expected, 2); fitResidualSum += FastMath.pow(fit - expected, 2); } Assert.assertTrue(fitResidualSum < noisyResidualSum); } @Test public void testIncreasingBandwidthIncreasesSmoothness() throws MathException { int numPoints = 100; double[] xval = new double[numPoints]; double[] yval = new double[numPoints]; double xnoise = 0.1; double ynoise = 0.1; generateSineData(xval, yval, xnoise, ynoise); // Check that variance decreases as bandwidth increases double[] bandwidths = {0.1, 0.5, 1.0}; double[] variances = new double[bandwidths.length]; for (int i = 0; i < bandwidths.length; i++) { double bw = bandwidths[i]; LoessInterpolator li = new LoessInterpolator(bw, 4, 1e-12); double[] res = li.smooth(xval, yval); for (int j = 1; j < res.length; ++j) { variances[i] += FastMath.pow(res[j] - res[j-1], 2); } } for(int i = 1; i < variances.length; ++i) { Assert.assertTrue(variances[i] < variances[i-1]); } } @Test public void testIncreasingRobustnessItersIncreasesSmoothnessWithOutliers() throws MathException { int numPoints = 100; double[] xval = new double[numPoints]; double[] yval = new double[numPoints]; double xnoise = 0.1; double ynoise = 0.1; generateSineData(xval, yval, xnoise, ynoise); // Introduce a couple of outliers yval[numPoints/3] *= 100; yval[2 * numPoints/3] *= -100; // Check that variance decreases as the number of robustness // iterations increases double[] variances = new double[4]; for (int i = 0; i < 4; i++) { LoessInterpolator li = new LoessInterpolator(0.3, i, 1e-12); double[] res = li.smooth(xval, yval); for (int j = 1; j < res.length; ++j) { variances[i] += FastMath.abs(res[j] - res[j-1]); } } for(int i = 1; i < variances.length; ++i) { Assert.assertTrue(variances[i] < variances[i-1]); } } @Test(expected=MathException.class) public void testUnequalSizeArguments() throws MathException { new LoessInterpolator().smooth(new double[] {1,2,3}, new double[] {1,2,3,4}); } @Test(expected=MathException.class) public void testEmptyData() throws MathException { new LoessInterpolator().smooth(new double[] {}, new double[] {}); } @Test(expected=MathException.class) public void testNonStrictlyIncreasing1() throws MathException { new LoessInterpolator().smooth(new double[] {4,3,1,2}, new double[] {3,4,5,6}); } @Test(expected=MathException.class) public void testNonStrictlyIncreasing2() throws MathException { new LoessInterpolator().smooth(new double[] {1,2,2,3}, new double[] {3,4,5,6}); } @Test(expected=MathException.class) public void testNotAllFiniteReal1() throws MathException { new LoessInterpolator().smooth(new double[] {1,2,Double.NaN}, new double[] {3,4,5}); } @Test(expected=MathException.class) public void testNotAllFiniteReal2() throws MathException { new LoessInterpolator().smooth(new double[] {1,2,Double.POSITIVE_INFINITY}, new double[] {3,4,5}); } @Test(expected=MathException.class) public void testNotAllFiniteReal3() throws MathException { new LoessInterpolator().smooth(new double[] {1,2,Double.NEGATIVE_INFINITY}, new double[] {3,4,5}); } @Test(expected=MathException.class) public void testNotAllFiniteReal4() throws MathException { new LoessInterpolator().smooth(new double[] {3,4,5}, new double[] {1,2,Double.NaN}); } @Test(expected=MathException.class) public void testNotAllFiniteReal5() throws MathException { new LoessInterpolator().smooth(new double[] {3,4,5}, new double[] {1,2,Double.POSITIVE_INFINITY}); } @Test(expected=MathException.class) public void testNotAllFiniteReal6() throws MathException { new LoessInterpolator().smooth(new double[] {3,4,5}, new double[] {1,2,Double.NEGATIVE_INFINITY}); } @Test(expected=MathException.class) public void testInsufficientBandwidth() throws MathException { LoessInterpolator li = new LoessInterpolator(0.1, 3, 1e-12); li.smooth(new double[] {1,2,3,4,5,6,7,8,9,10,11,12}, new double[] {1,2,3,4,5,6,7,8,9,10,11,12}); } @Test(expected=MathException.class) public void testCompletelyIncorrectBandwidth1() throws MathException { new LoessInterpolator(-0.2, 3, 1e-12); } @Test(expected=MathException.class) public void testCompletelyIncorrectBandwidth2() throws MathException { new LoessInterpolator(1.1, 3, 1e-12); } @Test public void testMath296withoutWeights() throws MathException { double[] xval = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0}; double[] yval = { 0.47, 0.48, 0.55, 0.56, -0.08, -0.04, -0.07, -0.07, -0.56, -0.46, -0.56, -0.52, -3.03, -3.08, -3.09, -3.04, 3.54, 3.46, 3.36, 3.35}; // Output from R, rounded to .001 double[] yref = { 0.461, 0.499, 0.541, 0.308, 0.175, -0.042, -0.072, -0.196, -0.311, -0.446, -0.557, -1.497, -2.133, -3.08, -3.09, -0.621, 0.982, 3.449, 3.389, 3.336 }; LoessInterpolator li = new LoessInterpolator(0.3, 4, 1e-12); double[] res = li.smooth(xval, yval); Assert.assertEquals(xval.length, res.length); for(int i = 0; i < res.length; ++i) { Assert.assertEquals(yref[i], res[i], 0.02); } } private void generateSineData(double[] xval, double[] yval, double xnoise, double ynoise) { double dx = 2 * FastMath.PI / xval.length; double x = 0; for(int i = 0; i < xval.length; ++i) { xval[i] = x; yval[i] = FastMath.sin(x) + (2 * FastMath.random() - 1) * ynoise; x += dx * (1 + (2 * FastMath.random() - 1) * xnoise); } } } ././@LongLink100644 0 0 210 11532242443 10244 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomialBicubicSplineInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomia100644 1750 1750 14734 11532241241 32720 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.analysis.BivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the smoothing bicubic interpolator. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class SmoothingPolynomialBicubicSplineInterpolatorTest { /** * Test preconditions. */ @Test public void testPreconditions() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[][] zval = new double[xval.length][yval.length]; BivariateRealGridInterpolator interpolator = new SmoothingPolynomialBicubicSplineInterpolator(0); @SuppressWarnings("unused") BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { p = interpolator.interpolate(wxval, yval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -3, -1, -1}; try { p = interpolator.interpolate(xval, wyval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][] wzval = new double[xval.length][yval.length + 1]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length - 1][yval.length]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length][yval.length - 1]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } } /** * Test of interpolator for a plane. *

                  * z = 2 x - 3 y + 5 */ @Test public void testPlane() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x - 3 * y + 5 + ((int) (FastMath.abs(5 * x + 3 * y)) % 2 == 0 ? 1 : -1); } }; BivariateRealGridInterpolator interpolator = new SmoothingPolynomialBicubicSplineInterpolator(1); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 4; y = -3; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 2); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 2); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 2); } /** * Test of interpolator for a paraboloid. *

                  * z = 2 x2 - 3 y2 + 4 x y - 5 */ @Test public void testParaboloid() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x * x - 3 * y * y + 4 * x * y - 5 + ((int) (FastMath.abs(5 * x + 3 * y)) % 2 == 0 ? 1 : -1); } }; BivariateRealGridInterpolator interpolator = new SmoothingPolynomialBicubicSplineInterpolator(4); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -2, -1, 0.5, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 5; y = 0.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 2); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 2); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 2); } } ././@LongLink100644 0 0 166 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInte100644 1750 1750 17011 11532241241 32607 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.analysis.TrivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the tricubic interpolator. * * @version $Revision$ $Date$ */ public final class TricubicSplineInterpolatorTest { /** * Test preconditions. */ @Test public void testPreconditions() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5}; double[][][] fval = new double[xval.length][yval.length][zval.length]; TrivariateRealGridInterpolator interpolator = new TricubicSplineInterpolator(); @SuppressWarnings("unused") TrivariateRealFunction p = interpolator.interpolate(xval, yval, zval, fval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { p = interpolator.interpolate(wxval, yval, zval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -3, -1, -1}; try { p = interpolator.interpolate(xval, wyval, zval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wzval = new double[] {-12, -8, -5.5, -3, -4, 2.5}; try { p = interpolator.interpolate(xval, yval, wzval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][][] wfval = new double[xval.length][yval.length + 1][zval.length]; try { p = interpolator.interpolate(xval, yval, zval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wfval = new double[xval.length - 1][yval.length][zval.length]; try { p = interpolator.interpolate(xval, yval, zval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wfval = new double[xval.length][yval.length][zval.length - 1]; try { p = interpolator.interpolate(xval, yval, zval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } } /** * Test of interpolator for a plane. *

                  * f(x, y, z) = 2 x - 3 y - z + 5 */ @Test public void testPlane() throws MathException { TrivariateRealFunction f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return 2 * x - 3 * y - z + 5; } }; TrivariateRealGridInterpolator interpolator = new TricubicSplineInterpolator(); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5}; double[][][] fval = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { fval[i][j][k] = f.value(xval[i], yval[j], zval[k]); } } } TrivariateRealFunction p = interpolator.interpolate(xval, yval, zval, fval); double x, y, z; double expected, result; x = 4; y = -3; z = 0; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; z = -4.25; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.3); x = 3.5; y = -3.5; z = -10; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.3); } /** * Test of interpolator for a sine wave. *

                  *

                  * f(x, y, z) = a cos [ω z - ky x - ky y] *

                  * with A = 0.2, ω = 0.5, kx = 2, ky = 1. */ @Test public void testWave() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 4}; final double a = 0.2; final double omega = 0.5; final double kx = 2; final double ky = 1; // Function values TrivariateRealFunction f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.cos(omega * z - kx * x - ky * y); } }; double[][][] fval = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { fval[i][j][k] = f.value(xval[i], yval[j], zval[k]); } } } TrivariateRealGridInterpolator interpolator = new TricubicSplineInterpolator(); TrivariateRealFunction p = interpolator.interpolate(xval, yval, zval, fval); double x, y, z; double expected, result; x = 4; y = -3; z = 0; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("On sample point", expected, result, 1e-12); x = 4.5; y = -1.5; z = -4.25; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("Half-way between sample points (middle of the patch)", expected, result, 0.1); x = 3.5; y = -3.5; z = -10; expected = f.value(x, y, z); result = p.value(x, y, z); Assert.assertEquals("Half-way between sample points (border of the patch)", expected, result, 0.1); } } ././@LongLink100644 0 0 176 11532242443 10257 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSp100644 1750 1750 14530 11532241241 32606 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.analysis.BivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the bicubic interpolator. * * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ * @deprecated To be removed in math 3.0 (when the class for which it is a test will also be removed). */ @Deprecated public final class SmoothingBicubicSplineInterpolatorTest { /** * Test preconditions. */ @Test public void testPreconditions() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[][] zval = new double[xval.length][yval.length]; BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator(); @SuppressWarnings("unused") BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { p = interpolator.interpolate(wxval, yval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -3, -1, -1}; try { p = interpolator.interpolate(xval, wyval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][] wzval = new double[xval.length][yval.length + 1]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length - 1][yval.length]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length][yval.length - 1]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } } /** * Test of interpolator for a plane. *

                  * z = 2 x - 3 y + 5 */ @Test public void testPlane() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x - 3 * y + 5; } }; BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator(); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 4; y = -3; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.3); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.3); } /** * Test of interpolator for a paraboloid. *

                  * z = 2 x2 - 3 y2 + 4 x y - 5 */ @Test public void testParaboloid() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x * x - 3 * y * y + 4 * x * y - 5; } }; BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator(); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -2, -1, 0.5, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 5; y = 0.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-13); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.2); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.2); } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInter100644 1750 1750 13645 11532241241 32576 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.analysis.BivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the bicubic interpolator. * * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (Sun, 04 Oct 2009) $ */ public final class BicubicSplineInterpolatorTest { /** * Test preconditions. */ @Test public void testPreconditions() throws MathException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[][] zval = new double[xval.length][yval.length]; BivariateRealGridInterpolator interpolator = new BicubicSplineInterpolator(); @SuppressWarnings("unused") BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { p = interpolator.interpolate(wxval, yval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -3, -1, -1}; try { p = interpolator.interpolate(xval, wyval, zval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][] wzval = new double[xval.length][yval.length + 1]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wzval = new double[xval.length - 1][yval.length]; try { p = interpolator.interpolate(xval, yval, wzval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } } /** * Test of interpolator for a plane. *

                  * z = 2 x - 3 y + 5 */ @Test public void testPlane() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x - 3 * y + 5; } }; BivariateRealGridInterpolator interpolator = new BicubicSplineInterpolator(); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 4; y = -3; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.3); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.3); } /** * Test of interpolator for a paraboloid. *

                  * z = 2 x2 - 3 y2 + 4 x y - 5 */ @Test public void testParaboloid() throws MathException { BivariateRealFunction f = new BivariateRealFunction() { public double value(double x, double y) { return 2 * x * x - 3 * y * y + 4 * x * y - 5; } }; BivariateRealGridInterpolator interpolator = new BicubicSplineInterpolator(); double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -2, -1, 0.5, 2.5}; double[][] zval = new double[xval.length][yval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { zval[i][j] = f.value(xval[i], yval[j]); } } BivariateRealFunction p = interpolator.interpolate(xval, yval, zval); double x, y; double expected, result; x = 5; y = 0.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("On sample point", expected, result, 1e-13); x = 4.5; y = -1.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.2); x = 3.5; y = -3.5; expected = f.value(x, y); result = p.value(x, y); Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.2); } } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpo100644 1750 1750 10751 11532241241 32675 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; /** * Testcase for the "microsphere projection" interpolator. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class MicrosphereInterpolatorTest { /** * Test of interpolator for a plane. *

                  * y = 2 x1 - 3 x2 + 5 */ @Test public void testLinearFunction2D() throws MathException { MultivariateRealFunction f = new MultivariateRealFunction() { public double value(double[] x) { if (x.length != 2) { throw new IllegalArgumentException(); } return 2 * x[0] - 3 * x[1] + 5; } }; MultivariateRealInterpolator interpolator = new MicrosphereInterpolator(); // Interpolating points in [-1, 1][-1, 1] by steps of 1. final int n = 9; final int dim = 2; double[][] x = new double[n][dim]; double[] y = new double[n]; int index = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { x[index][0] = i; x[index][1] = j; y[index] = f.value(x[index]); ++index; } } MultivariateRealFunction p = interpolator.interpolate(x, y); double[] c = new double[dim]; double expected, result; c[0] = 0; c[1] = 0; expected = f.value(c); result = p.value(c); Assert.assertEquals("On sample point", expected, result, FastMath.ulp(1d)); c[0] = 0 + 1e-5; c[1] = 1 - 1e-5; expected = f.value(c); result = p.value(c); Assert.assertEquals("1e-5 away from sample point", expected, result, 1e-4); } /** * Test of interpolator for a quadratic function. *

                  * y = 2 x12 - 3 x22 * + 4 x1 x2 - 5 */ @Test public void testParaboloid2D() throws MathException { MultivariateRealFunction f = new MultivariateRealFunction() { public double value(double[] x) { if (x.length != 2) { throw new IllegalArgumentException(); } return 2 * x[0] * x[0] - 3 * x[1] * x[1] + 4 * x[0] * x[1] - 5; } }; MultivariateRealInterpolator interpolator = new MicrosphereInterpolator(); // Interpolating points in [-10, 10][-10, 10] by steps of 2. final int n = 121; final int dim = 2; double[][] x = new double[n][dim]; double[] y = new double[n]; int index = 0; for (int i = -10; i <= 10; i += 2) { for (int j = -10; j <= 10; j += 2) { x[index][0] = i; x[index][1] = j; y[index] = f.value(x[index]); ++index; } } MultivariateRealFunction p = interpolator.interpolate(x, y); double[] c = new double[dim]; double expected, result; c[0] = 0; c[1] = 0; expected = f.value(c); result = p.value(c); Assert.assertEquals("On sample point", expected, result, FastMath.ulp(1d)); c[0] = 2 + 1e-5; c[1] = 2 - 1e-5; expected = f.value(c); result = p.value(c); Assert.assertEquals("1e-5 away from sample point", expected, result, 1e-3); } } ././@LongLink100644 0 0 177 11532242443 10260 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatingFunctionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInte100644 1750 1750 57747 11532241241 32633 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.analysis.TrivariateRealFunction; import org.junit.Assert; import org.junit.Test; /** * Testcase for the bicubic function. * * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (Sun, 04 Oct 2009) $ */ public final class TricubicSplineInterpolatingFunctionTest { /** * Test preconditions. */ @Test public void testPreconditions() { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5}; double[][][] fval = new double[xval.length][yval.length][zval.length]; @SuppressWarnings("unused") TrivariateRealFunction tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, fval, fval); double[] wxval = new double[] {3, 2, 5, 6.5}; try { tcf = new TricubicSplineInterpolatingFunction(wxval, yval, zval, fval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wyval = new double[] {-4, -1, -1, 2.5}; try { tcf = new TricubicSplineInterpolatingFunction(xval, wyval, zval, fval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[] wzval = new double[] {-12, -8, -9, -3, 0, 2.5}; try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, wzval, fval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } double[][][] wfval = new double[xval.length - 1][yval.length - 1][zval.length]; try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, wfval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, wfval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, wfval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, wfval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, wfval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, wfval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, wfval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, fval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wfval = new double[xval.length][yval.length - 1][zval.length]; try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, wfval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, wfval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, wfval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, wfval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, wfval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, wfval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, wfval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, fval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } wfval = new double[xval.length][yval.length][zval.length - 1]; try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, wfval, fval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, wfval, fval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, wfval, fval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, wfval, fval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, wfval, fval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, wfval, fval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, wfval, fval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } try { tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, fval, fval, fval, fval, fval, fval, wfval); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException e) { // Expected } Assert.assertNotNull(tcf); // Avoid Findbugs "dead store" warning } /** * Test for a plane. *

                  * f(x, y, z) = 2 x - 3 y - 4 z + 5 *

                  */ @Test public void testPlane() throws FunctionEvaluationException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5}; // Function values TrivariateRealFunction f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return 2 * x - 3 * y - 4 * z + 5; } }; double[][][] fval = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { fval[i][j][k] = f.value(xval[i], yval[j], zval[k]); } } } // Partial derivatives with respect to x double[][][] dFdX = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdX[i][j][k] = 2; } } } // Partial derivatives with respect to y double[][][] dFdY = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdY[i][j][k] = -3; } } } // Partial derivatives with respect to z double[][][] dFdZ = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdZ[i][j][k] = -4; } } } // Partial cross-derivatives double[][][] d2FdXdY = new double[xval.length][yval.length][zval.length]; double[][][] d2FdXdZ = new double[xval.length][yval.length][zval.length]; double[][][] d2FdYdZ = new double[xval.length][yval.length][zval.length]; double[][][] d3FdXdYdZ = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { d2FdXdY[i][j][k] = 0; d2FdXdZ[i][j][k] = 0; d2FdYdZ[i][j][k] = 0; d3FdXdYdZ[i][j][k] = 0; } } } TrivariateRealFunction tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, dFdX, dFdY, dFdZ, d2FdXdY, d2FdXdZ, d2FdYdZ, d3FdXdYdZ); double x, y, z; double expected, result; x = 4; y = -3; z = 0; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("On sample point", expected, result, 1e-15); x = 4.5; y = -1.5; z = -4.25; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("Half-way between sample points (middle of the patch)", expected, result, 0.3); x = 3.5; y = -3.5; z = -10; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("Half-way between sample points (border of the patch)", expected, result, 0.3); } /** * Sine wave. *

                  * f(x, y, z) = a cos [ω z - ky x - ky y] *

                  * with A = 0.2, ω = 0.5, kx = 2, ky = 1. */ @Test public void testWave() throws FunctionEvaluationException { double[] xval = new double[] {3, 4, 5, 6.5}; double[] yval = new double[] {-4, -3, -1, 2, 2.5}; double[] zval = new double[] {-12, -8, -5.5, -3, 0, 4}; final double a = 0.2; final double omega = 0.5; final double kx = 2; final double ky = 1; // Function values TrivariateRealFunction f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.cos(omega * z - kx * x - ky * y); } }; double[][][] fval = new double[xval.length][yval.length][zval.length]; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { fval[i][j][k] = f.value(xval[i], yval[j], zval[k]); } } } // Partial derivatives with respect to x double[][][] dFdX = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction dFdX_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.sin(omega * z - kx * x - ky * y) * kx; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdX[i][j][k] = dFdX_f.value(xval[i], yval[j], zval[k]); } } } // Partial derivatives with respect to y double[][][] dFdY = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction dFdY_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.sin(omega * z - kx * x - ky * y) * ky; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdY[i][j][k] = dFdY_f.value(xval[i], yval[j], zval[k]); } } } // Partial derivatives with respect to z double[][][] dFdZ = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction dFdZ_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return -a * FastMath.sin(omega * z - kx * x - ky * y) * omega; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { dFdZ[i][j][k] = dFdZ_f.value(xval[i], yval[j], zval[k]); } } } // Partial second derivatives w.r.t. (x, y) double[][][] d2FdXdY = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction d2FdXdY_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return -a * FastMath.cos(omega * z - kx * x - ky * y) * kx * ky; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { d2FdXdY[i][j][k] = d2FdXdY_f.value(xval[i], yval[j], zval[k]); } } } // Partial second derivatives w.r.t. (x, z) double[][][] d2FdXdZ = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction d2FdXdZ_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.cos(omega * z - kx * x - ky * y) * kx * omega; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { d2FdXdZ[i][j][k] = d2FdXdZ_f.value(xval[i], yval[j], zval[k]); } } } // Partial second derivatives w.r.t. (y, z) double[][][] d2FdYdZ = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction d2FdYdZ_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.cos(omega * z - kx * x - ky * y) * ky * omega; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { d2FdYdZ[i][j][k] = d2FdYdZ_f.value(xval[i], yval[j], zval[k]); } } } // Partial third derivatives double[][][] d3FdXdYdZ = new double[xval.length][yval.length][zval.length]; TrivariateRealFunction d3FdXdYdZ_f = new TrivariateRealFunction() { public double value(double x, double y, double z) { return a * FastMath.sin(omega * z - kx * x - ky * y) * kx * ky * omega; } }; for (int i = 0; i < xval.length; i++) { for (int j = 0; j < yval.length; j++) { for (int k = 0; k < zval.length; k++) { d3FdXdYdZ[i][j][k] = d3FdXdYdZ_f.value(xval[i], yval[j], zval[k]); } } } TrivariateRealFunction tcf = new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, dFdX, dFdY, dFdZ, d2FdXdY, d2FdXdZ, d2FdYdZ, d3FdXdYdZ); double x, y, z; double expected, result; x = 4; y = -3; z = 0; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("On sample point", expected, result, 1e-14); x = 4.5; y = -1.5; z = -4.25; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("Half-way between sample points (middle of the patch)", expected, result, 0.1); x = 3.5; y = -3.5; z = -10; expected = f.value(x, y, z); result = tcf.value(x, y, z); Assert.assertEquals("Half-way between sample points (border of the patch)", expected, result, 0.1); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator100644 1750 1750 24122 11532241241 32706 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.NonMonotonousSequenceException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.TestUtils; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.junit.Assert; import org.junit.Test; /** * Test the SplineInterpolator. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class SplineInterpolatorTest { /** error tolerance for spline interpolator value at knot points */ protected double knotTolerance = 1E-12; /** error tolerance for interpolating polynomial coefficients */ protected double coefficientTolerance = 1E-6; /** error tolerance for interpolated values -- high value is from sin test */ protected double interpolationTolerance = 1E-2; @Test public void testInterpolateLinearDegenerateTwoSegment() throws Exception { double x[] = { 0.0, 0.5, 1.0 }; double y[] = { 0.0, 0.5, 1.0 }; UnivariateRealInterpolator i = new SplineInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); verifyConsistency((PolynomialSplineFunction) f, x); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 1d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); // Check interpolation Assert.assertEquals(0.0,f.value(0.0), interpolationTolerance); Assert.assertEquals(0.4,f.value(0.4), interpolationTolerance); Assert.assertEquals(1.0,f.value(1.0), interpolationTolerance); } @Test public void testInterpolateLinearDegenerateThreeSegment() throws Exception { double x[] = { 0.0, 0.5, 1.0, 1.5 }; double y[] = { 0.0, 0.5, 1.0, 1.5 }; UnivariateRealInterpolator i = new SplineInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 1d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); target = new double[]{y[2], 1d}; TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance); // Check interpolation Assert.assertEquals(0,f.value(0), interpolationTolerance); Assert.assertEquals(1.4,f.value(1.4), interpolationTolerance); Assert.assertEquals(1.5,f.value(1.5), interpolationTolerance); } @Test public void testInterpolateLinear() throws Exception { double x[] = { 0.0, 0.5, 1.0 }; double y[] = { 0.0, 0.5, 0.0 }; UnivariateRealInterpolator i = new SplineInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); verifyConsistency((PolynomialSplineFunction) f, x); // Verify coefficients using analytical values PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1.5d, 0d, -2d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 0d, -3d, 2d}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); } @Test public void testInterpolateSin() throws Exception { double x[] = { 0.0, FastMath.PI / 6d, FastMath.PI / 2d, 5d * FastMath.PI / 6d, FastMath.PI, 7d * FastMath.PI / 6d, 3d * FastMath.PI / 2d, 11d * FastMath.PI / 6d, 2.d * FastMath.PI }; double y[] = { 0d, 0.5d, 1d, 0.5d, 0d, -0.5d, -1d, -0.5d, 0d }; UnivariateRealInterpolator i = new SplineInterpolator(); UnivariateRealFunction f = i.interpolate(x, y); verifyInterpolation(f, x, y); verifyConsistency((PolynomialSplineFunction) f, x); /* Check coefficients against values computed using R (version 1.8.1, Red Hat Linux 9) * * To replicate in R: * x[1] <- 0 * x[2] <- pi / 6, etc, same for y[] (could use y <- scan() for y values) * g <- splinefun(x, y, "natural") * splinecoef <- eval(expression(z), envir = environment(g)) * print(splinecoef) */ PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); double target[] = {y[0], 1.002676d, 0d, -0.17415829d}; TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); target = new double[]{y[1], 8.594367e-01, -2.735672e-01, -0.08707914}; TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); target = new double[]{y[2], 1.471804e-17,-5.471344e-01, 0.08707914}; TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance); target = new double[]{y[3], -8.594367e-01, -2.735672e-01, 0.17415829}; TestUtils.assertEquals(polynomials[3].getCoefficients(), target, coefficientTolerance); target = new double[]{y[4], -1.002676, 6.548562e-17, 0.17415829}; TestUtils.assertEquals(polynomials[4].getCoefficients(), target, coefficientTolerance); target = new double[]{y[5], -8.594367e-01, 2.735672e-01, 0.08707914}; TestUtils.assertEquals(polynomials[5].getCoefficients(), target, coefficientTolerance); target = new double[]{y[6], 3.466465e-16, 5.471344e-01, -0.08707914}; TestUtils.assertEquals(polynomials[6].getCoefficients(), target, coefficientTolerance); target = new double[]{y[7], 8.594367e-01, 2.735672e-01, -0.17415829}; TestUtils.assertEquals(polynomials[7].getCoefficients(), target, coefficientTolerance); //Check interpolation Assert.assertEquals(FastMath.sqrt(2d) / 2d,f.value(FastMath.PI/4d),interpolationTolerance); Assert.assertEquals(FastMath.sqrt(2d) / 2d,f.value(3d*FastMath.PI/4d),interpolationTolerance); } @Test public void testIllegalArguments() throws MathException { // Data set arrays of different size. UnivariateRealInterpolator i = new SplineInterpolator(); try { double xval[] = { 0.0, 1.0 }; double yval[] = { 0.0, 1.0, 2.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect data set array with different sizes."); } catch (DimensionMismatchException iae) { // Expected. } // X values not sorted. try { double xval[] = { 0.0, 1.0, 0.5 }; double yval[] = { 0.0, 1.0, 2.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect unsorted arguments."); } catch (NonMonotonousSequenceException iae) { // Expected. } // Not enough data to interpolate. try { double xval[] = { 0.0, 1.0 }; double yval[] = { 0.0, 1.0 }; i.interpolate(xval, yval); Assert.fail("Failed to detect unsorted arguments."); } catch (NumberIsTooSmallException iae) { // Expected. } } /** * verifies that f(x[i]) = y[i] for i = 0..n-1 where n is common length. */ protected void verifyInterpolation(UnivariateRealFunction f, double x[], double y[]) throws Exception{ for (int i = 0; i < x.length; i++) { Assert.assertEquals(f.value(x[i]), y[i], knotTolerance); } } /** * Verifies that interpolating polynomials satisfy consistency requirement: * adjacent polynomials must agree through two derivatives at knot points */ protected void verifyConsistency(PolynomialSplineFunction f, double x[]) throws Exception { PolynomialFunction polynomials[] = f.getPolynomials(); for (int i = 1; i < x.length - 2; i++) { // evaluate polynomials and derivatives at x[i + 1] Assert.assertEquals(polynomials[i].value(x[i +1] - x[i]), polynomials[i + 1].value(0), 0.1); Assert.assertEquals(polynomials[i].derivative().value(x[i +1] - x[i]), polynomials[i + 1].derivative().value(0), 0.5); Assert.assertEquals(polynomials[i].polynomialDerivative().derivative().value(x[i +1] - x[i]), polynomials[i + 1].polynomialDerivative().derivative().value(0), 0.5); } } } ././@LongLink100644 0 0 171 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolatorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceI100644 1750 1750 12573 11532241241 32514 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.Expm1Function; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Divided Difference interpolator. *

                  * The error of polynomial interpolation is * f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n! * where f^(n) is the n-th derivative of the approximated function and * zeta is some point in the interval determined by x[] and z. *

                  * Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound * it and use the absolute value upper bound for estimates. For reference, * see Introduction to Numerical Analysis, ISBN 038795452X, chapter 2. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class DividedDifferenceInterpolatorTest extends TestCase { /** * Test of interpolator for the sine function. *

                  * |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI] */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator(); double x[], y[], z, expected, result, tolerance; // 6 interpolating points on interval [0, 2*PI] int n = 6; double min = 0.0, max = 2 * FastMath.PI; x = new double[n]; y = new double[n]; for (int i = 0; i < n; i++) { x[i] = min + i * (max - min) / n; y[i] = f.value(x[i]); } double derivativebound = 1.0; UnivariateRealFunction p = interpolator.interpolate(x, y); z = FastMath.PI / 4; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = FastMath.PI * 1.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); } /** * Test of interpolator for the exponential function. *

                  * |expm1^(n)(zeta)| <= e, zeta in [-1, 1] */ public void testExpm1Function() throws MathException { UnivariateRealFunction f = new Expm1Function(); UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator(); double x[], y[], z, expected, result, tolerance; // 5 interpolating points on interval [-1, 1] int n = 5; double min = -1.0, max = 1.0; x = new double[n]; y = new double[n]; for (int i = 0; i < n; i++) { x[i] = min + i * (max - min) / n; y[i] = f.value(x[i]); } double derivativebound = FastMath.E; UnivariateRealFunction p = interpolator.interpolate(x, y); z = 0.0; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = 0.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); z = -0.5; expected = f.value(z); result = p.value(z); tolerance = FastMath.abs(derivativebound * partialerror(x, z)); assertEquals(expected, result, tolerance); } /** * Test of parameters for the interpolator. */ public void testParameters() throws Exception { UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator(); try { // bad abscissas array double x[] = { 1.0, 2.0, 2.0, 4.0 }; double y[] = { 0.0, 4.0, 4.0, 2.5 }; UnivariateRealFunction p = interpolator.interpolate(x, y); p.value(0.0); fail("Expecting MathException - bad abscissas array"); } catch (MathException ex) { // expected } } /** * Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n! */ protected double partialerror(double x[], double z) throws IllegalArgumentException { if (x.length < 1) { throw new IllegalArgumentException ("Interpolation array cannot be empty."); } double out = 1; for (int i = 0; i < x.length; i++) { out *= (z - x[i]) / (i + 1); } return out; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/Expm1Function.java100644 1750 1750 2570 11532241241 27565 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.util.FastMath; /** * Auxiliary class for testing purposes. * * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class Expm1Function implements DifferentiableUnivariateRealFunction { public double value(double x) { return FastMath.expm1(x); } public UnivariateRealFunction derivative() { return new UnivariateRealFunction() { public double value(double x) { return FastMath.exp(x); } }; } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtilsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtil100644 1750 1750 11561 11532241241 32626 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import junit.framework.TestCase; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; /** * @version $Revision: 1003901 $ $Date: 2010-10-03 00:11:04 +0200 (dim. 03 oct. 2010) $ */ public class UnivariateRealSolverUtilsTest extends TestCase { protected UnivariateRealFunction sin = new SinFunction(); public void testSolveNull() throws MathException { try { UnivariateRealSolverUtils.solve(null, 0.0, 4.0); fail(); } catch(IllegalArgumentException ex){ // success } } public void testSolveBadEndpoints() throws MathException { try { // bad endpoints UnivariateRealSolverUtils.solve(sin, -0.1, 4.0, 4.0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testSolveBadAccuracy() throws MathException { try { // bad accuracy UnivariateRealSolverUtils.solve(sin, 0.0, 4.0, 0.0); // fail("Expecting IllegalArgumentException"); // TODO needs rework since convergence behaviour was changed } catch (IllegalArgumentException ex) { // expected } } public void testSolveSin() throws MathException { double x = UnivariateRealSolverUtils.solve(sin, 1.0, 4.0); assertEquals(FastMath.PI, x, 1.0e-4); } public void testSolveAccuracyNull() throws MathException { try { double accuracy = 1.0e-6; UnivariateRealSolverUtils.solve(null, 0.0, 4.0, accuracy); fail(); } catch(IllegalArgumentException ex){ // success } } public void testSolveAccuracySin() throws MathException { double accuracy = 1.0e-6; double x = UnivariateRealSolverUtils.solve(sin, 1.0, 4.0, accuracy); assertEquals(FastMath.PI, x, accuracy); } public void testSolveNoRoot() throws MathException { try { UnivariateRealSolverUtils.solve(sin, 1.0, 1.5); fail("Expecting IllegalArgumentException "); } catch (IllegalArgumentException ex) { // expected } } public void testBracketSin() throws MathException { double[] result = UnivariateRealSolverUtils.bracket(sin, 0.0, -2.0, 2.0); assertTrue(sin.value(result[0]) < 0); assertTrue(sin.value(result[1]) > 0); } public void testBracketEndpointRoot() throws MathException { double[] result = UnivariateRealSolverUtils.bracket(sin, 1.5, 0, 2.0); assertEquals(0.0, sin.value(result[0]), 1.0e-15); assertTrue(sin.value(result[1]) > 0); } public void testNullFunction() throws MathException { try { // null function UnivariateRealSolverUtils.bracket(null, 1.5, 0, 2.0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testBadInitial() throws MathException { try { // initial not between endpoints UnivariateRealSolverUtils.bracket(sin, 2.5, 0, 2.0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testBadEndpoints() throws MathException { try { // endpoints not valid UnivariateRealSolverUtils.bracket(sin, 1.5, 2.0, 1.0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testBadMaximumIterations() throws MathException { try { // bad maximum iterations UnivariateRealSolverUtils.bracket(sin, 1.5, 0, 2.0, 0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImplTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFact100644 1750 1750 4557 11532241241 32555 0ustarlucluc 0 0 /* * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class UnivariateRealSolverFactoryImplTest extends TestCase { /** solver factory */ private UnivariateRealSolverFactory factory; /** * @throws java.lang.Exception * @see junit.framework.TestCase#tearDown() */ @Override protected void setUp() throws Exception { super.setUp(); factory = new UnivariateRealSolverFactoryImpl(); } /** * @throws java.lang.Exception * @see junit.framework.TestCase#tearDown() */ @Override protected void tearDown() throws Exception { factory = null; super.tearDown(); } public void testNewBisectionSolverValid() { UnivariateRealSolver solver = factory.newBisectionSolver(); assertNotNull(solver); assertTrue(solver instanceof BisectionSolver); } public void testNewNewtonSolverValid() { UnivariateRealSolver solver = factory.newNewtonSolver(); assertNotNull(solver); assertTrue(solver instanceof NewtonSolver); } public void testNewBrentSolverValid() { UnivariateRealSolver solver = factory.newBrentSolver(); assertNotNull(solver); assertTrue(solver instanceof BrentSolver); } public void testNewSecantSolverValid() { UnivariateRealSolver solver = factory.newSecantSolver(); assertNotNull(solver); assertTrue(solver instanceof SecantSolver); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/RiddersSolverTest.java100644 1750 1750 14435 11532241241 32234 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.Expm1Function; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Ridders solver. *

                  * Ridders' method converges superlinearly, more specific, its rate of * convergence is sqrt(2). Test runs show that for a default absolute * accuracy of 1E-6, it generally takes less than 5 iterations for close * initial bracket and 5 to 10 iterations for distant initial bracket * to converge. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class RiddersSolverTest extends TestCase { /** * Test the deprecated APIs. */ @Deprecated public void testDeprecated() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new RiddersSolver(f); double min, max, expected, result, tolerance; min = 3.0; max = 4.0; expected = FastMath.PI; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(min, max); assertEquals(expected, result, tolerance); min = -1.0; max = 1.5; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the sine function. */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new RiddersSolver(); double min, max, expected, result, tolerance; min = 3.0; max = 4.0; expected = FastMath.PI; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -1.0; max = 1.5; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quintic function. */ public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new RiddersSolver(); double min, max, expected, result, tolerance; min = -0.4; max = 0.2; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = 0.75; max = 1.5; expected = 1.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -0.9; max = -0.2; expected = -0.5; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the exponential function. */ public void testExpm1Function() throws MathException { UnivariateRealFunction f = new Expm1Function(); UnivariateRealSolver solver = new RiddersSolver(); double min, max, expected, result, tolerance; min = -1.0; max = 2.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -20.0; max = 10.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -50.0; max = 100.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of parameters for the solver. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new RiddersSolver(); try { // bad interval solver.solve(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // no bracketing solver.solve(f, 2, 3); fail("Expecting IllegalArgumentException - no bracketing"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/BisectionSolverTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/BisectionSolverTest.java100644 1750 1750 15040 11532241241 32550 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class BisectionSolverTest extends TestCase { @Deprecated public void testDeprecated() throws MathException { UnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new BisectionSolver(f); result = solver.solve(3, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); result = solver.solve(1, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); } public void testSinZero() throws MathException { UnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new BisectionSolver(); result = solver.solve(f, 3, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); result = solver.solve(f, 1, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); } public void testQuinticZero() throws MathException { UnivariateRealFunction f = new QuinticFunction(); double result; UnivariateRealSolver solver = new BisectionSolver(); result = solver.solve(f, -0.2, 0.2); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, -0.1, 0.3); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, -0.3, 0.45); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.3, 0.7); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.2, 0.6); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.05, 0.95); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 1.25); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.8, 1.2); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 1.75); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.55, 1.45); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 5); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, solver.getResult(), 0); assertTrue(solver.getIterationCount() > 0); } public void testMath369() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new BisectionSolver(); assertEquals(FastMath.PI, solver.solve(f, 3.0, 3.2, 3.1), solver.getAbsoluteAccuracy()); } /** * */ public void testSetFunctionValueAccuracy(){ double expected = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); solver.setFunctionValueAccuracy(expected); assertEquals(expected, solver.getFunctionValueAccuracy(), 1.0e-2); } /** * */ public void testResetFunctionValueAccuracy(){ double newValue = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); double oldValue = solver.getFunctionValueAccuracy(); solver.setFunctionValueAccuracy(newValue); solver.resetFunctionValueAccuracy(); assertEquals(oldValue, solver.getFunctionValueAccuracy(), 1.0e-2); } /** * */ public void testSetAbsoluteAccuracy(){ double expected = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); solver.setAbsoluteAccuracy(expected); assertEquals(expected, solver.getAbsoluteAccuracy(), 1.0e-2); } /** * */ public void testResetAbsoluteAccuracy(){ double newValue = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); double oldValue = solver.getAbsoluteAccuracy(); solver.setAbsoluteAccuracy(newValue); solver.resetAbsoluteAccuracy(); assertEquals(oldValue, solver.getAbsoluteAccuracy(), 1.0e-2); } /** * */ public void testSetMaximalIterationCount(){ int expected = 100; UnivariateRealSolver solver = new BisectionSolver(); solver.setMaximalIterationCount(expected); assertEquals(expected, solver.getMaximalIterationCount()); } /** * */ public void testResetMaximalIterationCount(){ int newValue = 10000; UnivariateRealSolver solver = new BisectionSolver(); int oldValue = solver.getMaximalIterationCount(); solver.setMaximalIterationCount(newValue); solver.resetMaximalIterationCount(); assertEquals(oldValue, solver.getMaximalIterationCount()); } /** * */ public void testSetRelativeAccuracy(){ double expected = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); solver.setRelativeAccuracy(expected); assertEquals(expected, solver.getRelativeAccuracy(), 1.0e-2); } /** * */ public void testResetRelativeAccuracy(){ double newValue = 1.0e-2; UnivariateRealSolver solver = new BisectionSolver(); double oldValue = solver.getRelativeAccuracy(); solver.setRelativeAccuracy(newValue); solver.resetRelativeAccuracy(); assertEquals(oldValue, solver.getRelativeAccuracy(), 1.0e-2); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/NewtonSolverTest.java100644 1750 1750 7460 11532241241 32072 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class NewtonSolverTest extends TestCase { @Deprecated public void testDeprecated() throws MathException { DifferentiableUnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new NewtonSolver(f); result = solver.solve(3, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); result = solver.solve(1, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); assertEquals(result, solver.getResult(), 0); assertTrue(solver.getIterationCount() > 0); } /** * */ public void testSinZero() throws MathException { DifferentiableUnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new NewtonSolver(); result = solver.solve(f, 3, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); result = solver.solve(f, 1, 4); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); assertEquals(result, solver.getResult(), 0); assertTrue(solver.getIterationCount() > 0); } /** * */ public void testQuinticZero() throws MathException { DifferentiableUnivariateRealFunction f = new QuinticFunction(); double result; UnivariateRealSolver solver = new NewtonSolver(); result = solver.solve(f, -0.2, 0.2); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, -0.1, 0.3); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, -0.3, 0.45); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.3, 0.7); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.2, 0.6); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.05, 0.95); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 1.25); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.8, 1.2); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 1.75); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.55, 1.45); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); result = solver.solve(f, 0.85, 5); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/MullerSolverTest.java100644 1750 1750 25577 11532241241 32111 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.Expm1Function; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Muller solver. *

                  * Muller's method converges almost quadratically near roots, but it can * be very slow in regions far away from zeros. Test runs show that for * reasonably good initial values, for a default absolute accuracy of 1E-6, * it generally takes 5 to 10 iterations for the solver to converge. *

                  * Tests for the exponential function illustrate the situations where * Muller solver performs poorly. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class MullerSolverTest extends TestCase { /** * Test deprecated APIs. */ @Deprecated public void testDeprecated() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new MullerSolver(f); double min, max, expected, result, tolerance; min = 3.0; max = 4.0; expected = FastMath.PI; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(min, max); assertEquals(expected, result, tolerance); min = -1.0; max = 1.5; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(min, max); assertEquals(expected, result, tolerance); } /** * Test deprecated APIs. */ @Deprecated public void testDeprecated2() throws MathException { UnivariateRealFunction f = new QuinticFunction(); MullerSolver solver = new MullerSolver(f); double min, max, expected, result, tolerance; min = -0.4; max = 0.2; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(min, max); assertEquals(expected, result, tolerance); min = 0.75; max = 1.5; expected = 1.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(min, max); assertEquals(expected, result, tolerance); min = -0.9; max = -0.2; expected = -0.5; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the sine function. */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = 3.0; max = 4.0; expected = FastMath.PI; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -1.0; max = 1.5; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the sine function using solve2(). */ public void testSinFunction2() throws MathException { UnivariateRealFunction f = new SinFunction(); MullerSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = 3.0; max = 4.0; expected = FastMath.PI; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); min = -1.0; max = 1.5; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quintic function. */ public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = -0.4; max = 0.2; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = 0.75; max = 1.5; expected = 1.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -0.9; max = -0.2; expected = -0.5; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quintic function using solve2(). */ public void testQuinticFunction2() throws MathException { UnivariateRealFunction f = new QuinticFunction(); MullerSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = -0.4; max = 0.2; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); min = 0.75; max = 1.5; expected = 1.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); min = -0.9; max = -0.2; expected = -0.5; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the exponential function. *

                  * It takes 10 to 15 iterations for the last two tests to converge. * In fact, if not for the bisection alternative, the solver would * exceed the default maximal iteration of 100. */ public void testExpm1Function() throws MathException { UnivariateRealFunction f = new Expm1Function(); UnivariateRealSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = -1.0; max = 2.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -20.0; max = 10.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -50.0; max = 100.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the exponential function using solve2(). *

                  * It takes 25 to 50 iterations for the last two tests to converge. */ public void testExpm1Function2() throws MathException { UnivariateRealFunction f = new Expm1Function(); MullerSolver solver = new MullerSolver(); double min, max, expected, result, tolerance; min = -1.0; max = 2.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); min = -20.0; max = 10.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); min = -50.0; max = 100.0; expected = 0.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve2(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of parameters for the solver. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new MullerSolver(); try { // bad interval solver.solve(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // no bracketing solver.solve(f, 2, 3); fail("Expecting IllegalArgumentException - no bracketing"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/LaguerreSolverTest.java100644 1750 1750 17631 11532241241 32407 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.MathException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Laguerre solver. *

                  * Laguerre's method is very efficient in solving polynomials. Test runs * show that for a default absolute accuracy of 1E-6, it generally takes * less than 5 iterations to find one root, provided solveAll() is not * invoked, and 15 to 20 iterations to find all roots for quintic function. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class LaguerreSolverTest extends TestCase { /** * Test deprecated APIs. */ @Deprecated public void testDeprecated() throws MathException { double min, max, expected, result, tolerance; // p(x) = 4x - 1 double coefficients[] = { -1.0, 4.0 }; PolynomialFunction f = new PolynomialFunction(coefficients); UnivariateRealSolver solver = new LaguerreSolver(f); min = 0.0; max = 1.0; expected = 0.25; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the linear function. */ public void testLinearFunction() throws MathException { double min, max, expected, result, tolerance; // p(x) = 4x - 1 double coefficients[] = { -1.0, 4.0 }; PolynomialFunction f = new PolynomialFunction(coefficients); UnivariateRealSolver solver = new LaguerreSolver(); min = 0.0; max = 1.0; expected = 0.25; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quadratic function. */ public void testQuadraticFunction() throws MathException { double min, max, expected, result, tolerance; // p(x) = 2x^2 + 5x - 3 = (x+3)(2x-1) double coefficients[] = { -3.0, 5.0, 2.0 }; PolynomialFunction f = new PolynomialFunction(coefficients); UnivariateRealSolver solver = new LaguerreSolver(); min = 0.0; max = 2.0; expected = 0.5; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -4.0; max = -1.0; expected = -3.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quintic function. */ public void testQuinticFunction() throws MathException { double min, max, expected, result, tolerance; // p(x) = x^5 - x^4 - 12x^3 + x^2 - x - 12 = (x+1)(x+3)(x-4)(x^2-x+1) double coefficients[] = { -12.0, -1.0, 1.0, -12.0, -1.0, 1.0 }; PolynomialFunction f = new PolynomialFunction(coefficients); UnivariateRealSolver solver = new LaguerreSolver(); min = -2.0; max = 2.0; expected = -1.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = -5.0; max = -2.5; expected = -3.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); min = 3.0; max = 6.0; expected = 4.0; tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected * solver.getRelativeAccuracy())); result = solver.solve(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of solver for the quintic function using solveAll(). */ public void testQuinticFunction2() throws MathException { double initial = 0.0, tolerance; Complex expected, result[]; // p(x) = x^5 + 4x^3 + x^2 + 4 = (x+1)(x^2-x+1)(x^2+4) double coefficients[] = { 4.0, 0.0, 1.0, 4.0, 0.0, 1.0 }; LaguerreSolver solver = new LaguerreSolver(); result = solver.solveAll(coefficients, initial); expected = new Complex(0.0, -2.0); tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected.abs() * solver.getRelativeAccuracy())); TestUtils.assertContains(result, expected, tolerance); expected = new Complex(0.0, 2.0); tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected.abs() * solver.getRelativeAccuracy())); TestUtils.assertContains(result, expected, tolerance); expected = new Complex(0.5, 0.5 * FastMath.sqrt(3.0)); tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected.abs() * solver.getRelativeAccuracy())); TestUtils.assertContains(result, expected, tolerance); expected = new Complex(-1.0, 0.0); tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected.abs() * solver.getRelativeAccuracy())); TestUtils.assertContains(result, expected, tolerance); expected = new Complex(0.5, -0.5 * FastMath.sqrt(3.0)); tolerance = FastMath.max(solver.getAbsoluteAccuracy(), FastMath.abs(expected.abs() * solver.getRelativeAccuracy())); TestUtils.assertContains(result, expected, tolerance); } /** * Test of parameters for the solver. */ public void testParameters() throws Exception { double coefficients[] = { -3.0, 5.0, 2.0 }; PolynomialFunction f = new PolynomialFunction(coefficients); UnivariateRealSolver solver = new LaguerreSolver(); try { // bad interval solver.solve(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // no bracketing solver.solve(f, 2, 3); fail("Expecting IllegalArgumentException - no bracketing"); } catch (IllegalArgumentException ex) { // expected } try { // bad function solver.solve(new SinFunction(), -1, 1); fail("Expecting IllegalArgumentException - bad function"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/solvers/BrentSolverTest.java100644 1750 1750 44370 11532241241 31713 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import junit.framework.TestCase; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.MonitoredFunction; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; /** * Testcase for UnivariateRealSolver. * Because Brent-Dekker is guaranteed to converge in less than the default * maximum iteration count due to bisection fallback, it is quite hard to * debug. I include measured iteration counts plus one in order to detect * regressions. On average Brent-Dekker should use 4..5 iterations for the * default absolute accuracy of 10E-8 for sinus and the quintic function around * zero, and 5..10 iterations for the other zeros. * * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $ */ public final class BrentSolverTest extends TestCase { public BrentSolverTest(String name) { super(name); } @Deprecated public void testDeprecated() throws MathException { // The sinus function is behaved well around the root at #pi. The second // order derivative is zero, which means linar approximating methods will // still converge quadratically. UnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new BrentSolver(f); // Somewhat benign interval. The function is monotone. result = solver.solve(3, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 4 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 5); // Larger and somewhat less benign interval. The function is grows first. result = solver.solve(1, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); solver = new SecantSolver(f); result = solver.solve(3, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 4 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 5); result = solver.solve(1, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); assertEquals(result, solver.getResult(), 0); } public void testSinZero() throws MathException { // The sinus function is behaved well around the root at #pi. The second // order derivative is zero, which means linar approximating methods will // still converge quadratically. UnivariateRealFunction f = new SinFunction(); double result; UnivariateRealSolver solver = new BrentSolver(); // Somewhat benign interval. The function is monotone. result = solver.solve(f, 3, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 4 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 5); // Larger and somewhat less benign interval. The function is grows first. result = solver.solve(f, 1, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); solver = new SecantSolver(); result = solver.solve(f, 3, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 4 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 5); result = solver.solve(f, 1, 4); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); assertEquals(result, solver.getResult(), 0); } public void testQuinticZero() throws MathException { // The quintic function has zeros at 0, +-0.5 and +-1. // Around the root of 0 the function is well behaved, with a second derivative // of zero a 0. // The other roots are less well to find, in particular the root at 1, because // the function grows fast for x>1. // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643, // intervals containing these values are harder for the solvers. UnivariateRealFunction f = new QuinticFunction(); double result; // Brent-Dekker solver. UnivariateRealSolver solver = new BrentSolver(); // Symmetric bracket around 0. Test whether solvers can handle hitting // the root in the first iteration. result = solver.solve(f, -0.2, 0.2); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertTrue(solver.getIterationCount() <= 2); // 1 iterations on i586 JDK 1.4.1. // Asymmetric bracket around 0, just for fun. Contains extremum. result = solver.solve(f, -0.1, 0.3); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); // Large bracket around 0. Contains two extrema. result = solver.solve(f, -0.3, 0.45); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); // 6 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 7); // Benign bracket around 0.5, function is monotonous. result = solver.solve(f, 0.3, 0.7); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 6 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 7); // Less benign bracket around 0.5, contains one extremum. result = solver.solve(f, 0.2, 0.6); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 6 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 7); // Large, less benign bracket around 0.5, contains both extrema. result = solver.solve(f, 0.05, 0.95); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 8 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 9); // Relatively benign bracket around 1, function is monotonous. Fast growth for x>1 // is still a problem. result = solver.solve(f, 0.85, 1.25); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 8 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 9); // Less benign bracket around 1 with extremum. result = solver.solve(f, 0.8, 1.2); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 8 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 9); // Large bracket around 1. Monotonous. result = solver.solve(f, 0.85, 1.75); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 10 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 11); // Large bracket around 1. Interval contains extremum. result = solver.solve(f, 0.55, 1.45); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 7 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 8); // Very large bracket around 1 for testing fast growth behaviour. result = solver.solve(f, 0.85, 5); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 12 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 13); // Secant solver. solver = new SecantSolver(); result = solver.solve(f, -0.2, 0.2); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); // 1 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 2); result = solver.solve(f, -0.1, 0.3); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); // 5 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 6); result = solver.solve(f, -0.3, 0.45); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0, solver.getAbsoluteAccuracy()); // 6 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 7); result = solver.solve(f, 0.3, 0.7); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 7 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 8); result = solver.solve(f, 0.2, 0.6); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 6 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 7); result = solver.solve(f, 0.05, 0.95); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); // 8 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 9); result = solver.solve(f, 0.85, 1.25); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 10 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 11); result = solver.solve(f, 0.8, 1.2); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 8 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 9); result = solver.solve(f, 0.85, 1.75); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 14 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 15); // The followig is especially slow because the solver first has to reduce // the bracket to exclude the extremum. After that, convergence is rapide. result = solver.solve(f, 0.55, 1.45); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 7 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 8); result = solver.solve(f, 0.85, 5); //System.out.println( // "Root: " + result + " Iterations: " + solver.getIterationCount()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); // 14 iterations on i586 JDK 1.4.1. assertTrue(solver.getIterationCount() <= 15); // Static solve method result = UnivariateRealSolverUtils.solve(f, -0.2, 0.2); assertEquals(result, 0, solver.getAbsoluteAccuracy()); result = UnivariateRealSolverUtils.solve(f, -0.1, 0.3); assertEquals(result, 0, 1E-8); result = UnivariateRealSolverUtils.solve(f, -0.3, 0.45); assertEquals(result, 0, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.3, 0.7); assertEquals(result, 0.5, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.2, 0.6); assertEquals(result, 0.5, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.05, 0.95); assertEquals(result, 0.5, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.85, 1.25); assertEquals(result, 1.0, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.8, 1.2); assertEquals(result, 1.0, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.85, 1.75); assertEquals(result, 1.0, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.55, 1.45); assertEquals(result, 1.0, 1E-6); result = UnivariateRealSolverUtils.solve(f, 0.85, 5); assertEquals(result, 1.0, 1E-6); } public void testRootEndpoints() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new BrentSolver(); // endpoint is root double result = solver.solve(f, FastMath.PI, 4); assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy()); result = solver.solve(f, 3, FastMath.PI); assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy()); result = solver.solve(f, FastMath.PI, 4, 3.5); assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy()); result = solver.solve(f, 3, FastMath.PI, 3.07); assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy()); } public void testBadEndpoints() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealSolver solver = new BrentSolver(); try { // bad interval solver.solve(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // no bracket solver.solve(f, 1, 1.5); fail("Expecting IllegalArgumentException - non-bracketing"); } catch (IllegalArgumentException ex) { // expected } try { // no bracket solver.solve(f, 1, 1.5, 1.2); fail("Expecting IllegalArgumentException - non-bracketing"); } catch (IllegalArgumentException ex) { // expected } } public void testInitialGuess() throws MathException { MonitoredFunction f = new MonitoredFunction(new QuinticFunction()); UnivariateRealSolver solver = new BrentSolver(); double result; // no guess result = solver.solve(f, 0.6, 7.0); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); int referenceCallsCount = f.getCallsCount(); assertTrue(referenceCallsCount >= 13); // invalid guess (it *is* a root, but outside of the range) try { result = solver.solve(f, 0.6, 7.0, 0.0); fail("an IllegalArgumentException was expected"); } catch (IllegalArgumentException iae) { // expected behaviour } // bad guess f.setCallsCount(0); result = solver.solve(f, 0.6, 7.0, 0.61); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertTrue(f.getCallsCount() > referenceCallsCount); // good guess f.setCallsCount(0); result = solver.solve(f, 0.6, 7.0, 0.999999); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertTrue(f.getCallsCount() < referenceCallsCount); // perfect guess f.setCallsCount(0); result = solver.solve(f, 0.6, 7.0, 1.0); assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(0, solver.getIterationCount()); assertEquals(1, f.getCallsCount()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/SumSincFunction.java100644 1750 1750 5520 11532241241 30152 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * Auxiliary class for testing optimizers. * * @version $Revision$ $Date$ */ public class SumSincFunction implements DifferentiableMultivariateRealFunction { private static final DifferentiableUnivariateRealFunction sinc = new SincFunction(); private static final UnivariateRealFunction sincDeriv = sinc.derivative(); /** * Factor that will multiply each term of the sum. */ private final double factor; /** * @param factor Factor that will multiply each term of the sum. */ public SumSincFunction(double factor) { this.factor = factor; } /** * @param point Argument. * @return the value of this function at point {@code x}. */ public double value(double[] point) throws FunctionEvaluationException { double sum = 0; for (int i = 0, max = point.length; i < max; i++) { final double x = point[i]; final double v = sinc.value(x); sum += v; } return factor * sum; } /** * {@inheritDoc} */ public MultivariateRealFunction partialDerivative(final int k) { return new MultivariateRealFunction() { public double value(double[] point) throws FunctionEvaluationException { return sincDeriv.value(point[k]); } }; } /** * {@inheritDoc} */ public MultivariateVectorialFunction gradient() { return new MultivariateVectorialFunction() { public double[] value(double[] point) throws FunctionEvaluationException { final int n = point.length; final double[] r = new double[n]; for (int i = 0; i < n; i++) { final double x = point[i]; r[i] = factor * sincDeriv.value(x); } return r; } }; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/MonitoredFunction.java100644 1750 1750 3062 11532241241 30530 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * Wrapper class for counting functions calls. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class MonitoredFunction implements UnivariateRealFunction { public MonitoredFunction(UnivariateRealFunction f) { callsCount = 0; this.f = f; } public void setCallsCount(int callsCount) { this.callsCount = callsCount; } public int getCallsCount() { return callsCount; } public double value(double x) throws FunctionEvaluationException { ++callsCount; return f.value(x); } private int callsCount; private UnivariateRealFunction f; } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTe100644 1750 1750 23654 11532241241 32663 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; // junit import junit.framework.TestCase; /** * Tests the PolynomialFunction implementation of a UnivariateRealFunction. * * @version $Revision: 1070725 $ * @author Matt Cliff */ public final class PolynomialFunctionTest extends TestCase { /** Error tolerance for tests */ protected double tolerance = 1.0e-12; /** * tests the value of a constant polynomial. * *

                  value of this is 2.5 everywhere.

                  */ public void testConstants() throws Exception { double[] c = { 2.5 }; PolynomialFunction f = new PolynomialFunction( c ); // verify that we are equal to c[0] at several (nonsymmetric) places assertEquals( f.value( 0.0), c[0], tolerance ); assertEquals( f.value( -1.0), c[0], tolerance ); assertEquals( f.value( -123.5), c[0], tolerance ); assertEquals( f.value( 3.0), c[0], tolerance ); assertEquals( f.value( 456.89), c[0], tolerance ); assertEquals(f.degree(), 0); assertEquals(f.derivative().value(0), 0, tolerance); assertEquals(f.polynomialDerivative().derivative().value(0), 0, tolerance); } /** * tests the value of a linear polynomial. * *

                  This will test the function f(x) = 3*x - 1.5

                  *

                  This will have the values * f(0.0) = -1.5, f(-1.0) = -4.5, f(-2.5) = -9.0, * f(0.5) = 0.0, f(1.5) = 3.0 and f(3.0) = 7.5 *

                  */ public void testLinear() throws Exception { double[] c = { -1.5, 3.0 }; PolynomialFunction f = new PolynomialFunction( c ); // verify that we are equal to c[0] when x=0 assertEquals( f.value( 0.0), c[0], tolerance ); // now check a few other places assertEquals( -4.5, f.value( -1.0), tolerance ); assertEquals( -9.0, f.value( -2.5), tolerance ); assertEquals( 0.0, f.value( 0.5), tolerance ); assertEquals( 3.0, f.value( 1.5), tolerance ); assertEquals( 7.5, f.value( 3.0), tolerance ); assertEquals(f.degree(), 1); assertEquals(f.polynomialDerivative().derivative().value(0), 0, tolerance); } /** * Tests a second order polynomial. *

                  This will test the function f(x) = 2x^2 - 3x -2 = (2x+1)(x-2)

                  * */ public void testQuadratic() { double[] c = { -2.0, -3.0, 2.0 }; PolynomialFunction f = new PolynomialFunction( c ); // verify that we are equal to c[0] when x=0 assertEquals( f.value( 0.0), c[0], tolerance ); // now check a few other places assertEquals( 0.0, f.value( -0.5), tolerance ); assertEquals( 0.0, f.value( 2.0), tolerance ); assertEquals( -2.0, f.value( 1.5), tolerance ); assertEquals( 7.0, f.value( -1.5), tolerance ); assertEquals( 265.5312, f.value( 12.34), tolerance ); } /** * This will test the quintic function * f(x) = x^2(x-5)(x+3)(x-1) = x^5 - 3x^4 -13x^3 + 15x^2

                  * */ public void testQuintic() { double[] c = { 0.0, 0.0, 15.0, -13.0, -3.0, 1.0 }; PolynomialFunction f = new PolynomialFunction( c ); // verify that we are equal to c[0] when x=0 assertEquals( f.value( 0.0), c[0], tolerance ); // now check a few other places assertEquals( 0.0, f.value( 5.0), tolerance ); assertEquals( 0.0, f.value( 1.0), tolerance ); assertEquals( 0.0, f.value( -3.0), tolerance ); assertEquals( 54.84375, f.value( -1.5), tolerance ); assertEquals( -8.06637, f.value( 1.3), tolerance ); assertEquals(f.degree(), 5); } /** * tests the firstDerivative function by comparison * *

                  This will test the functions * f(x) = x^3 - 2x^2 + 6x + 3, g(x) = 3x^2 - 4x + 6 * and h(x) = 6x - 4 */ public void testfirstDerivativeComparison() throws Exception { double[] f_coeff = { 3.0, 6.0, -2.0, 1.0 }; double[] g_coeff = { 6.0, -4.0, 3.0 }; double[] h_coeff = { -4.0, 6.0 }; PolynomialFunction f = new PolynomialFunction( f_coeff ); PolynomialFunction g = new PolynomialFunction( g_coeff ); PolynomialFunction h = new PolynomialFunction( h_coeff ); // compare f' = g assertEquals( f.derivative().value(0.0), g.value(0.0), tolerance ); assertEquals( f.derivative().value(1.0), g.value(1.0), tolerance ); assertEquals( f.derivative().value(100.0), g.value(100.0), tolerance ); assertEquals( f.derivative().value(4.1), g.value(4.1), tolerance ); assertEquals( f.derivative().value(-3.25), g.value(-3.25), tolerance ); // compare g' = h assertEquals( g.derivative().value(FastMath.PI), h.value(FastMath.PI), tolerance ); assertEquals( g.derivative().value(FastMath.E), h.value(FastMath.E), tolerance ); } public void testString() { PolynomialFunction p = new PolynomialFunction(new double[] { -5.0, 3.0, 1.0 }); checkPolynomial(p, "-5.0 + 3.0 x + x^2"); checkPolynomial(new PolynomialFunction(new double[] { 0.0, -2.0, 3.0 }), "-2.0 x + 3.0 x^2"); checkPolynomial(new PolynomialFunction(new double[] { 1.0, -2.0, 3.0 }), "1.0 - 2.0 x + 3.0 x^2"); checkPolynomial(new PolynomialFunction(new double[] { 0.0, 2.0, 3.0 }), "2.0 x + 3.0 x^2"); checkPolynomial(new PolynomialFunction(new double[] { 1.0, 2.0, 3.0 }), "1.0 + 2.0 x + 3.0 x^2"); checkPolynomial(new PolynomialFunction(new double[] { 1.0, 0.0, 3.0 }), "1.0 + 3.0 x^2"); checkPolynomial(new PolynomialFunction(new double[] { 0.0 }), "0"); } public void testAddition() { PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 1.0 }); PolynomialFunction p2 = new PolynomialFunction(new double[] { 2.0, -1.0, 0.0 }); checkNullPolynomial(p1.add(p2)); p2 = p1.add(p1); checkPolynomial(p2, "-4.0 + 2.0 x"); p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 }); p2 = new PolynomialFunction(new double[] { -1.0, 3.0, -2.0 }); p1 = p1.add(p2); assertEquals(1, p1.degree()); checkPolynomial(p1, "-x"); } public void testSubtraction() { PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 1.0 }); checkNullPolynomial(p1.subtract(p1)); PolynomialFunction p2 = new PolynomialFunction(new double[] { -2.0, 6.0 }); p2 = p2.subtract(p1); checkPolynomial(p2, "5.0 x"); p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 }); p2 = new PolynomialFunction(new double[] { -1.0, 3.0, 2.0 }); p1 = p1.subtract(p2); assertEquals(1, p1.degree()); checkPolynomial(p1, "2.0 - 7.0 x"); } public void testMultiplication() { PolynomialFunction p1 = new PolynomialFunction(new double[] { -3.0, 2.0 }); PolynomialFunction p2 = new PolynomialFunction(new double[] { 3.0, 2.0, 1.0 }); checkPolynomial(p1.multiply(p2), "-9.0 + x^2 + 2.0 x^3"); p1 = new PolynomialFunction(new double[] { 0.0, 1.0 }); p2 = p1; for (int i = 2; i < 10; ++i) { p2 = p2.multiply(p1); checkPolynomial(p2, "x^" + i); } } public void testSerial() { PolynomialFunction p2 = new PolynomialFunction(new double[] { 3.0, 2.0, 1.0 }); assertEquals(p2, TestUtils.serializeAndRecover(p2)); } /** * tests the firstDerivative function by comparison * *

                  This will test the functions * f(x) = x^3 - 2x^2 + 6x + 3, g(x) = 3x^2 - 4x + 6 * and h(x) = 6x - 4 */ public void testMath341() throws Exception { double[] f_coeff = { 3.0, 6.0, -2.0, 1.0 }; double[] g_coeff = { 6.0, -4.0, 3.0 }; double[] h_coeff = { -4.0, 6.0 }; PolynomialFunction f = new PolynomialFunction( f_coeff ); PolynomialFunction g = new PolynomialFunction( g_coeff ); PolynomialFunction h = new PolynomialFunction( h_coeff ); // compare f' = g assertEquals( f.derivative().value(0.0), g.value(0.0), tolerance ); assertEquals( f.derivative().value(1.0), g.value(1.0), tolerance ); assertEquals( f.derivative().value(100.0), g.value(100.0), tolerance ); assertEquals( f.derivative().value(4.1), g.value(4.1), tolerance ); assertEquals( f.derivative().value(-3.25), g.value(-3.25), tolerance ); // compare g' = h assertEquals( g.derivative().value(FastMath.PI), h.value(FastMath.PI), tolerance ); assertEquals( g.derivative().value(FastMath.E), h.value(FastMath.E), tolerance ); } public void checkPolynomial(PolynomialFunction p, String reference) { assertEquals(reference, p.toString()); } private void checkNullPolynomial(PolynomialFunction p) { for (double coefficient : p.getCoefficients()) { assertEquals(0.0, coefficient, 1.0e-15); } } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest100644 1750 1750 23716 11532241241 32727 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Tests the PolynomialsUtils class. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class PolynomialsUtilsTest extends TestCase { public void testFirstChebyshevPolynomials() { checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(3), "-3.0 x + 4.0 x^3"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(2), "-1.0 + 2.0 x^2"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(1), "x"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(0), "1.0"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(7), "-7.0 x + 56.0 x^3 - 112.0 x^5 + 64.0 x^7"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(6), "-1.0 + 18.0 x^2 - 48.0 x^4 + 32.0 x^6"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(5), "5.0 x - 20.0 x^3 + 16.0 x^5"); checkPolynomial(PolynomialsUtils.createChebyshevPolynomial(4), "1.0 - 8.0 x^2 + 8.0 x^4"); } public void testChebyshevBounds() { for (int k = 0; k < 12; ++k) { PolynomialFunction Tk = PolynomialsUtils.createChebyshevPolynomial(k); for (double x = -1.0; x <= 1.0; x += 0.02) { assertTrue(k + " " + Tk.value(x), FastMath.abs(Tk.value(x)) < (1.0 + 1.0e-12)); } } } public void testChebyshevDifferentials() { for (int k = 0; k < 12; ++k) { PolynomialFunction Tk0 = PolynomialsUtils.createChebyshevPolynomial(k); PolynomialFunction Tk1 = Tk0.polynomialDerivative(); PolynomialFunction Tk2 = Tk1.polynomialDerivative(); PolynomialFunction g0 = new PolynomialFunction(new double[] { k * k }); PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -1}); PolynomialFunction g2 = new PolynomialFunction(new double[] { 1, 0, -1 }); PolynomialFunction Tk0g0 = Tk0.multiply(g0); PolynomialFunction Tk1g1 = Tk1.multiply(g1); PolynomialFunction Tk2g2 = Tk2.multiply(g2); checkNullPolynomial(Tk0g0.add(Tk1g1.add(Tk2g2))); } } public void testFirstHermitePolynomials() { checkPolynomial(PolynomialsUtils.createHermitePolynomial(3), "-12.0 x + 8.0 x^3"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(2), "-2.0 + 4.0 x^2"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(1), "2.0 x"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(0), "1.0"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(7), "-1680.0 x + 3360.0 x^3 - 1344.0 x^5 + 128.0 x^7"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(6), "-120.0 + 720.0 x^2 - 480.0 x^4 + 64.0 x^6"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(5), "120.0 x - 160.0 x^3 + 32.0 x^5"); checkPolynomial(PolynomialsUtils.createHermitePolynomial(4), "12.0 - 48.0 x^2 + 16.0 x^4"); } public void testHermiteDifferentials() { for (int k = 0; k < 12; ++k) { PolynomialFunction Hk0 = PolynomialsUtils.createHermitePolynomial(k); PolynomialFunction Hk1 = Hk0.polynomialDerivative(); PolynomialFunction Hk2 = Hk1.polynomialDerivative(); PolynomialFunction g0 = new PolynomialFunction(new double[] { 2 * k }); PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -2 }); PolynomialFunction g2 = new PolynomialFunction(new double[] { 1 }); PolynomialFunction Hk0g0 = Hk0.multiply(g0); PolynomialFunction Hk1g1 = Hk1.multiply(g1); PolynomialFunction Hk2g2 = Hk2.multiply(g2); checkNullPolynomial(Hk0g0.add(Hk1g1.add(Hk2g2))); } } public void testFirstLaguerrePolynomials() { checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(3), 6l, "6.0 - 18.0 x + 9.0 x^2 - x^3"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(2), 2l, "2.0 - 4.0 x + x^2"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(1), 1l, "1.0 - x"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(0), 1l, "1.0"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(7), 5040l, "5040.0 - 35280.0 x + 52920.0 x^2 - 29400.0 x^3" + " + 7350.0 x^4 - 882.0 x^5 + 49.0 x^6 - x^7"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(6), 720l, "720.0 - 4320.0 x + 5400.0 x^2 - 2400.0 x^3 + 450.0 x^4" + " - 36.0 x^5 + x^6"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(5), 120l, "120.0 - 600.0 x + 600.0 x^2 - 200.0 x^3 + 25.0 x^4 - x^5"); checkPolynomial(PolynomialsUtils.createLaguerrePolynomial(4), 24l, "24.0 - 96.0 x + 72.0 x^2 - 16.0 x^3 + x^4"); } public void testLaguerreDifferentials() { for (int k = 0; k < 12; ++k) { PolynomialFunction Lk0 = PolynomialsUtils.createLaguerrePolynomial(k); PolynomialFunction Lk1 = Lk0.polynomialDerivative(); PolynomialFunction Lk2 = Lk1.polynomialDerivative(); PolynomialFunction g0 = new PolynomialFunction(new double[] { k }); PolynomialFunction g1 = new PolynomialFunction(new double[] { 1, -1 }); PolynomialFunction g2 = new PolynomialFunction(new double[] { 0, 1 }); PolynomialFunction Lk0g0 = Lk0.multiply(g0); PolynomialFunction Lk1g1 = Lk1.multiply(g1); PolynomialFunction Lk2g2 = Lk2.multiply(g2); checkNullPolynomial(Lk0g0.add(Lk1g1.add(Lk2g2))); } } public void testFirstLegendrePolynomials() { checkPolynomial(PolynomialsUtils.createLegendrePolynomial(3), 2l, "-3.0 x + 5.0 x^3"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(2), 2l, "-1.0 + 3.0 x^2"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(1), 1l, "x"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(0), 1l, "1.0"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(7), 16l, "-35.0 x + 315.0 x^3 - 693.0 x^5 + 429.0 x^7"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(6), 16l, "-5.0 + 105.0 x^2 - 315.0 x^4 + 231.0 x^6"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(5), 8l, "15.0 x - 70.0 x^3 + 63.0 x^5"); checkPolynomial(PolynomialsUtils.createLegendrePolynomial(4), 8l, "3.0 - 30.0 x^2 + 35.0 x^4"); } public void testLegendreDifferentials() { for (int k = 0; k < 12; ++k) { PolynomialFunction Pk0 = PolynomialsUtils.createLegendrePolynomial(k); PolynomialFunction Pk1 = Pk0.polynomialDerivative(); PolynomialFunction Pk2 = Pk1.polynomialDerivative(); PolynomialFunction g0 = new PolynomialFunction(new double[] { k * (k + 1) }); PolynomialFunction g1 = new PolynomialFunction(new double[] { 0, -2 }); PolynomialFunction g2 = new PolynomialFunction(new double[] { 1, 0, -1 }); PolynomialFunction Pk0g0 = Pk0.multiply(g0); PolynomialFunction Pk1g1 = Pk1.multiply(g1); PolynomialFunction Pk2g2 = Pk2.multiply(g2); checkNullPolynomial(Pk0g0.add(Pk1g1.add(Pk2g2))); } } public void testHighDegreeLegendre() { PolynomialsUtils.createLegendrePolynomial(40); double[] l40 = PolynomialsUtils.createLegendrePolynomial(40).getCoefficients(); double denominator = 274877906944.0; double[] numerators = new double[] { +34461632205.0, -28258538408100.0, +3847870979902950.0, -207785032914759300.0, +5929294332103310025.0, -103301483474866556880.0, +1197358103913226000200.0, -9763073770369381232400.0, +58171647881784229843050.0, -260061484647976556945400.0, +888315281771246239250340.0, -2345767627188139419665400.0, +4819022625419112503443050.0, -7710436200670580005508880.0, +9566652323054238154983240.0, -9104813935044723209570256.0, +6516550296251767619752905.0, -3391858621221953912598660.0, +1211378079007840683070950.0, -265365894974690562152100.0, +26876802183334044115405.0 }; for (int i = 0; i < l40.length; ++i) { if (i % 2 == 0) { double ci = numerators[i / 2] / denominator; assertEquals(ci, l40[i], FastMath.abs(ci) * 1.0e-15); } else { assertEquals(0.0, l40[i], 0.0); } } } private void checkPolynomial(PolynomialFunction p, long denominator, String reference) { PolynomialFunction q = new PolynomialFunction(new double[] { denominator}); assertEquals(reference, p.multiply(q).toString()); } private void checkPolynomial(PolynomialFunction p, String reference) { assertEquals(reference, p.toString()); } private void checkNullPolynomial(PolynomialFunction p) { for (double coefficient : p.getCoefficients()) { assertEquals(0.0, coefficient, 1.0e-13); } } } ././@LongLink100644 0 0 162 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunctionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunc100644 1750 1750 12575 11532241241 32653 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import java.util.Arrays; import junit.framework.TestCase; import org.apache.commons.math.ArgumentOutsideDomainException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Tests the PolynomialSplineFunction implementation. * * @version $Revision: 1042508 $ */ public class PolynomialSplineFunctionTest extends TestCase { /** Error tolerance for tests */ protected double tolerance = 1.0e-12; /** * Quadratic polynomials used in tests: * * x^2 + x [-1, 0) * x^2 + x + 2 [0, 1) * x^2 + x + 4 [1, 2) * * Defined so that evaluation using PolynomialSplineFunction evaluation * algorithm agrees at knot point boundaries. */ protected PolynomialFunction[] polynomials = { new PolynomialFunction(new double[] {0d, 1d, 1d}), new PolynomialFunction(new double[] {2d, 1d, 1d}), new PolynomialFunction(new double[] {4d, 1d, 1d}) }; /** Knot points */ protected double[] knots = {-1, 0, 1, 2}; /** Derivative of test polynomials -- 2x + 1 */ protected PolynomialFunction dp = new PolynomialFunction(new double[] {1d, 2d}); public void testConstructor() { PolynomialSplineFunction spline = new PolynomialSplineFunction(knots, polynomials); assertTrue(Arrays.equals(knots, spline.getKnots())); assertEquals(1d, spline.getPolynomials()[0].getCoefficients()[2], 0); assertEquals(3, spline.getN()); try { // too few knots new PolynomialSplineFunction(new double[] {0}, polynomials); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { // too many knots new PolynomialSplineFunction(new double[] {0,1,2,3,4}, polynomials); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } try { // knots not increasing new PolynomialSplineFunction(new double[] {0,1, 3, 2}, polynomials); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testValues() throws Exception { PolynomialSplineFunction spline = new PolynomialSplineFunction(knots, polynomials); UnivariateRealFunction dSpline = spline.derivative(); /** * interior points -- spline value at x should equal p(x - knot) * where knot is the largest knot point less than or equal to x and p * is the polynomial defined over the knot segment to which x belongs. */ double x = -1; int index = 0; for (int i = 0; i < 10; i++) { x+=0.25; index = findKnot(knots, x); assertEquals("spline function evaluation failed for x=" + x, polynomials[index].value(x - knots[index]), spline.value(x), tolerance); assertEquals("spline derivative evaluation failed for x=" + x, dp.value(x - knots[index]), dSpline.value(x), tolerance); } // knot points -- centering should zero arguments for (int i = 0; i < 3; i++) { assertEquals("spline function evaluation failed for knot=" + knots[i], polynomials[i].value(0), spline.value(knots[i]), tolerance); assertEquals("spline function evaluation failed for knot=" + knots[i], dp.value(0), dSpline.value(knots[i]), tolerance); } try { //outside of domain -- under min x = spline.value(-1.5); fail("Expecting ArgumentOutsideDomainException"); } catch (ArgumentOutsideDomainException ex) { // expected } try { //outside of domain -- over max x = spline.value(2.5); fail("Expecting ArgumentOutsideDomainException"); } catch (ArgumentOutsideDomainException ex) { // expected } } /** * Do linear search to find largest knot point less than or equal to x. * Implementation does binary search. */ protected int findKnot(double[] knots, double x) { if (x < knots[0] || x >= knots[knots.length -1]) { throw new IllegalArgumentException("x is out of range"); } for (int i = 0; i < knots.length; i++) { if (knots[i] > x) { return i -1; } } throw new IllegalArgumentException("x is out of range"); } } ././@LongLink100644 0 0 166 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonFormTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNe100644 1750 1750 12520 11532241241 32643 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.FunctionEvaluationException; import junit.framework.TestCase; /** * Testcase for Newton form of polynomial function. *

                  * The small tolerance number is used only to account for round-off errors. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ */ public final class PolynomialFunctionNewtonFormTest extends TestCase { /** * Test of polynomial for the linear function. */ public void testLinearFunction() throws FunctionEvaluationException { PolynomialFunctionNewtonForm p; double coefficients[], z, expected, result, tolerance = 1E-12; // p(x) = 1.5x - 4 = 2 + 1.5(x-4) double a[] = { 2.0, 1.5 }; double c[] = { 4.0 }; p = new PolynomialFunctionNewtonForm(a, c); z = 2.0; expected = -1.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 4.5; expected = 2.75; result = p.value(z); assertEquals(expected, result, tolerance); z = 6.0; expected = 5.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(1, p.degree()); coefficients = p.getCoefficients(); assertEquals(2, coefficients.length); assertEquals(-4.0, coefficients[0], tolerance); assertEquals(1.5, coefficients[1], tolerance); } /** * Test of polynomial for the quadratic function. */ public void testQuadraticFunction() throws FunctionEvaluationException { PolynomialFunctionNewtonForm p; double coefficients[], z, expected, result, tolerance = 1E-12; // p(x) = 2x^2 + 5x - 3 = 4 + 3(x-1) + 2(x-1)(x+2) double a[] = { 4.0, 3.0, 2.0 }; double c[] = { 1.0, -2.0 }; p = new PolynomialFunctionNewtonForm(a, c); z = 1.0; expected = 4.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 2.5; expected = 22.0; result = p.value(z); assertEquals(expected, result, tolerance); z = -2.0; expected = -5.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(2, p.degree()); coefficients = p.getCoefficients(); assertEquals(3, coefficients.length); assertEquals(-3.0, coefficients[0], tolerance); assertEquals(5.0, coefficients[1], tolerance); assertEquals(2.0, coefficients[2], tolerance); } /** * Test of polynomial for the quintic function. */ public void testQuinticFunction() throws FunctionEvaluationException { PolynomialFunctionNewtonForm p; double coefficients[], z, expected, result, tolerance = 1E-12; // p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x // = 6x - 6x^2 -6x^2(x-1) + x^2(x-1)(x+1) + x^2(x-1)(x+1)(x-2) double a[] = { 0.0, 6.0, -6.0, -6.0, 1.0, 1.0 }; double c[] = { 0.0, 0.0, 1.0, -1.0, 2.0 }; p = new PolynomialFunctionNewtonForm(a, c); z = 0.0; expected = 0.0; result = p.value(z); assertEquals(expected, result, tolerance); z = -2.0; expected = 0.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 4.0; expected = 360.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(5, p.degree()); coefficients = p.getCoefficients(); assertEquals(6, coefficients.length); assertEquals(0.0, coefficients[0], tolerance); assertEquals(6.0, coefficients[1], tolerance); assertEquals(1.0, coefficients[2], tolerance); assertEquals(-7.0, coefficients[3], tolerance); assertEquals(-1.0, coefficients[4], tolerance); assertEquals(1.0, coefficients[5], tolerance); } /** * Test of parameters for the polynomial. */ public void testParameters() throws Exception { try { // bad input array length double a[] = { 1.0 }; double c[] = { 2.0 }; new PolynomialFunctionNewtonForm(a, c); fail("Expecting IllegalArgumentException - bad input array length"); } catch (IllegalArgumentException ex) { // expected } try { // mismatch input arrays double a[] = { 1.0, 2.0, 3.0, 4.0 }; double c[] = { 4.0, 3.0, 2.0, 1.0 }; new PolynomialFunctionNewtonForm(a, c); fail("Expecting IllegalArgumentException - mismatch input arrays"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 170 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeFormTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLa100644 1750 1750 12325 11532241241 32640 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.FunctionEvaluationException; import junit.framework.TestCase; /** * Testcase for Lagrange form of polynomial function. *

                  * We use n+1 points to interpolate a polynomial of degree n. This should * give us the exact same polynomial as result. Thus we can use a very * small tolerance to account only for round-off errors. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ */ public final class PolynomialFunctionLagrangeFormTest extends TestCase { /** * Test of polynomial for the linear function. */ public void testLinearFunction() throws FunctionEvaluationException { PolynomialFunctionLagrangeForm p; double c[], z, expected, result, tolerance = 1E-12; // p(x) = 1.5x - 4 double x[] = { 0.0, 3.0 }; double y[] = { -4.0, 0.5 }; p = new PolynomialFunctionLagrangeForm(x, y); z = 2.0; expected = -1.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 4.5; expected = 2.75; result = p.value(z); assertEquals(expected, result, tolerance); z = 6.0; expected = 5.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(1, p.degree()); c = p.getCoefficients(); assertEquals(2, c.length); assertEquals(-4.0, c[0], tolerance); assertEquals(1.5, c[1], tolerance); } /** * Test of polynomial for the quadratic function. */ public void testQuadraticFunction() throws FunctionEvaluationException { PolynomialFunctionLagrangeForm p; double c[], z, expected, result, tolerance = 1E-12; // p(x) = 2x^2 + 5x - 3 = (2x - 1)(x + 3) double x[] = { 0.0, -1.0, 0.5 }; double y[] = { -3.0, -6.0, 0.0 }; p = new PolynomialFunctionLagrangeForm(x, y); z = 1.0; expected = 4.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 2.5; expected = 22.0; result = p.value(z); assertEquals(expected, result, tolerance); z = -2.0; expected = -5.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(2, p.degree()); c = p.getCoefficients(); assertEquals(3, c.length); assertEquals(-3.0, c[0], tolerance); assertEquals(5.0, c[1], tolerance); assertEquals(2.0, c[2], tolerance); } /** * Test of polynomial for the quintic function. */ public void testQuinticFunction() throws FunctionEvaluationException { PolynomialFunctionLagrangeForm p; double c[], z, expected, result, tolerance = 1E-12; // p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x = x(x^2 - 1)(x + 2)(x - 3) double x[] = { 1.0, -1.0, 2.0, 3.0, -3.0, 0.5 }; double y[] = { 0.0, 0.0, -24.0, 0.0, -144.0, 2.34375 }; p = new PolynomialFunctionLagrangeForm(x, y); z = 0.0; expected = 0.0; result = p.value(z); assertEquals(expected, result, tolerance); z = -2.0; expected = 0.0; result = p.value(z); assertEquals(expected, result, tolerance); z = 4.0; expected = 360.0; result = p.value(z); assertEquals(expected, result, tolerance); assertEquals(5, p.degree()); c = p.getCoefficients(); assertEquals(6, c.length); assertEquals(0.0, c[0], tolerance); assertEquals(6.0, c[1], tolerance); assertEquals(1.0, c[2], tolerance); assertEquals(-7.0, c[3], tolerance); assertEquals(-1.0, c[4], tolerance); assertEquals(1.0, c[5], tolerance); } /** * Test of parameters for the polynomial. */ public void testParameters() throws Exception { try { // bad input array length double x[] = { 1.0 }; double y[] = { 2.0 }; new PolynomialFunctionLagrangeForm(x, y); fail("Expecting IllegalArgumentException - bad input array length"); } catch (IllegalArgumentException ex) { // expected } try { // mismatch input arrays double x[] = { 1.0, 2.0, 3.0, 4.0 }; double y[] = { 0.0, -4.0, -24.0 }; new PolynomialFunctionLagrangeForm(x, y); fail("Expecting IllegalArgumentException - mismatch input arrays"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/SincFunction.java100644 1750 1750 3147 11532241241 27470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Auxiliary class for testing optimizers. * * @version $Revision$ $Date$ */ public class SincFunction implements DifferentiableUnivariateRealFunction { private static final double EPS = 1e-12; /** * @param x Argument. * @return the value of this function at point {@code x}. */ public double value(double x) { return (Math.abs(x) < EPS ? 1 : Math.sin(x) / x); } /** * {@inheritDoc} */ public UnivariateRealFunction derivative() { return new UnivariateRealFunction() { public double value(double x) { return (Math.abs(x) < EPS ? 0 : (x * Math.cos(x) - Math.sin(x)) / (x * x)); } }; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java100644 1750 1750 5452 11532241241 30661 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; public class BinaryFunctionTest { @Test public void testAdd() throws Exception { Assert.assertEquals(5.0, BinaryFunction.ADD.value(2, 3), 1.0e-15); Assert.assertEquals(0.0, BinaryFunction.ADD.value(-1, 1), 1.0e-15); } @Test public void testSubtract() throws Exception { Assert.assertEquals(-1.0, BinaryFunction.SUBTRACT.value(2, 3), 1.0e-15); Assert.assertEquals(-2.0, BinaryFunction.SUBTRACT.value(-1, 1), 1.0e-15); } @Test public void testMultiply() throws Exception { Assert.assertEquals(6.0, BinaryFunction.MULTIPLY.value(2, 3), 1.0e-15); Assert.assertEquals(-1.0, BinaryFunction.MULTIPLY.value(-1, 1), 1.0e-15); } @Test public void testDivide() throws Exception { Assert.assertEquals(1.5, BinaryFunction.DIVIDE.value(3, 2), 1.0e-15); Assert.assertEquals(-1.0, BinaryFunction.DIVIDE.value(-1, 1), 1.0e-15); } @Test public void testPow() throws Exception { Assert.assertEquals(9.0, BinaryFunction.POW.value(3, 2), 1.0e-15); Assert.assertEquals(-1.0, BinaryFunction.POW.value(-1, 1), 1.0e-15); } @Test public void testAtan2() throws Exception { Assert.assertEquals(FastMath.PI / 4, BinaryFunction.ATAN2.value(1, 1), 1.0e-15); Assert.assertEquals(-FastMath.PI / 4, BinaryFunction.ATAN2.value(-1, 1), 1.0e-15); } @Test public void testFix1st() throws Exception { ComposableFunction f = BinaryFunction.POW.fix1stArgument(2); for (double x = 0.0; x < 1.0; x += 0.01) { Assert.assertEquals(FastMath.pow(2.0, x), f.value(x), 1.0e-15); } } @Test public void testFix2nd() throws Exception { ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2); for (double y = 0.0; y < 1.0; y += 0.01) { Assert.assertEquals(y * y, f.value(y), 1.0e-15); } } } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegra100644 1750 1750 11316 11532241241 32550 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import java.util.Random; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.util.FastMath; import junit.framework.*; public class LegendreGaussIntegratorTest extends TestCase { public LegendreGaussIntegratorTest(String name) { super(name); } public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new LegendreGaussIntegrator(5, 64); integrator.setAbsoluteAccuracy(1.0e-10); integrator.setRelativeAccuracy(1.0e-14); integrator.setMinimalIterationCount(2); integrator.setMaximalIterationCount(15); double min, max, expected, result, tolerance; min = 0; max = FastMath.PI; expected = 2; tolerance = FastMath.max(integrator.getAbsoluteAccuracy(), FastMath.abs(expected * integrator.getRelativeAccuracy())); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -FastMath.PI/3; max = 0; expected = -0.5; tolerance = FastMath.max(integrator.getAbsoluteAccuracy(), FastMath.abs(expected * integrator.getRelativeAccuracy())); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealIntegrator integrator = new LegendreGaussIntegrator(3, 64); double min, max, expected, result; min = 0; max = 1; expected = -1.0/48; result = integrator.integrate(f, min, max); assertEquals(expected, result, 1.0e-16); min = 0; max = 0.5; expected = 11.0/768; result = integrator.integrate(f, min, max); assertEquals(expected, result, 1.0e-16); min = -1; max = 4; expected = 2048/3.0 - 78 + 1.0/48; result = integrator.integrate(f, min, max); assertEquals(expected, result, 1.0e-16); } public void testExactIntegration() throws ConvergenceException, FunctionEvaluationException { Random random = new Random(86343623467878363l); for (int n = 2; n < 6; ++n) { LegendreGaussIntegrator integrator = new LegendreGaussIntegrator(n, 64); // an n points Gauss-Legendre integrator integrates 2n-1 degree polynoms exactly for (int degree = 0; degree <= 2 * n - 1; ++degree) { for (int i = 0; i < 10; ++i) { double[] coeff = new double[degree + 1]; for (int k = 0; k < coeff.length; ++k) { coeff[k] = 2 * random.nextDouble() - 1; } PolynomialFunction p = new PolynomialFunction(coeff); double result = integrator.integrate(p, -5.0, 15.0); double reference = exactIntegration(p, -5.0, 15.0); assertEquals(n + " " + degree + " " + i, reference, result, 1.0e-12 * (1.0 + FastMath.abs(reference))); } } } } private double exactIntegration(PolynomialFunction p, double a, double b) { final double[] coeffs = p.getCoefficients(); double yb = coeffs[coeffs.length - 1] / coeffs.length; double ya = yb; for (int i = coeffs.length - 2; i >= 0; --i) { yb = yb * b + coeffs[i] / (i + 1); ya = ya * a + coeffs[i] / (i + 1); } return yb * b - ya * a; } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/TrapezoidIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/TrapezoidIntegratorT100644 1750 1750 10650 11532241241 32632 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for trapezoid integrator. *

                  * Test runs show that for a default relative accuracy of 1E-6, it * generally takes 10 to 15 iterations for the integral to converge. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class TrapezoidIntegratorTest extends TestCase { /** * Test of integrator for the sine function. */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new TrapezoidIntegrator(); double min, max, expected, result, tolerance; min = 0; max = FastMath.PI; expected = 2; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -FastMath.PI/3; max = 0; expected = -0.5; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of integrator for the quintic function. */ public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealIntegrator integrator = new TrapezoidIntegrator(); double min, max, expected, result, tolerance; min = 0; max = 1; expected = -1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = 0; max = 0.5; expected = 11.0/768; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -1; max = 4; expected = 2048/3.0 - 78 + 1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of parameters for the integrator. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new TrapezoidIntegrator(); try { // bad interval integrator.integrate(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(5); integrator.setMaximalIterationCount(4); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(10); integrator.setMaximalIterationCount(99); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/SimpsonIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/SimpsonIntegratorTes100644 1750 1750 10635 11532241241 32654 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Simpson integrator. *

                  * Test runs show that for a default relative accuracy of 1E-6, it * generally takes 5 to 10 iterations for the integral to converge. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class SimpsonIntegratorTest extends TestCase { /** * Test of integrator for the sine function. */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new SimpsonIntegrator(); double min, max, expected, result, tolerance; min = 0; max = FastMath.PI; expected = 2; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -FastMath.PI/3; max = 0; expected = -0.5; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of integrator for the quintic function. */ public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealIntegrator integrator = new SimpsonIntegrator(); double min, max, expected, result, tolerance; min = 0; max = 1; expected = -1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = 0; max = 0.5; expected = 11.0/768; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -1; max = 4; expected = 2048/3.0 - 78 + 1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of parameters for the integrator. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new SimpsonIntegrator(); try { // bad interval integrator.integrate(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(5); integrator.setMaximalIterationCount(4); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(10); integrator.setMaximalIterationCount(99); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/RombergIntegratorTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/integration/RombergIntegratorTes100644 1750 1750 10746 11532241241 32624 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for Romberg integrator. *

                  * Romberg algorithm is very fast for good behavior integrand. Test runs * show that for a default relative accuracy of 1E-6, it generally takes * takes less than 5 iterations for the integral to converge. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public final class RombergIntegratorTest extends TestCase { /** * Test of integrator for the sine function. */ public void testSinFunction() throws MathException { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new RombergIntegrator(); double min, max, expected, result, tolerance; min = 0; max = FastMath.PI; expected = 2; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -FastMath.PI/3; max = 0; expected = -0.5; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of integrator for the quintic function. */ public void testQuinticFunction() throws MathException { UnivariateRealFunction f = new QuinticFunction(); UnivariateRealIntegrator integrator = new RombergIntegrator(); double min, max, expected, result, tolerance; min = 0; max = 1; expected = -1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = 0; max = 0.5; expected = 11.0/768; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); min = -1; max = 4; expected = 2048/3.0 - 78 + 1.0/48; tolerance = FastMath.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(f, min, max); assertEquals(expected, result, tolerance); } /** * Test of parameters for the integrator. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); UnivariateRealIntegrator integrator = new RombergIntegrator(); try { // bad interval integrator.integrate(f, 1, -1); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(5); integrator.setMaximalIterationCount(4); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } try { // bad iteration limits integrator.setMinimalIterationCount(10); integrator.setMaximalIterationCount(50); integrator.integrate(f, -1, 1); fail("Expecting IllegalArgumentException - bad iteration limits"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/QuinticFunction.java100644 1750 1750 2706 11532241241 30210 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Auxiliary class for testing solvers. * * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class QuinticFunction implements DifferentiableUnivariateRealFunction { /* Evaluate quintic. * @see org.apache.commons.math.UnivariateRealFunction#value(double) */ public double value(double x) { return (x-1)*(x-0.5)*x*(x+0.5)*(x+1); } public UnivariateRealFunction derivative() { return new UnivariateRealFunction() { public double value(double x) { return (5*x*x-3.75)*x*x+0.25; } }; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java100644 1750 1750 15272 11532241241 31542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.util.FastMath; import org.junit.Assert; import org.junit.Test; public class ComposableFunctionTest { @Test public void testZero() throws Exception { Assert.assertEquals(0.0, ComposableFunction.ZERO.value(1), 1.0e-15); Assert.assertEquals(0.0, ComposableFunction.ZERO.value(2), 1.0e-15); } @Test public void testOne() throws Exception { Assert.assertEquals(1.0, ComposableFunction.ONE.value(1), 1.0e-15); Assert.assertEquals(1.0, ComposableFunction.ONE.value(2), 1.0e-15); } @Test public void testIdentity() throws Exception { Assert.assertEquals(1.0, ComposableFunction.IDENTITY.value(1), 1.0e-15); Assert.assertEquals(2.0, ComposableFunction.IDENTITY.value(2), 1.0e-15); } @Test public void testRint() throws Exception { Assert.assertEquals(1.0, ComposableFunction.RINT.value(0.9), 1.0e-15); Assert.assertEquals(2.0, ComposableFunction.RINT.value(2.2), 1.0e-15); } @Test public void testSignum() throws Exception { Assert.assertEquals(1.0, ComposableFunction.SIGNUM.value(12.3), 1.0e-15); Assert.assertEquals(-1.0, ComposableFunction.SIGNUM.value(-6), 1.0e-15); } @Test public void testComposition() throws Exception { ComposableFunction abs = ComposableFunction.ABS; ComposableFunction acos = ComposableFunction.ACOS; ComposableFunction asin = ComposableFunction.ASIN; ComposableFunction atan = ComposableFunction.ATAN; ComposableFunction cbrt = ComposableFunction.CBRT; ComposableFunction ceil = ComposableFunction.CEIL; ComposableFunction cos = ComposableFunction.COS; ComposableFunction cosh = ComposableFunction.COSH; ComposableFunction exp = ComposableFunction.EXP; ComposableFunction expm1 = ComposableFunction.EXPM1; ComposableFunction floor = ComposableFunction.FLOOR; ComposableFunction id = ComposableFunction.IDENTITY; ComposableFunction log = ComposableFunction.LOG; ComposableFunction log10 = ComposableFunction.LOG10; ComposableFunction negate = ComposableFunction.NEGATE; ComposableFunction sin = ComposableFunction.SIN; ComposableFunction sinh = ComposableFunction.SINH; ComposableFunction sqrt = ComposableFunction.SQRT; ComposableFunction tan = ComposableFunction.TAN; ComposableFunction tanh = ComposableFunction.TANH; ComposableFunction ulp = ComposableFunction.ULP; ComposableFunction f1 = sqrt.of(abs.of(expm1.of(cbrt.of(tanh).of(id)))); for (double x = 0.1; x < 0.9; x += 0.01) { Assert.assertEquals(FastMath.sqrt(FastMath.abs(FastMath.expm1(FastMath.cbrt(FastMath.tanh(x))))), f1.value(x), 1.0e-15); } ComposableFunction f2 = cosh.of(sinh.of(tanh.of(ceil.postCompose(log.postCompose(cosh))))); for (double x = 0.1; x < 12.9; x += 1.0) { Assert.assertEquals(FastMath.cosh(FastMath.sinh(FastMath.tanh(FastMath.cosh(FastMath.log(FastMath.ceil(x)))))), f2.value(x), 1.0e-15); } ComposableFunction f3 = cos.of(sin.of(tan.of(acos.of(asin.of(log10.of(log.of(ulp))))))); for (double x = 1.0e16; x < 1.0e17; x += 1.0e16) { Assert.assertEquals(FastMath.cos(FastMath.sin(FastMath.tan(FastMath.acos(FastMath.asin(FastMath.log10(FastMath.log(FastMath.ulp(x)))))))), f3.value(x), 1.0e-15); } ComposableFunction f4 = atan.of(exp.of(negate.of(floor))); for (double x = 1.1; x < 10.2; x += 1.0) { Assert.assertEquals(FastMath.atan(FastMath.exp(-FastMath.floor(x))), f4.value(x), 1.0e-15); } } @Test public void testCombine() throws Exception { ComposableFunction f = ComposableFunction.COS.combine(ComposableFunction.ASIN, BinaryFunction.POW); for (double x = 0.1; x < 0.9; x += 0.01) { Assert.assertEquals(FastMath.pow(FastMath.cos(x), FastMath.asin(x)), f.value(x), 1.0e-15); } } @Test public void testSimpleCombination() throws Exception { ComposableFunction f1 = ComposableFunction.COS.add(3); ComposableFunction f2 = ComposableFunction.COS.add(ComposableFunction.SIN); ComposableFunction f3 = ComposableFunction.COS.subtract(ComposableFunction.SIN); ComposableFunction f4 = ComposableFunction.COS.multiply(ComposableFunction.SIN); ComposableFunction f5 = ComposableFunction.COS.multiply(5); ComposableFunction f6 = ComposableFunction.COS.divide(ComposableFunction.SIN); for (double x = 0.1; x < 0.9; x += 0.01) { Assert.assertEquals(FastMath.cos(x) + 3, f1.value(x), 1.0e-15); Assert.assertEquals(FastMath.cos(x) + FastMath.sin(x), f2.value(x), 1.0e-15); Assert.assertEquals(FastMath.cos(x) - FastMath.sin(x), f3.value(x), 1.0e-15); Assert.assertEquals(FastMath.cos(x) * FastMath.sin(x), f4.value(x), 1.0e-15); Assert.assertEquals(FastMath.cos(x) * 5, f5.value(x), 1.0e-15); Assert.assertEquals(FastMath.cos(x) / FastMath.sin(x), f6.value(x), 1.0e-15); } } @Test public void testCollector() throws Exception { ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2); Assert.assertEquals(30, f.asCollector().value(new double[] { 1, 2, 3, 4 }), 1.0e-15); Assert.assertEquals(33, f.asCollector(3).value(new double[] { 1, 2, 3, 4 }), 1.0e-15); Assert.assertEquals(-30, f.asCollector(BinaryFunction.SUBTRACT).value(new double[] { 1, 2, 3, 4 }), 1.0e-15); Assert.assertEquals(1152, f.asCollector(BinaryFunction.MULTIPLY, 2).value(new double[] { 1, 2, 3, 4 }), 1.0e-15); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/analysis/SinFunction.java100644 1750 1750 3366 11532241241 27330 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.util.FastMath; /** * Auxillary class for testing solvers. * * The function is extraordinarily well behaved around zero roots: it * has an inflection point there (second order derivative is zero), * which means linear approximation (Regula Falsi) will converge * quadratically. * * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class SinFunction implements DifferentiableUnivariateRealFunction { /* Evaluate sinus fuction. * @see org.apache.commons.math.UnivariateRealFunction#value(double) */ public double value(double x) { return FastMath.sin(x); } /* First derivative of sinus function */ public UnivariateRealFunction derivative() { return new UnivariateRealFunction() { public double value(double x) { return FastMath.cos(x); } }; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ComplexTest.java100644 1750 1750 106151 11532241242 27221 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import java.util.List; import junit.framework.TestCase; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class ComplexTest extends TestCase { private double inf = Double.POSITIVE_INFINITY; private double neginf = Double.NEGATIVE_INFINITY; private double nan = Double.NaN; private double pi = FastMath.PI; private Complex oneInf = new Complex(1, inf); private Complex oneNegInf = new Complex(1, neginf); private Complex infOne = new Complex(inf, 1); private Complex infZero = new Complex(inf, 0); private Complex infNaN = new Complex(inf, nan); private Complex infNegInf = new Complex(inf, neginf); private Complex infInf = new Complex(inf, inf); private Complex negInfInf = new Complex(neginf, inf); private Complex negInfZero = new Complex(neginf, 0); private Complex negInfOne = new Complex(neginf, 1); private Complex negInfNaN = new Complex(neginf, nan); private Complex negInfNegInf = new Complex(neginf, neginf); private Complex oneNaN = new Complex(1, nan); private Complex zeroInf = new Complex(0, inf); private Complex zeroNaN = new Complex(0, nan); private Complex nanInf = new Complex(nan, inf); private Complex nanNegInf = new Complex(nan, neginf); private Complex nanZero = new Complex(nan, 0); public void testConstructor() { Complex z = new Complex(3.0, 4.0); assertEquals(3.0, z.getReal(), 1.0e-5); assertEquals(4.0, z.getImaginary(), 1.0e-5); } public void testConstructorNaN() { Complex z = new Complex(3.0, Double.NaN); assertTrue(z.isNaN()); z = new Complex(nan, 4.0); assertTrue(z.isNaN()); z = new Complex(3.0, 4.0); assertFalse(z.isNaN()); } public void testAbs() { Complex z = new Complex(3.0, 4.0); assertEquals(5.0, z.abs(), 1.0e-5); } public void testAbsNaN() { assertTrue(Double.isNaN(Complex.NaN.abs())); Complex z = new Complex(inf, nan); assertTrue(Double.isNaN(z.abs())); } public void testAbsInfinite() { Complex z = new Complex(inf, 0); assertEquals(inf, z.abs(), 0); z = new Complex(0, neginf); assertEquals(inf, z.abs(), 0); z = new Complex(inf, neginf); assertEquals(inf, z.abs(), 0); } public void testAdd() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.add(y); assertEquals(8.0, z.getReal(), 1.0e-5); assertEquals(10.0, z.getImaginary(), 1.0e-5); } public void testAddNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.add(Complex.NaN); assertTrue(z.isNaN()); z = new Complex(1, nan); Complex w = x.add(z); assertEquals(w.getReal(), 4.0, 0); assertTrue(Double.isNaN(w.getImaginary())); } public void testAddInfinite() { Complex x = new Complex(1, 1); Complex z = new Complex(inf, 0); Complex w = x.add(z); assertEquals(w.getImaginary(), 1, 0); assertEquals(inf, w.getReal(), 0); x = new Complex(neginf, 0); assertTrue(Double.isNaN(x.add(z).getReal())); } public void testConjugate() { Complex x = new Complex(3.0, 4.0); Complex z = x.conjugate(); assertEquals(3.0, z.getReal(), 1.0e-5); assertEquals(-4.0, z.getImaginary(), 1.0e-5); } public void testConjugateNaN() { Complex z = Complex.NaN.conjugate(); assertTrue(z.isNaN()); } public void testConjugateInfiinite() { Complex z = new Complex(0, inf); assertEquals(neginf, z.conjugate().getImaginary(), 0); z = new Complex(0, neginf); assertEquals(inf, z.conjugate().getImaginary(), 0); } public void testDivide() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.divide(y); assertEquals(39.0 / 61.0, z.getReal(), 1.0e-5); assertEquals(2.0 / 61.0, z.getImaginary(), 1.0e-5); } public void testDivideReal() { Complex x = new Complex(2d, 3d); Complex y = new Complex(2d, 0d); assertEquals(new Complex(1d, 1.5), x.divide(y)); } public void testDivideImaginary() { Complex x = new Complex(2d, 3d); Complex y = new Complex(0d, 2d); assertEquals(new Complex(1.5d, -1d), x.divide(y)); } public void testDivideInfinite() { Complex x = new Complex(3, 4); Complex w = new Complex(neginf, inf); assertTrue(x.divide(w).equals(Complex.ZERO)); Complex z = w.divide(x); assertTrue(Double.isNaN(z.getReal())); assertEquals(inf, z.getImaginary(), 0); w = new Complex(inf, inf); z = w.divide(x); assertTrue(Double.isNaN(z.getImaginary())); assertEquals(inf, z.getReal(), 0); w = new Complex(1, inf); z = w.divide(w); assertTrue(Double.isNaN(z.getReal())); assertTrue(Double.isNaN(z.getImaginary())); } public void testDivideZero() { Complex x = new Complex(3.0, 4.0); Complex z = x.divide(Complex.ZERO); assertEquals(z, Complex.NaN); } public void testDivideNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.divide(Complex.NaN); assertTrue(z.isNaN()); } public void testDivideNaNInf() { Complex z = oneInf.divide(Complex.ONE); assertTrue(Double.isNaN(z.getReal())); assertEquals(inf, z.getImaginary(), 0); z = negInfNegInf.divide(oneNaN); assertTrue(Double.isNaN(z.getReal())); assertTrue(Double.isNaN(z.getImaginary())); z = negInfInf.divide(Complex.ONE); assertTrue(Double.isNaN(z.getReal())); assertTrue(Double.isNaN(z.getImaginary())); } public void testMultiply() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.multiply(y); assertEquals(-9.0, z.getReal(), 1.0e-5); assertEquals(38.0, z.getImaginary(), 1.0e-5); } public void testMultiplyNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.multiply(Complex.NaN); assertTrue(z.isNaN()); } public void testMultiplyNaNInf() { Complex z = new Complex(1,1); Complex w = z.multiply(infOne); assertEquals(w.getReal(), inf, 0); assertEquals(w.getImaginary(), inf, 0); // [MATH-164] assertTrue(new Complex( 1,0).multiply(infInf).equals(Complex.INF)); assertTrue(new Complex(-1,0).multiply(infInf).equals(Complex.INF)); assertTrue(new Complex( 1,0).multiply(negInfZero).equals(Complex.INF)); w = oneInf.multiply(oneNegInf); assertEquals(w.getReal(), inf, 0); assertEquals(w.getImaginary(), inf, 0); w = negInfNegInf.multiply(oneNaN); assertTrue(Double.isNaN(w.getReal())); assertTrue(Double.isNaN(w.getImaginary())); } public void testScalarMultiply() { Complex x = new Complex(3.0, 4.0); double y = 2.0; Complex z = x.multiply(y); assertEquals(6.0, z.getReal(), 1.0e-5); assertEquals(8.0, z.getImaginary(), 1.0e-5); } public void testScalarMultiplyNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.multiply(Double.NaN); assertTrue(z.isNaN()); } public void testScalarMultiplyInf() { Complex z = new Complex(1,1); Complex w = z.multiply(Double.POSITIVE_INFINITY); assertEquals(w.getReal(), inf, 0); assertEquals(w.getImaginary(), inf, 0); w = z.multiply(Double.NEGATIVE_INFINITY); assertEquals(w.getReal(), inf, 0); assertEquals(w.getImaginary(), inf, 0); } public void testNegate() { Complex x = new Complex(3.0, 4.0); Complex z = x.negate(); assertEquals(-3.0, z.getReal(), 1.0e-5); assertEquals(-4.0, z.getImaginary(), 1.0e-5); } public void testNegateNaN() { Complex z = Complex.NaN.negate(); assertTrue(z.isNaN()); } public void testSubtract() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.subtract(y); assertEquals(-2.0, z.getReal(), 1.0e-5); assertEquals(-2.0, z.getImaginary(), 1.0e-5); } public void testSubtractNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.subtract(Complex.NaN); assertTrue(z.isNaN()); } public void testEqualsNull() { Complex x = new Complex(3.0, 4.0); assertFalse(x.equals(null)); } public void testEqualsClass() { Complex x = new Complex(3.0, 4.0); assertFalse(x.equals(this)); } public void testEqualsSame() { Complex x = new Complex(3.0, 4.0); assertTrue(x.equals(x)); } public void testEqualsTrue() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(3.0, 4.0); assertTrue(x.equals(y)); } public void testEqualsRealDifference() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0 + Double.MIN_VALUE, 0.0); assertFalse(x.equals(y)); } public void testEqualsImaginaryDifference() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE); assertFalse(x.equals(y)); } public void testEqualsNaN() { Complex realNaN = new Complex(Double.NaN, 0.0); Complex imaginaryNaN = new Complex(0.0, Double.NaN); Complex complexNaN = Complex.NaN; assertTrue(realNaN.equals(imaginaryNaN)); assertTrue(imaginaryNaN.equals(complexNaN)); assertTrue(realNaN.equals(complexNaN)); } public void testHashCode() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE); assertFalse(x.hashCode()==y.hashCode()); y = new Complex(0.0 + Double.MIN_VALUE, 0.0); assertFalse(x.hashCode()==y.hashCode()); Complex realNaN = new Complex(Double.NaN, 0.0); Complex imaginaryNaN = new Complex(0.0, Double.NaN); assertEquals(realNaN.hashCode(), imaginaryNaN.hashCode()); assertEquals(imaginaryNaN.hashCode(), Complex.NaN.hashCode()); } public void testAcos() { Complex z = new Complex(3, 4); Complex expected = new Complex(0.936812, -2.30551); TestUtils.assertEquals(expected, z.acos(), 1.0e-5); TestUtils.assertEquals(new Complex(FastMath.acos(0), 0), Complex.ZERO.acos(), 1.0e-12); } public void testAcosInf() { TestUtils.assertSame(Complex.NaN, oneInf.acos()); TestUtils.assertSame(Complex.NaN, oneNegInf.acos()); TestUtils.assertSame(Complex.NaN, infOne.acos()); TestUtils.assertSame(Complex.NaN, negInfOne.acos()); TestUtils.assertSame(Complex.NaN, infInf.acos()); TestUtils.assertSame(Complex.NaN, infNegInf.acos()); TestUtils.assertSame(Complex.NaN, negInfInf.acos()); TestUtils.assertSame(Complex.NaN, negInfNegInf.acos()); } public void testAcosNaN() { assertTrue(Complex.NaN.acos().isNaN()); } public void testAsin() { Complex z = new Complex(3, 4); Complex expected = new Complex(0.633984, 2.30551); TestUtils.assertEquals(expected, z.asin(), 1.0e-5); } public void testAsinNaN() { assertTrue(Complex.NaN.asin().isNaN()); } public void testAsinInf() { TestUtils.assertSame(Complex.NaN, oneInf.asin()); TestUtils.assertSame(Complex.NaN, oneNegInf.asin()); TestUtils.assertSame(Complex.NaN, infOne.asin()); TestUtils.assertSame(Complex.NaN, negInfOne.asin()); TestUtils.assertSame(Complex.NaN, infInf.asin()); TestUtils.assertSame(Complex.NaN, infNegInf.asin()); TestUtils.assertSame(Complex.NaN, negInfInf.asin()); TestUtils.assertSame(Complex.NaN, negInfNegInf.asin()); } public void testAtan() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.44831, 0.158997); TestUtils.assertEquals(expected, z.atan(), 1.0e-5); } public void testAtanInf() { TestUtils.assertSame(Complex.NaN, oneInf.atan()); TestUtils.assertSame(Complex.NaN, oneNegInf.atan()); TestUtils.assertSame(Complex.NaN, infOne.atan()); TestUtils.assertSame(Complex.NaN, negInfOne.atan()); TestUtils.assertSame(Complex.NaN, infInf.atan()); TestUtils.assertSame(Complex.NaN, infNegInf.atan()); TestUtils.assertSame(Complex.NaN, negInfInf.atan()); TestUtils.assertSame(Complex.NaN, negInfNegInf.atan()); } public void testAtanNaN() { assertTrue(Complex.NaN.atan().isNaN()); assertTrue(Complex.I.atan().isNaN()); } public void testCos() { Complex z = new Complex(3, 4); Complex expected = new Complex(-27.03495, -3.851153); TestUtils.assertEquals(expected, z.cos(), 1.0e-5); } public void testCosNaN() { assertTrue(Complex.NaN.cos().isNaN()); } public void testCosInf() { TestUtils.assertSame(infNegInf, oneInf.cos()); TestUtils.assertSame(infInf, oneNegInf.cos()); TestUtils.assertSame(Complex.NaN, infOne.cos()); TestUtils.assertSame(Complex.NaN, negInfOne.cos()); TestUtils.assertSame(Complex.NaN, infInf.cos()); TestUtils.assertSame(Complex.NaN, infNegInf.cos()); TestUtils.assertSame(Complex.NaN, negInfInf.cos()); TestUtils.assertSame(Complex.NaN, negInfNegInf.cos()); } public void testCosh() { Complex z = new Complex(3, 4); Complex expected = new Complex(-6.58066, -7.58155); TestUtils.assertEquals(expected, z.cosh(), 1.0e-5); } public void testCoshNaN() { assertTrue(Complex.NaN.cosh().isNaN()); } public void testCoshInf() { TestUtils.assertSame(Complex.NaN, oneInf.cosh()); TestUtils.assertSame(Complex.NaN, oneNegInf.cosh()); TestUtils.assertSame(infInf, infOne.cosh()); TestUtils.assertSame(infNegInf, negInfOne.cosh()); TestUtils.assertSame(Complex.NaN, infInf.cosh()); TestUtils.assertSame(Complex.NaN, infNegInf.cosh()); TestUtils.assertSame(Complex.NaN, negInfInf.cosh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.cosh()); } public void testExp() { Complex z = new Complex(3, 4); Complex expected = new Complex(-13.12878, -15.20078); TestUtils.assertEquals(expected, z.exp(), 1.0e-5); TestUtils.assertEquals(Complex.ONE, Complex.ZERO.exp(), 10e-12); Complex iPi = Complex.I.multiply(new Complex(pi,0)); TestUtils.assertEquals(Complex.ONE.negate(), iPi.exp(), 10e-12); } public void testExpNaN() { assertTrue(Complex.NaN.exp().isNaN()); } public void testExpInf() { TestUtils.assertSame(Complex.NaN, oneInf.exp()); TestUtils.assertSame(Complex.NaN, oneNegInf.exp()); TestUtils.assertSame(infInf, infOne.exp()); TestUtils.assertSame(Complex.ZERO, negInfOne.exp()); TestUtils.assertSame(Complex.NaN, infInf.exp()); TestUtils.assertSame(Complex.NaN, infNegInf.exp()); TestUtils.assertSame(Complex.NaN, negInfInf.exp()); TestUtils.assertSame(Complex.NaN, negInfNegInf.exp()); } public void testLog() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.60944, 0.927295); TestUtils.assertEquals(expected, z.log(), 1.0e-5); } public void testLogNaN() { assertTrue(Complex.NaN.log().isNaN()); } public void testLogInf() { TestUtils.assertEquals(new Complex(inf, pi / 2), oneInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, -pi / 2), oneNegInf.log(), 10e-12); TestUtils.assertEquals(infZero, infOne.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, pi), negInfOne.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, pi / 4), infInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, -pi / 4), infNegInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, 3d * pi / 4), negInfInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, - 3d * pi / 4), negInfNegInf.log(), 10e-12); } public void testLogZero() { TestUtils.assertSame(negInfZero, Complex.ZERO.log()); } public void testPow() { Complex x = new Complex(3, 4); Complex y = new Complex(5, 6); Complex expected = new Complex(-1.860893, 11.83677); TestUtils.assertEquals(expected, x.pow(y), 1.0e-5); } public void testPowNaNBase() { Complex x = new Complex(3, 4); assertTrue(Complex.NaN.pow(x).isNaN()); } public void testPowNaNExponent() { Complex x = new Complex(3, 4); assertTrue(x.pow(Complex.NaN).isNaN()); } public void testPowInf() { TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneNegInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infOne)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infOne.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfOne.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,infInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(infInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(infInf)); } public void testPowZero() { TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.ZERO)); TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.I)); TestUtils.assertEquals(Complex.ONE, Complex.ONE.pow(Complex.ZERO), 10e-12); TestUtils.assertEquals(Complex.ONE, Complex.I.pow(Complex.ZERO), 10e-12); TestUtils.assertEquals(Complex.ONE, new Complex(-1, 3).pow(Complex.ZERO), 10e-12); } public void testpowNull() { try { Complex.ONE.pow(null); fail("Expecting NullPointerException"); } catch (NullPointerException ex) { // expected } } public void testSin() { Complex z = new Complex(3, 4); Complex expected = new Complex(3.853738, -27.01681); TestUtils.assertEquals(expected, z.sin(), 1.0e-5); } public void testSinInf() { TestUtils.assertSame(infInf, oneInf.sin()); TestUtils.assertSame(infNegInf, oneNegInf.sin()); TestUtils.assertSame(Complex.NaN, infOne.sin()); TestUtils.assertSame(Complex.NaN, negInfOne.sin()); TestUtils.assertSame(Complex.NaN, infInf.sin()); TestUtils.assertSame(Complex.NaN, infNegInf.sin()); TestUtils.assertSame(Complex.NaN, negInfInf.sin()); TestUtils.assertSame(Complex.NaN, negInfNegInf.sin()); } public void testSinNaN() { assertTrue(Complex.NaN.sin().isNaN()); } public void testSinh() { Complex z = new Complex(3, 4); Complex expected = new Complex(-6.54812, -7.61923); TestUtils.assertEquals(expected, z.sinh(), 1.0e-5); } public void testSinhNaN() { assertTrue(Complex.NaN.sinh().isNaN()); } public void testSinhInf() { TestUtils.assertSame(Complex.NaN, oneInf.sinh()); TestUtils.assertSame(Complex.NaN, oneNegInf.sinh()); TestUtils.assertSame(infInf, infOne.sinh()); TestUtils.assertSame(negInfInf, negInfOne.sinh()); TestUtils.assertSame(Complex.NaN, infInf.sinh()); TestUtils.assertSame(Complex.NaN, infNegInf.sinh()); TestUtils.assertSame(Complex.NaN, negInfInf.sinh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.sinh()); } public void testSqrtRealPositive() { Complex z = new Complex(3, 4); Complex expected = new Complex(2, 1); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } public void testSqrtRealZero() { Complex z = new Complex(0.0, 4); Complex expected = new Complex(1.41421, 1.41421); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } public void testSqrtRealNegative() { Complex z = new Complex(-3.0, 4); Complex expected = new Complex(1, 2); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } public void testSqrtImaginaryZero() { Complex z = new Complex(-3.0, 0.0); Complex expected = new Complex(0.0, 1.73205); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } public void testSqrtImaginaryNegative() { Complex z = new Complex(-3.0, -4.0); Complex expected = new Complex(1.0, -2.0); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } public void testSqrtPolar() { double r = 1; for (int i = 0; i < 5; i++) { r += i; double theta = 0; for (int j =0; j < 11; j++) { theta += pi /12; Complex z = ComplexUtils.polar2Complex(r, theta); Complex sqrtz = ComplexUtils.polar2Complex(FastMath.sqrt(r), theta / 2); TestUtils.assertEquals(sqrtz, z.sqrt(), 10e-12); } } } public void testSqrtNaN() { assertTrue(Complex.NaN.sqrt().isNaN()); } public void testSqrtInf() { TestUtils.assertSame(infNaN, oneInf.sqrt()); TestUtils.assertSame(infNaN, oneNegInf.sqrt()); TestUtils.assertSame(infZero, infOne.sqrt()); TestUtils.assertSame(zeroInf, negInfOne.sqrt()); TestUtils.assertSame(infNaN, infInf.sqrt()); TestUtils.assertSame(infNaN, infNegInf.sqrt()); TestUtils.assertSame(nanInf, negInfInf.sqrt()); TestUtils.assertSame(nanNegInf, negInfNegInf.sqrt()); } public void testSqrt1z() { Complex z = new Complex(3, 4); Complex expected = new Complex(4.08033, -2.94094); TestUtils.assertEquals(expected, z.sqrt1z(), 1.0e-5); } public void testSqrt1zNaN() { assertTrue(Complex.NaN.sqrt1z().isNaN()); } public void testTan() { Complex z = new Complex(3, 4); Complex expected = new Complex(-0.000187346, 0.999356); TestUtils.assertEquals(expected, z.tan(), 1.0e-5); } public void testTanNaN() { assertTrue(Complex.NaN.tan().isNaN()); } public void testTanInf() { TestUtils.assertSame(zeroNaN, oneInf.tan()); TestUtils.assertSame(zeroNaN, oneNegInf.tan()); TestUtils.assertSame(Complex.NaN, infOne.tan()); TestUtils.assertSame(Complex.NaN, negInfOne.tan()); TestUtils.assertSame(Complex.NaN, infInf.tan()); TestUtils.assertSame(Complex.NaN, infNegInf.tan()); TestUtils.assertSame(Complex.NaN, negInfInf.tan()); TestUtils.assertSame(Complex.NaN, negInfNegInf.tan()); } public void testTanCritical() { TestUtils.assertSame(infNaN, new Complex(pi/2, 0).tan()); TestUtils.assertSame(negInfNaN, new Complex(-pi/2, 0).tan()); } public void testTanh() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.00071, 0.00490826); TestUtils.assertEquals(expected, z.tanh(), 1.0e-5); } public void testTanhNaN() { assertTrue(Complex.NaN.tanh().isNaN()); } public void testTanhInf() { TestUtils.assertSame(Complex.NaN, oneInf.tanh()); TestUtils.assertSame(Complex.NaN, oneNegInf.tanh()); TestUtils.assertSame(nanZero, infOne.tanh()); TestUtils.assertSame(nanZero, negInfOne.tanh()); TestUtils.assertSame(Complex.NaN, infInf.tanh()); TestUtils.assertSame(Complex.NaN, infNegInf.tanh()); TestUtils.assertSame(Complex.NaN, negInfInf.tanh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.tanh()); } public void testTanhCritical() { TestUtils.assertSame(nanInf, new Complex(0, pi/2).tanh()); } /** test issue MATH-221 */ public void testMath221() { assertEquals(new Complex(0,-1), new Complex(0,1).multiply(new Complex(-1,0))); } /** * Test: computing third roots of z. *

                       * 
                       * z = -2 + 2 * i
                       *   => z_0 =  1      +          i
                       *   => z_1 = -1.3660 + 0.3660 * i
                       *   => z_2 =  0.3660 - 1.3660 * i
                       * 
                       * 
                  */ public void testNthRoot_normal_thirdRoot() { // The complex number we want to compute all third-roots for. Complex z = new Complex(-2,2); // The List holding all third roots Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]); // Returned Collection must not be empty! assertEquals(3, thirdRootsOfZ.length); // test z_0 assertEquals(1.0, thirdRootsOfZ[0].getReal(), 1.0e-5); assertEquals(1.0, thirdRootsOfZ[0].getImaginary(), 1.0e-5); // test z_1 assertEquals(-1.3660254037844386, thirdRootsOfZ[1].getReal(), 1.0e-5); assertEquals(0.36602540378443843, thirdRootsOfZ[1].getImaginary(), 1.0e-5); // test z_2 assertEquals(0.366025403784439, thirdRootsOfZ[2].getReal(), 1.0e-5); assertEquals(-1.3660254037844384, thirdRootsOfZ[2].getImaginary(), 1.0e-5); } /** * Test: computing fourth roots of z. *
                       * 
                       * z = 5 - 2 * i
                       *   => z_0 =  1.5164 - 0.1446 * i
                       *   => z_1 =  0.1446 + 1.5164 * i
                       *   => z_2 = -1.5164 + 0.1446 * i
                       *   => z_3 = -1.5164 - 0.1446 * i
                       * 
                       * 
                  */ public void testNthRoot_normal_fourthRoot() { // The complex number we want to compute all third-roots for. Complex z = new Complex(5,-2); // The List holding all fourth roots Complex[] fourthRootsOfZ = z.nthRoot(4).toArray(new Complex[0]); // Returned Collection must not be empty! assertEquals(4, fourthRootsOfZ.length); // test z_0 assertEquals(1.5164629308487783, fourthRootsOfZ[0].getReal(), 1.0e-5); assertEquals(-0.14469266210702247, fourthRootsOfZ[0].getImaginary(), 1.0e-5); // test z_1 assertEquals(0.14469266210702256, fourthRootsOfZ[1].getReal(), 1.0e-5); assertEquals(1.5164629308487783, fourthRootsOfZ[1].getImaginary(), 1.0e-5); // test z_2 assertEquals(-1.5164629308487783, fourthRootsOfZ[2].getReal(), 1.0e-5); assertEquals(0.14469266210702267, fourthRootsOfZ[2].getImaginary(), 1.0e-5); // test z_3 assertEquals(-0.14469266210702275, fourthRootsOfZ[3].getReal(), 1.0e-5); assertEquals(-1.5164629308487783, fourthRootsOfZ[3].getImaginary(), 1.0e-5); } /** * Test: computing third roots of z. *
                       * 
                       * z = 8
                       *   => z_0 =  2
                       *   => z_1 = -1 + 1.73205 * i
                       *   => z_2 = -1 - 1.73205 * i
                       * 
                       * 
                  */ public void testNthRoot_cornercase_thirdRoot_imaginaryPartEmpty() { // The number 8 has three third roots. One we all already know is the number 2. // But there are two more complex roots. Complex z = new Complex(8,0); // The List holding all third roots Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]); // Returned Collection must not be empty! assertEquals(3, thirdRootsOfZ.length); // test z_0 assertEquals(2.0, thirdRootsOfZ[0].getReal(), 1.0e-5); assertEquals(0.0, thirdRootsOfZ[0].getImaginary(), 1.0e-5); // test z_1 assertEquals(-1.0, thirdRootsOfZ[1].getReal(), 1.0e-5); assertEquals(1.7320508075688774, thirdRootsOfZ[1].getImaginary(), 1.0e-5); // test z_2 assertEquals(-1.0, thirdRootsOfZ[2].getReal(), 1.0e-5); assertEquals(-1.732050807568877, thirdRootsOfZ[2].getImaginary(), 1.0e-5); } /** * Test: computing third roots of z with real part 0. *
                       * 
                       * z = 2 * i
                       *   => z_0 =  1.0911 + 0.6299 * i
                       *   => z_1 = -1.0911 + 0.6299 * i
                       *   => z_2 = -2.3144 - 1.2599 * i
                       * 
                       * 
                  */ public void testNthRoot_cornercase_thirdRoot_realPartZero() { // complex number with only imaginary part Complex z = new Complex(0,2); // The List holding all third roots Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]); // Returned Collection must not be empty! assertEquals(3, thirdRootsOfZ.length); // test z_0 assertEquals(1.0911236359717216, thirdRootsOfZ[0].getReal(), 1.0e-5); assertEquals(0.6299605249474365, thirdRootsOfZ[0].getImaginary(), 1.0e-5); // test z_1 assertEquals(-1.0911236359717216, thirdRootsOfZ[1].getReal(), 1.0e-5); assertEquals(0.6299605249474365, thirdRootsOfZ[1].getImaginary(), 1.0e-5); // test z_2 assertEquals(-2.3144374213981936E-16, thirdRootsOfZ[2].getReal(), 1.0e-5); assertEquals(-1.2599210498948732, thirdRootsOfZ[2].getImaginary(), 1.0e-5); } /** * Test cornercases with NaN and Infinity. */ public void testNthRoot_cornercase_NAN_Inf() { // NaN + finite -> NaN List roots = oneNaN.nthRoot(3); assertEquals(1,roots.size()); assertEquals(Complex.NaN, roots.get(0)); roots = nanZero.nthRoot(3); assertEquals(1,roots.size()); assertEquals(Complex.NaN, roots.get(0)); // NaN + infinite -> NaN roots = nanInf.nthRoot(3); assertEquals(1,roots.size()); assertEquals(Complex.NaN, roots.get(0)); // finite + infinite -> Inf roots = oneInf.nthRoot(3); assertEquals(1,roots.size()); assertEquals(Complex.INF, roots.get(0)); // infinite + infinite -> Inf roots = negInfInf.nthRoot(3); assertEquals(1,roots.size()); assertEquals(Complex.INF, roots.get(0)); } /** * Test standard values */ public void testGetArgument() { Complex z = new Complex(1, 0); assertEquals(0.0, z.getArgument(), 1.0e-12); z = new Complex(1, 1); assertEquals(FastMath.PI/4, z.getArgument(), 1.0e-12); z = new Complex(0, 1); assertEquals(FastMath.PI/2, z.getArgument(), 1.0e-12); z = new Complex(-1, 1); assertEquals(3 * FastMath.PI/4, z.getArgument(), 1.0e-12); z = new Complex(-1, 0); assertEquals(FastMath.PI, z.getArgument(), 1.0e-12); z = new Complex(-1, -1); assertEquals(-3 * FastMath.PI/4, z.getArgument(), 1.0e-12); z = new Complex(0, -1); assertEquals(-FastMath.PI/2, z.getArgument(), 1.0e-12); z = new Complex(1, -1); assertEquals(-FastMath.PI/4, z.getArgument(), 1.0e-12); } /** * Verify atan2-style handling of infinite parts */ public void testGetArgumentInf() { assertEquals(FastMath.PI/4, infInf.getArgument(), 1.0e-12); assertEquals(FastMath.PI/2, oneInf.getArgument(), 1.0e-12); assertEquals(0.0, infOne.getArgument(), 1.0e-12); assertEquals(FastMath.PI/2, zeroInf.getArgument(), 1.0e-12); assertEquals(0.0, infZero.getArgument(), 1.0e-12); assertEquals(FastMath.PI, negInfOne.getArgument(), 1.0e-12); assertEquals(-3.0*FastMath.PI/4, negInfNegInf.getArgument(), 1.0e-12); assertEquals(-FastMath.PI/2, oneNegInf.getArgument(), 1.0e-12); } /** * Verify that either part NaN results in NaN */ public void testGetArgumentNaN() { assertEquals(nan, nanZero.getArgument()); assertEquals(nan, zeroNaN.getArgument()); assertEquals(nan, Complex.NaN.getArgument()); } public void testSerial() { Complex z = new Complex(3.0, 4.0); assertEquals(z, TestUtils.serializeAndRecover(z)); Complex ncmplx = (Complex)TestUtils.serializeAndRecover(oneNaN); assertEquals(nanZero, ncmplx); assertTrue(ncmplx.isNaN()); Complex infcmplx = (Complex)TestUtils.serializeAndRecover(infInf); assertEquals(infInf, infcmplx); assertTrue(infcmplx.isInfinite()); TestComplex tz = new TestComplex(3.0, 4.0); assertEquals(tz, TestUtils.serializeAndRecover(tz)); TestComplex ntcmplx = (TestComplex)TestUtils.serializeAndRecover(new TestComplex(oneNaN)); assertEquals(nanZero, ntcmplx); assertTrue(ntcmplx.isNaN()); TestComplex inftcmplx = (TestComplex)TestUtils.serializeAndRecover(new TestComplex(infInf)); assertEquals(infInf, inftcmplx); assertTrue(inftcmplx.isInfinite()); } /** * Class to test extending Complex */ public static class TestComplex extends Complex { /** * Serialization identifier. */ private static final long serialVersionUID = 3268726724160389237L; public TestComplex(double real, double imaginary) { super(real, imaginary); } public TestComplex(Complex other){ this(other.getReal(), other.getImaginary()); } @Override protected TestComplex createComplex(double real, double imaginary){ return new TestComplex(real, imaginary); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/FrenchComplexFormatTest.java100644 1750 1750 2136 11532241242 31456 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.util.Locale; public class FrenchComplexFormatTest extends ComplexFormatAbstractTest { @Override protected char getDecimalCharacter() { return ','; } @Override protected Locale getLocale() { return Locale.FRENCH; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ComplexUtilsTest.java100644 1750 1750 10220 11532241242 30211 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class ComplexUtilsTest extends TestCase { private double inf = Double.POSITIVE_INFINITY; private double negInf = Double.NEGATIVE_INFINITY; private double nan = Double.NaN; private double pi = FastMath.PI; private Complex negInfInf = new Complex(negInf, inf); private Complex infNegInf = new Complex(inf, negInf); private Complex infInf = new Complex(inf, inf); private Complex negInfNegInf = new Complex(negInf, negInf); private Complex infNaN = new Complex(inf, nan); public void testPolar2Complex() { TestUtils.assertEquals(Complex.ONE, ComplexUtils.polar2Complex(1, 0), 10e-12); TestUtils.assertEquals(Complex.ZERO, ComplexUtils.polar2Complex(0, 1), 10e-12); TestUtils.assertEquals(Complex.ZERO, ComplexUtils.polar2Complex(0, -1), 10e-12); TestUtils.assertEquals(Complex.I, ComplexUtils.polar2Complex(1, pi/2), 10e-12); TestUtils.assertEquals(Complex.I.negate(), ComplexUtils.polar2Complex(1, -pi/2), 10e-12); double r = 0; for (int i = 0; i < 5; i++) { r += i; double theta = 0; for (int j =0; j < 20; j++) { theta += pi / 6; TestUtils.assertEquals(altPolar(r, theta), ComplexUtils.polar2Complex(r, theta), 10e-12); } theta = -2 * pi; for (int j =0; j < 20; j++) { theta -= pi / 6; TestUtils.assertEquals(altPolar(r, theta), ComplexUtils.polar2Complex(r, theta), 10e-12); } } } protected Complex altPolar(double r, double theta) { return Complex.I.multiply(new Complex(theta, 0)).exp().multiply(new Complex(r, 0)); } public void testPolar2ComplexIllegalModulus() { try { ComplexUtils.polar2Complex(-1, 0); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testPolar2ComplexNaN() { TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(nan, 1)); TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, nan)); TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(nan, nan)); } public void testPolar2ComplexInf() { TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, inf)); TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, negInf)); TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(inf, inf)); TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(inf, negInf)); TestUtils.assertSame(infInf, ComplexUtils.polar2Complex(inf, pi/4)); TestUtils.assertSame(infNaN, ComplexUtils.polar2Complex(inf, 0)); TestUtils.assertSame(infNegInf, ComplexUtils.polar2Complex(inf, -pi/4)); TestUtils.assertSame(negInfInf, ComplexUtils.polar2Complex(inf, 3*pi/4)); TestUtils.assertSame(negInfNegInf, ComplexUtils.polar2Complex(inf, 5*pi/4)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ComplexFormatTest.java100644 1750 1750 2123 11532241242 30324 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.util.Locale; public class ComplexFormatTest extends ComplexFormatAbstractTest { @Override protected char getDecimalCharacter() { return '.'; } @Override protected Locale getLocale() { return Locale.US; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ComplexFormatAbstractTest.java100644 1750 1750 30513 11532241242 32034 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.util.CompositeFormat; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public abstract class ComplexFormatAbstractTest extends TestCase { CompositeFormat complexFormat = null; ComplexFormat complexFormatJ = null; protected abstract Locale getLocale(); protected abstract char getDecimalCharacter(); @Override protected void setUp() throws Exception { complexFormat = ComplexFormat.getInstance(getLocale()); complexFormatJ = ComplexFormat.getInstance(getLocale()); complexFormatJ.setImaginaryCharacter("j"); } public void testSimpleNoDecimals() { Complex c = new Complex(1, 1); String expected = "1 + 1i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testSimpleWithDecimals() { Complex c = new Complex(1.23, 1.43); String expected = "1" + getDecimalCharacter() + "23 + 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testSimpleWithDecimalsTrunc() { Complex c = new Complex(1.2323, 1.4343); String expected = "1" + getDecimalCharacter() + "23 + 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testNegativeReal() { Complex c = new Complex(-1.2323, 1.4343); String expected = "-1" + getDecimalCharacter() + "23 + 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testNegativeImaginary() { Complex c = new Complex(1.2323, -1.4343); String expected = "1" + getDecimalCharacter() + "23 - 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testNegativeBoth() { Complex c = new Complex(-1.2323, -1.4343); String expected = "-1" + getDecimalCharacter() + "23 - 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testZeroReal() { Complex c = new Complex(0.0, -1.4343); String expected = "0 - 1" + getDecimalCharacter() + "43i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testZeroImaginary() { Complex c = new Complex(30.233, 0); String expected = "30" + getDecimalCharacter() + "23"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testDifferentImaginaryChar() { Complex c = new Complex(1, 1); String expected = "1 + 1j"; String actual = complexFormatJ.format(c); assertEquals(expected, actual); } public void testStaticFormatComplex() { Locale defaultLocal = Locale.getDefault(); Locale.setDefault(getLocale()); Complex c = new Complex(232.222, -342.33); String expected = "232" + getDecimalCharacter() + "22 - 342" + getDecimalCharacter() + "33i"; String actual = ComplexFormat.formatComplex(c); assertEquals(expected, actual); Locale.setDefault(defaultLocal); } public void testNan() { Complex c = new Complex(Double.NaN, Double.NaN); String expected = "(NaN) + (NaN)i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testPositiveInfinity() { Complex c = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); String expected = "(Infinity) + (Infinity)i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testNegativeInfinity() { Complex c = new Complex(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); String expected = "(-Infinity) - (Infinity)i"; String actual = complexFormat.format(c); assertEquals(expected, actual); } public void testParseSimpleNoDecimals() { String source = "1 + 1i"; Complex expected = new Complex(1, 1); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseSimpleWithDecimals() { String source = "1" + getDecimalCharacter() + "23 + 1" + getDecimalCharacter() + "43i"; Complex expected = new Complex(1.23, 1.43); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseSimpleWithDecimalsTrunc() { String source = "1" + getDecimalCharacter() + "2323 + 1" + getDecimalCharacter() + "4343i"; Complex expected = new Complex(1.2323, 1.4343); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeReal() { String source = "-1" + getDecimalCharacter() + "2323 + 1" + getDecimalCharacter() + "4343i"; Complex expected = new Complex(-1.2323, 1.4343); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeImaginary() { String source = "1" + getDecimalCharacter() + "2323 - 1" + getDecimalCharacter() + "4343i"; Complex expected = new Complex(1.2323, -1.4343); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNegativeBoth() { String source = "-1" + getDecimalCharacter() + "2323 - 1" + getDecimalCharacter() + "4343i"; Complex expected = new Complex(-1.2323, -1.4343); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseZeroReal() { String source = "0" + getDecimalCharacter() + "0 - 1" + getDecimalCharacter() + "4343i"; Complex expected = new Complex(0.0, -1.4343); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseZeroImaginary() { String source = "-1" + getDecimalCharacter() + "2323"; Complex expected = new Complex(-1.2323, 0); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseDifferentImaginaryChar() { String source = "-1" + getDecimalCharacter() + "2323 - 1" + getDecimalCharacter() + "4343j"; Complex expected = new Complex(-1.2323, -1.4343); try { Complex actual = (Complex)complexFormatJ.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseNan() { String source = "(NaN) + (NaN)i"; Complex expected = new Complex(Double.NaN, Double.NaN); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParsePositiveInfinity() { String source = "(Infinity) + (Infinity)i"; Complex expected = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testPaseNegativeInfinity() { String source = "(-Infinity) - (Infinity)i"; Complex expected = new Complex(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); try { Complex actual = (Complex)complexFormat.parseObject(source); assertEquals(expected, actual); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testConstructorSingleFormat() { NumberFormat nf = NumberFormat.getInstance(); ComplexFormat cf = new ComplexFormat(nf); assertNotNull(cf); assertEquals(nf, cf.getRealFormat()); } public void testGetImaginaryFormat() { NumberFormat nf = NumberFormat.getInstance(); ComplexFormat cf = new ComplexFormat(); assertNotSame(nf, cf.getImaginaryFormat()); cf.setImaginaryFormat(nf); assertSame(nf, cf.getImaginaryFormat()); } public void testSetImaginaryFormatNull() { try { ComplexFormat cf = new ComplexFormat(); cf.setImaginaryFormat(null); fail(); } catch (IllegalArgumentException ex) { // success } } public void testSetRealFormatNull() { try { ComplexFormat cf = new ComplexFormat(); cf.setRealFormat(null); fail(); } catch (IllegalArgumentException ex) { // success } } public void testGetRealFormat() { NumberFormat nf = NumberFormat.getInstance(); ComplexFormat cf = new ComplexFormat(); assertNotSame(nf, cf.getRealFormat()); cf.setRealFormat(nf); assertSame(nf, cf.getRealFormat()); } public void testSetImaginaryCharacterNull() { try { ComplexFormat cf = new ComplexFormat(); cf.setImaginaryCharacter(null); fail(); } catch (IllegalArgumentException ex) { // success } } public void testSetImaginaryCharacterEmpty() { try { ComplexFormat cf = new ComplexFormat(); cf.setImaginaryCharacter(""); fail(); } catch (IllegalArgumentException ex) { // success } } public void testFormatNumber() { CompositeFormat cf = ComplexFormat.getInstance(getLocale()); Double pi = Double.valueOf(FastMath.PI); String text = cf.format(pi); assertEquals("3" + getDecimalCharacter() + "14", text); } public void testFormatObject() { try { CompositeFormat cf = new ComplexFormat(); Object object = new Object(); cf.format(object); fail(); } catch (IllegalArgumentException ex) { // success } } public void testForgottenImaginaryCharacter() { ParsePosition pos = new ParsePosition(0); assertNull(new ComplexFormat().parse("1 + 1", pos)); assertEquals(5, pos.getErrorIndex()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/complex/ComplexFieldTest.java100644 1750 1750 2761 11532241242 30127 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.TestUtils; import org.junit.Test; public class ComplexFieldTest { @Test public void testZero() { assertEquals(Complex.ZERO, ComplexField.getInstance().getZero()); } @Test public void testOne() { assertEquals(Complex.ONE, ComplexField.getInstance().getOne()); } @Test public void testSerial() { // deserializing the singleton should give the singleton itself back ComplexField field = ComplexField.getInstance(); assertTrue(field == TestUtils.serializeAndRecover(field)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/BigFractionFormatTest.java100644 1750 1750 24415 11532241242 31272 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.math.BigDecimal; import java.math.BigInteger; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public class BigFractionFormatTest extends TestCase { BigFractionFormat properFormat = null; BigFractionFormat improperFormat = null; protected Locale getLocale() { return Locale.getDefault(); } @Override protected void setUp() throws Exception { properFormat = BigFractionFormat.getProperInstance(getLocale()); improperFormat = BigFractionFormat.getImproperInstance(getLocale()); } public void testFormat() { BigFraction c = new BigFraction(1, 2); String expected = "1 / 2"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatNegative() { BigFraction c = new BigFraction(-1, 2); String expected = "-1 / 2"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatZero() { BigFraction c = new BigFraction(0, 1); String expected = "0 / 1"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatImproper() { BigFraction c = new BigFraction(5, 3); String actual = properFormat.format(c); assertEquals("1 2 / 3", actual); actual = improperFormat.format(c); assertEquals("5 / 3", actual); } public void testFormatImproperNegative() { BigFraction c = new BigFraction(-5, 3); String actual = properFormat.format(c); assertEquals("-1 2 / 3", actual); actual = improperFormat.format(c); assertEquals("-5 / 3", actual); } public void testParse() { String source = "1 / 2"; try { BigFraction c = properFormat.parse(source); assertNotNull(c); assertEquals(BigInteger.ONE, c.getNumerator()); assertEquals(BigInteger.valueOf(2l), c.getDenominator()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(BigInteger.ONE, c.getNumerator()); assertEquals(BigInteger.valueOf(2l), c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseInteger() { String source = "10"; try { BigFraction c = properFormat.parse(source); assertNotNull(c); assertEquals(BigInteger.TEN, c.getNumerator()); assertEquals(BigInteger.ONE, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } try { BigFraction c = improperFormat.parse(source); assertNotNull(c); assertEquals(BigInteger.TEN, c.getNumerator()); assertEquals(BigInteger.ONE, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseInvalid() { String source = "a"; String msg = "should not be able to parse '10 / a'."; try { properFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } try { improperFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } } public void testParseInvalidDenominator() { String source = "10 / a"; String msg = "should not be able to parse '10 / a'."; try { properFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } try { improperFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } } public void testParseNegative() { try { String source = "-1 / 2"; BigFraction c = properFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumeratorAsInt()); assertEquals(2, c.getDenominatorAsInt()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumeratorAsInt()); assertEquals(2, c.getDenominatorAsInt()); source = "1 / -2"; c = properFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumeratorAsInt()); assertEquals(2, c.getDenominatorAsInt()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumeratorAsInt()); assertEquals(2, c.getDenominatorAsInt()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseProper() { String source = "1 2 / 3"; try { BigFraction c = properFormat.parse(source); assertNotNull(c); assertEquals(5, c.getNumeratorAsInt()); assertEquals(3, c.getDenominatorAsInt()); } catch (ParseException ex) { fail(ex.getMessage()); } try { improperFormat.parse(source); fail("invalid improper fraction."); } catch (ParseException ex) { // success } } public void testParseProperNegative() { String source = "-1 2 / 3"; try { BigFraction c = properFormat.parse(source); assertNotNull(c); assertEquals(-5, c.getNumeratorAsInt()); assertEquals(3, c.getDenominatorAsInt()); } catch (ParseException ex) { fail(ex.getMessage()); } try { improperFormat.parse(source); fail("invalid improper fraction."); } catch (ParseException ex) { // success } } public void testParseProperInvalidMinus() { String source = "2 -2 / 3"; try { properFormat.parse(source); fail("invalid minus in improper fraction."); } catch (ParseException ex) { // expected } source = "2 2 / -3"; try { properFormat.parse(source); fail("invalid minus in improper fraction."); } catch (ParseException ex) { // expected } } public void testParseBig() throws ParseException { BigFraction f1 = improperFormat.parse("167213075789791382630275400487886041651764456874403" + " / " + "53225575123090058458126718248444563466137046489291"); assertEquals(FastMath.PI, f1.doubleValue(), 0.0); BigFraction f2 = properFormat.parse("3 " + "7536350420521207255895245742552351253353317406530" + " / " + "53225575123090058458126718248444563466137046489291"); assertEquals(FastMath.PI, f2.doubleValue(), 0.0); assertEquals(f1, f2); BigDecimal pi = new BigDecimal("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068"); assertEquals(pi, f1.bigDecimalValue(99, BigDecimal.ROUND_HALF_EVEN)); } public void testNumeratorFormat() { NumberFormat old = properFormat.getNumeratorFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); properFormat.setNumeratorFormat(nf); assertEquals(nf, properFormat.getNumeratorFormat()); properFormat.setNumeratorFormat(old); old = improperFormat.getNumeratorFormat(); nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); improperFormat.setNumeratorFormat(nf); assertEquals(nf, improperFormat.getNumeratorFormat()); improperFormat.setNumeratorFormat(old); } public void testDenominatorFormat() { NumberFormat old = properFormat.getDenominatorFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); properFormat.setDenominatorFormat(nf); assertEquals(nf, properFormat.getDenominatorFormat()); properFormat.setDenominatorFormat(old); old = improperFormat.getDenominatorFormat(); nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); improperFormat.setDenominatorFormat(nf); assertEquals(nf, improperFormat.getDenominatorFormat()); improperFormat.setDenominatorFormat(old); } public void testWholeFormat() { ProperBigFractionFormat format = (ProperBigFractionFormat)properFormat; NumberFormat old = format.getWholeFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); format.setWholeFormat(nf); assertEquals(nf, format.getWholeFormat()); format.setWholeFormat(old); } public void testLongFormat() { assertEquals("10 / 1", improperFormat.format(10l)); } public void testDoubleFormat() { assertEquals("1 / 16", improperFormat.format(0.0625)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/BigFractionTest.java100644 1750 1750 60352 11532241242 30121 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.math.BigDecimal; import java.math.BigInteger; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public class BigFractionTest extends TestCase { private void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) { assertEquals(expectedNumerator, actual.getNumeratorAsInt()); assertEquals(expectedDenominator, actual.getDenominatorAsInt()); } private void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) { assertEquals(expectedNumerator, actual.getNumeratorAsLong()); assertEquals(expectedDenominator, actual.getDenominatorAsLong()); } public void testConstructor() { assertFraction(0, 1, new BigFraction(0, 1)); assertFraction(0, 1, new BigFraction(0l, 2l)); assertFraction(0, 1, new BigFraction(0, -1)); assertFraction(1, 2, new BigFraction(1, 2)); assertFraction(1, 2, new BigFraction(2, 4)); assertFraction(-1, 2, new BigFraction(-1, 2)); assertFraction(-1, 2, new BigFraction(1, -2)); assertFraction(-1, 2, new BigFraction(-2, 4)); assertFraction(-1, 2, new BigFraction(2, -4)); assertFraction(11, 1, new BigFraction(11)); assertFraction(11, 1, new BigFraction(11l)); assertFraction(11, 1, new BigFraction(new BigInteger("11"))); try { assertFraction(0, 1, new BigFraction(0.00000000000001, 1.0e-5, 100)); assertFraction(2, 5, new BigFraction(0.40000000000001, 1.0e-5, 100)); assertFraction(15, 1, new BigFraction(15.0000000000001, 1.0e-5, 100)); } catch (ConvergenceException ex) { fail(ex.getMessage()); } assertEquals(0.00000000000001, new BigFraction(0.00000000000001).doubleValue(), 0.0); assertEquals(0.40000000000001, new BigFraction(0.40000000000001).doubleValue(), 0.0); assertEquals(15.0000000000001, new BigFraction(15.0000000000001).doubleValue(), 0.0); assertFraction(3602879701896487l, 9007199254740992l, new BigFraction(0.40000000000001)); assertFraction(1055531162664967l, 70368744177664l, new BigFraction(15.0000000000001)); try { new BigFraction(null, BigInteger.ONE); fail("Expecting NullPointerException"); } catch (NullPointerException npe) { // expected } try { new BigFraction(BigInteger.ONE, null); fail("Expecting NullPointerException"); } catch (NullPointerException npe) { // expected } try { new BigFraction(BigInteger.ONE, BigInteger.ZERO); fail("Expecting ArithmeticException"); } catch (ArithmeticException npe) { // expected } try { new BigFraction(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000); fail("Expecting FractionConversionException"); } catch (FractionConversionException fce) { // expected } } public void testGoldenRatio() { try { // the golden ratio is notoriously a difficult number for continuous // fraction new BigFraction((1 + FastMath.sqrt(5)) / 2, 1.0e-12, 25); fail("an exception should have been thrown"); } catch (ConvergenceException ce) { // expected behavior } } // MATH-179 public void testDoubleConstructor() throws ConvergenceException { assertFraction(1, 2, new BigFraction((double) 1 / (double) 2, 1.0e-5, 100)); assertFraction(1, 3, new BigFraction((double) 1 / (double) 3, 1.0e-5, 100)); assertFraction(2, 3, new BigFraction((double) 2 / (double) 3, 1.0e-5, 100)); assertFraction(1, 4, new BigFraction((double) 1 / (double) 4, 1.0e-5, 100)); assertFraction(3, 4, new BigFraction((double) 3 / (double) 4, 1.0e-5, 100)); assertFraction(1, 5, new BigFraction((double) 1 / (double) 5, 1.0e-5, 100)); assertFraction(2, 5, new BigFraction((double) 2 / (double) 5, 1.0e-5, 100)); assertFraction(3, 5, new BigFraction((double) 3 / (double) 5, 1.0e-5, 100)); assertFraction(4, 5, new BigFraction((double) 4 / (double) 5, 1.0e-5, 100)); assertFraction(1, 6, new BigFraction((double) 1 / (double) 6, 1.0e-5, 100)); assertFraction(5, 6, new BigFraction((double) 5 / (double) 6, 1.0e-5, 100)); assertFraction(1, 7, new BigFraction((double) 1 / (double) 7, 1.0e-5, 100)); assertFraction(2, 7, new BigFraction((double) 2 / (double) 7, 1.0e-5, 100)); assertFraction(3, 7, new BigFraction((double) 3 / (double) 7, 1.0e-5, 100)); assertFraction(4, 7, new BigFraction((double) 4 / (double) 7, 1.0e-5, 100)); assertFraction(5, 7, new BigFraction((double) 5 / (double) 7, 1.0e-5, 100)); assertFraction(6, 7, new BigFraction((double) 6 / (double) 7, 1.0e-5, 100)); assertFraction(1, 8, new BigFraction((double) 1 / (double) 8, 1.0e-5, 100)); assertFraction(3, 8, new BigFraction((double) 3 / (double) 8, 1.0e-5, 100)); assertFraction(5, 8, new BigFraction((double) 5 / (double) 8, 1.0e-5, 100)); assertFraction(7, 8, new BigFraction((double) 7 / (double) 8, 1.0e-5, 100)); assertFraction(1, 9, new BigFraction((double) 1 / (double) 9, 1.0e-5, 100)); assertFraction(2, 9, new BigFraction((double) 2 / (double) 9, 1.0e-5, 100)); assertFraction(4, 9, new BigFraction((double) 4 / (double) 9, 1.0e-5, 100)); assertFraction(5, 9, new BigFraction((double) 5 / (double) 9, 1.0e-5, 100)); assertFraction(7, 9, new BigFraction((double) 7 / (double) 9, 1.0e-5, 100)); assertFraction(8, 9, new BigFraction((double) 8 / (double) 9, 1.0e-5, 100)); assertFraction(1, 10, new BigFraction((double) 1 / (double) 10, 1.0e-5, 100)); assertFraction(3, 10, new BigFraction((double) 3 / (double) 10, 1.0e-5, 100)); assertFraction(7, 10, new BigFraction((double) 7 / (double) 10, 1.0e-5, 100)); assertFraction(9, 10, new BigFraction((double) 9 / (double) 10, 1.0e-5, 100)); assertFraction(1, 11, new BigFraction((double) 1 / (double) 11, 1.0e-5, 100)); assertFraction(2, 11, new BigFraction((double) 2 / (double) 11, 1.0e-5, 100)); assertFraction(3, 11, new BigFraction((double) 3 / (double) 11, 1.0e-5, 100)); assertFraction(4, 11, new BigFraction((double) 4 / (double) 11, 1.0e-5, 100)); assertFraction(5, 11, new BigFraction((double) 5 / (double) 11, 1.0e-5, 100)); assertFraction(6, 11, new BigFraction((double) 6 / (double) 11, 1.0e-5, 100)); assertFraction(7, 11, new BigFraction((double) 7 / (double) 11, 1.0e-5, 100)); assertFraction(8, 11, new BigFraction((double) 8 / (double) 11, 1.0e-5, 100)); assertFraction(9, 11, new BigFraction((double) 9 / (double) 11, 1.0e-5, 100)); assertFraction(10, 11, new BigFraction((double) 10 / (double) 11, 1.0e-5, 100)); } // MATH-181 public void testDigitLimitConstructor() throws ConvergenceException { assertFraction(2, 5, new BigFraction(0.4, 9)); assertFraction(2, 5, new BigFraction(0.4, 99)); assertFraction(2, 5, new BigFraction(0.4, 999)); assertFraction(3, 5, new BigFraction(0.6152, 9)); assertFraction(8, 13, new BigFraction(0.6152, 99)); assertFraction(510, 829, new BigFraction(0.6152, 999)); assertFraction(769, 1250, new BigFraction(0.6152, 9999)); } public void testEpsilonLimitConstructor() throws ConvergenceException { assertFraction(2, 5, new BigFraction(0.4, 1.0e-5, 100)); assertFraction(3, 5, new BigFraction(0.6152, 0.02, 100)); assertFraction(8, 13, new BigFraction(0.6152, 1.0e-3, 100)); assertFraction(251, 408, new BigFraction(0.6152, 1.0e-4, 100)); assertFraction(251, 408, new BigFraction(0.6152, 1.0e-5, 100)); assertFraction(510, 829, new BigFraction(0.6152, 1.0e-6, 100)); assertFraction(769, 1250, new BigFraction(0.6152, 1.0e-7, 100)); } public void testCompareTo() { BigFraction first = new BigFraction(1, 2); BigFraction second = new BigFraction(1, 3); BigFraction third = new BigFraction(1, 2); assertEquals(0, first.compareTo(first)); assertEquals(0, first.compareTo(third)); assertEquals(1, first.compareTo(second)); assertEquals(-1, second.compareTo(first)); // these two values are different approximations of PI // the first one is approximately PI - 3.07e-18 // the second one is approximately PI + 1.936e-17 BigFraction pi1 = new BigFraction(1068966896, 340262731); BigFraction pi2 = new BigFraction( 411557987, 131002976); assertEquals(-1, pi1.compareTo(pi2)); assertEquals( 1, pi2.compareTo(pi1)); assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20); } public void testDoubleValue() { BigFraction first = new BigFraction(1, 2); BigFraction second = new BigFraction(1, 3); assertEquals(0.5, first.doubleValue(), 0.0); assertEquals(1.0 / 3.0, second.doubleValue(), 0.0); } public void testFloatValue() { BigFraction first = new BigFraction(1, 2); BigFraction second = new BigFraction(1, 3); assertEquals(0.5f, first.floatValue(), 0.0f); assertEquals((float) (1.0 / 3.0), second.floatValue(), 0.0f); } public void testIntValue() { BigFraction first = new BigFraction(1, 2); BigFraction second = new BigFraction(3, 2); assertEquals(0, first.intValue()); assertEquals(1, second.intValue()); } public void testLongValue() { BigFraction first = new BigFraction(1, 2); BigFraction second = new BigFraction(3, 2); assertEquals(0L, first.longValue()); assertEquals(1L, second.longValue()); } public void testConstructorDouble() { assertFraction(1, 2, new BigFraction(0.5)); assertFraction(6004799503160661l, 18014398509481984l, new BigFraction(1.0 / 3.0)); assertFraction(6124895493223875l, 36028797018963968l, new BigFraction(17.0 / 100.0)); assertFraction(1784551352345559l, 562949953421312l, new BigFraction(317.0 / 100.0)); assertFraction(-1, 2, new BigFraction(-0.5)); assertFraction(-6004799503160661l, 18014398509481984l, new BigFraction(-1.0 / 3.0)); assertFraction(-6124895493223875l, 36028797018963968l, new BigFraction(17.0 / -100.0)); assertFraction(-1784551352345559l, 562949953421312l, new BigFraction(-317.0 / 100.0)); for (double v : new double[] { Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) { try { new BigFraction(v); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException iae) { // expected } } assertEquals(1l, new BigFraction(Double.MAX_VALUE).getDenominatorAsLong()); assertEquals(1l, new BigFraction(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong()); assertEquals(1l, new BigFraction(Double.MIN_VALUE).getNumeratorAsLong()); } public void testAbs() { BigFraction a = new BigFraction(10, 21); BigFraction b = new BigFraction(-10, 21); BigFraction c = new BigFraction(10, -21); assertFraction(10, 21, a.abs()); assertFraction(10, 21, b.abs()); assertFraction(10, 21, c.abs()); } public void testReciprocal() { BigFraction f = null; f = new BigFraction(50, 75); f = f.reciprocal(); assertEquals(3, f.getNumeratorAsInt()); assertEquals(2, f.getDenominatorAsInt()); f = new BigFraction(4, 3); f = f.reciprocal(); assertEquals(3, f.getNumeratorAsInt()); assertEquals(4, f.getDenominatorAsInt()); f = new BigFraction(-15, 47); f = f.reciprocal(); assertEquals(-47, f.getNumeratorAsInt()); assertEquals(15, f.getDenominatorAsInt()); f = new BigFraction(0, 3); try { f = f.reciprocal(); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { } // large values f = new BigFraction(Integer.MAX_VALUE, 1); f = f.reciprocal(); assertEquals(1, f.getNumeratorAsInt()); assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt()); } public void testNegate() { BigFraction f = null; f = new BigFraction(50, 75); f = f.negate(); assertEquals(-2, f.getNumeratorAsInt()); assertEquals(3, f.getDenominatorAsInt()); f = new BigFraction(-50, 75); f = f.negate(); assertEquals(2, f.getNumeratorAsInt()); assertEquals(3, f.getDenominatorAsInt()); // large values f = new BigFraction(Integer.MAX_VALUE - 1, Integer.MAX_VALUE); f = f.negate(); assertEquals(Integer.MIN_VALUE + 2, f.getNumeratorAsInt()); assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt()); } public void testAdd() { BigFraction a = new BigFraction(1, 2); BigFraction b = new BigFraction(2, 3); assertFraction(1, 1, a.add(a)); assertFraction(7, 6, a.add(b)); assertFraction(7, 6, b.add(a)); assertFraction(4, 3, b.add(b)); BigFraction f1 = new BigFraction(Integer.MAX_VALUE - 1, 1); BigFraction f2 = BigFraction.ONE; BigFraction f = f1.add(f2); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f1 = new BigFraction(-1, 13 * 13 * 2 * 2); f2 = new BigFraction(-2, 13 * 17 * 2); f = f1.add(f2); assertEquals(13 * 13 * 17 * 2 * 2, f.getDenominatorAsInt()); assertEquals(-17 - 2 * 13 * 2, f.getNumeratorAsInt()); try { f.add((BigFraction) null); fail("expecting NullPointerException"); } catch (NullPointerException ex) { } // if this fraction is added naively, it will overflow. // check that it doesn't. f1 = new BigFraction(1, 32768 * 3); f2 = new BigFraction(1, 59049); f = f1.add(f2); assertEquals(52451, f.getNumeratorAsInt()); assertEquals(1934917632, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MIN_VALUE, 3); f2 = new BigFraction(1, 3); f = f1.add(f2); assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt()); assertEquals(3, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MAX_VALUE - 1, 1); f = f1.add(BigInteger.ONE); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f = f.add(BigInteger.ZERO); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MAX_VALUE - 1, 1); f = f1.add(1); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f = f.add(0); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MAX_VALUE - 1, 1); f = f1.add(1l); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f = f.add(0l); assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); } public void testDivide() { BigFraction a = new BigFraction(1, 2); BigFraction b = new BigFraction(2, 3); assertFraction(1, 1, a.divide(a)); assertFraction(3, 4, a.divide(b)); assertFraction(4, 3, b.divide(a)); assertFraction(1, 1, b.divide(b)); BigFraction f1 = new BigFraction(3, 5); BigFraction f2 = BigFraction.ZERO; try { f1.divide(f2); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { } f1 = new BigFraction(0, 5); f2 = new BigFraction(2, 7); BigFraction f = f1.divide(f2); assertSame(BigFraction.ZERO, f); f1 = new BigFraction(2, 7); f2 = BigFraction.ONE; f = f1.divide(f2); assertEquals(2, f.getNumeratorAsInt()); assertEquals(7, f.getDenominatorAsInt()); f1 = new BigFraction(1, Integer.MAX_VALUE); f = f1.divide(f1); assertEquals(1, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE); f2 = new BigFraction(1, Integer.MAX_VALUE); f = f1.divide(f2); assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); try { f.divide((BigFraction) null); fail("expecting NullPointerException"); } catch (NullPointerException ex) { } f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE); f = f1.divide(BigInteger.valueOf(Integer.MIN_VALUE)); assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt()); assertEquals(1, f.getNumeratorAsInt()); f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE); f = f1.divide(Integer.MIN_VALUE); assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt()); assertEquals(1, f.getNumeratorAsInt()); f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE); f = f1.divide((long) Integer.MIN_VALUE); assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt()); assertEquals(1, f.getNumeratorAsInt()); } public void testMultiply() { BigFraction a = new BigFraction(1, 2); BigFraction b = new BigFraction(2, 3); assertFraction(1, 4, a.multiply(a)); assertFraction(1, 3, a.multiply(b)); assertFraction(1, 3, b.multiply(a)); assertFraction(4, 9, b.multiply(b)); BigFraction f1 = new BigFraction(Integer.MAX_VALUE, 1); BigFraction f2 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE); BigFraction f = f1.multiply(f2); assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f = f2.multiply(Integer.MAX_VALUE); assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); f = f2.multiply((long) Integer.MAX_VALUE); assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); try { f.multiply((BigFraction) null); fail("expecting NullPointerException"); } catch (NullPointerException ex) { } } public void testSubtract() { BigFraction a = new BigFraction(1, 2); BigFraction b = new BigFraction(2, 3); assertFraction(0, 1, a.subtract(a)); assertFraction(-1, 6, a.subtract(b)); assertFraction(1, 6, b.subtract(a)); assertFraction(0, 1, b.subtract(b)); BigFraction f = new BigFraction(1, 1); try { f.subtract((BigFraction) null); fail("expecting NullPointerException"); } catch (NullPointerException ex) { } // if this fraction is subtracted naively, it will overflow. // check that it doesn't. BigFraction f1 = new BigFraction(1, 32768 * 3); BigFraction f2 = new BigFraction(1, 59049); f = f1.subtract(f2); assertEquals(-13085, f.getNumeratorAsInt()); assertEquals(1934917632, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MIN_VALUE, 3); f2 = new BigFraction(1, 3).negate(); f = f1.subtract(f2); assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt()); assertEquals(3, f.getDenominatorAsInt()); f1 = new BigFraction(Integer.MAX_VALUE, 1); f2 = BigFraction.ONE; f = f1.subtract(f2); assertEquals(Integer.MAX_VALUE - 1, f.getNumeratorAsInt()); assertEquals(1, f.getDenominatorAsInt()); } public void testBigDecimalValue() { assertEquals(new BigDecimal(0.5), new BigFraction(1, 2).bigDecimalValue()); assertEquals(new BigDecimal("0.0003"), new BigFraction(3, 10000).bigDecimalValue()); assertEquals(new BigDecimal("0"), new BigFraction(1, 3).bigDecimalValue(BigDecimal.ROUND_DOWN)); assertEquals(new BigDecimal("0.333"), new BigFraction(1, 3).bigDecimalValue(3, BigDecimal.ROUND_DOWN)); } public void testEqualsAndHashCode() { BigFraction zero = new BigFraction(0, 1); BigFraction nullFraction = null; assertTrue(zero.equals(zero)); assertFalse(zero.equals(nullFraction)); assertFalse(zero.equals(Double.valueOf(0))); BigFraction zero2 = new BigFraction(0, 2); assertTrue(zero.equals(zero2)); assertEquals(zero.hashCode(), zero2.hashCode()); BigFraction one = new BigFraction(1, 1); assertFalse((one.equals(zero) || zero.equals(one))); assertTrue(one.equals(BigFraction.ONE)); } public void testGetReducedFraction() { BigFraction threeFourths = new BigFraction(3, 4); assertTrue(threeFourths.equals(BigFraction.getReducedFraction(6, 8))); assertTrue(BigFraction.ZERO.equals(BigFraction.getReducedFraction(0, -1))); try { BigFraction.getReducedFraction(1, 0); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected } assertEquals(BigFraction.getReducedFraction(2, Integer.MIN_VALUE).getNumeratorAsInt(), -1); assertEquals(BigFraction.getReducedFraction(1, -1).getNumeratorAsInt(), -1); } public void testPow() { assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13)); assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13l)); assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(BigInteger.valueOf(13l))); assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0)); assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0l)); assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(BigInteger.valueOf(0l))); assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13)); assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13l)); assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(BigInteger.valueOf(-13l))); } public void testMath340() { BigFraction fractionA = new BigFraction(0.00131); BigFraction fractionB = new BigFraction(.37).reciprocal(); BigFraction errorResult = fractionA.multiply(fractionB); BigFraction correctResult = new BigFraction(fractionA.getNumerator().multiply(fractionB.getNumerator()), fractionA.getDenominator().multiply(fractionB.getDenominator())); assertEquals(correctResult, errorResult); } public void testSerial() throws FractionConversionException { BigFraction[] fractions = { new BigFraction(3, 4), BigFraction.ONE, BigFraction.ZERO, new BigFraction(17), new BigFraction(FastMath.PI, 1000), new BigFraction(-5, 2) }; for (BigFraction fraction : fractions) { assertEquals(fraction, TestUtils.serializeAndRecover(fraction)); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/FractionFieldTest.java100644 1750 1750 2771 11532241242 30424 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.TestUtils; import org.junit.Test; public class FractionFieldTest { @Test public void testZero() { assertEquals(Fraction.ZERO, FractionField.getInstance().getZero()); } @Test public void testOne() { assertEquals(Fraction.ONE, FractionField.getInstance().getOne()); } @Test public void testSerial() { // deserializing the singleton should give the singleton itself back FractionField field = FractionField.getInstance(); assertTrue(field == TestUtils.serializeAndRecover(field)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/FractionTest.java100644 1750 1750 52604 11532241242 27500 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 1003907 $ $Date: 2010-10-03 00:23:34 +0200 (dim. 03 oct. 2010) $ */ public class FractionTest extends TestCase { private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) { assertEquals(expectedNumerator, actual.getNumerator()); assertEquals(expectedDenominator, actual.getDenominator()); } public void testConstructor() { assertFraction(0, 1, new Fraction(0, 1)); assertFraction(0, 1, new Fraction(0, 2)); assertFraction(0, 1, new Fraction(0, -1)); assertFraction(1, 2, new Fraction(1, 2)); assertFraction(1, 2, new Fraction(2, 4)); assertFraction(-1, 2, new Fraction(-1, 2)); assertFraction(-1, 2, new Fraction(1, -2)); assertFraction(-1, 2, new Fraction(-2, 4)); assertFraction(-1, 2, new Fraction(2, -4)); // overflow try { new Fraction(Integer.MIN_VALUE, -1); fail(); } catch (ArithmeticException ex) { // success } try { new Fraction(1, Integer.MIN_VALUE); fail(); } catch (ArithmeticException ex) { // success } try { assertFraction(0, 1, new Fraction(0.00000000000001)); assertFraction(2, 5, new Fraction(0.40000000000001)); assertFraction(15, 1, new Fraction(15.0000000000001)); } catch (ConvergenceException ex) { fail(ex.getMessage()); } } public void testGoldenRatio() { try { // the golden ratio is notoriously a difficult number for continuous fraction new Fraction((1 + FastMath.sqrt(5)) / 2, 1.0e-12, 25); fail("an exception should have been thrown"); } catch (ConvergenceException ce) { // expected behavior } } // MATH-179 public void testDoubleConstructor() throws ConvergenceException { assertFraction(1, 2, new Fraction((double)1 / (double)2)); assertFraction(1, 3, new Fraction((double)1 / (double)3)); assertFraction(2, 3, new Fraction((double)2 / (double)3)); assertFraction(1, 4, new Fraction((double)1 / (double)4)); assertFraction(3, 4, new Fraction((double)3 / (double)4)); assertFraction(1, 5, new Fraction((double)1 / (double)5)); assertFraction(2, 5, new Fraction((double)2 / (double)5)); assertFraction(3, 5, new Fraction((double)3 / (double)5)); assertFraction(4, 5, new Fraction((double)4 / (double)5)); assertFraction(1, 6, new Fraction((double)1 / (double)6)); assertFraction(5, 6, new Fraction((double)5 / (double)6)); assertFraction(1, 7, new Fraction((double)1 / (double)7)); assertFraction(2, 7, new Fraction((double)2 / (double)7)); assertFraction(3, 7, new Fraction((double)3 / (double)7)); assertFraction(4, 7, new Fraction((double)4 / (double)7)); assertFraction(5, 7, new Fraction((double)5 / (double)7)); assertFraction(6, 7, new Fraction((double)6 / (double)7)); assertFraction(1, 8, new Fraction((double)1 / (double)8)); assertFraction(3, 8, new Fraction((double)3 / (double)8)); assertFraction(5, 8, new Fraction((double)5 / (double)8)); assertFraction(7, 8, new Fraction((double)7 / (double)8)); assertFraction(1, 9, new Fraction((double)1 / (double)9)); assertFraction(2, 9, new Fraction((double)2 / (double)9)); assertFraction(4, 9, new Fraction((double)4 / (double)9)); assertFraction(5, 9, new Fraction((double)5 / (double)9)); assertFraction(7, 9, new Fraction((double)7 / (double)9)); assertFraction(8, 9, new Fraction((double)8 / (double)9)); assertFraction(1, 10, new Fraction((double)1 / (double)10)); assertFraction(3, 10, new Fraction((double)3 / (double)10)); assertFraction(7, 10, new Fraction((double)7 / (double)10)); assertFraction(9, 10, new Fraction((double)9 / (double)10)); assertFraction(1, 11, new Fraction((double)1 / (double)11)); assertFraction(2, 11, new Fraction((double)2 / (double)11)); assertFraction(3, 11, new Fraction((double)3 / (double)11)); assertFraction(4, 11, new Fraction((double)4 / (double)11)); assertFraction(5, 11, new Fraction((double)5 / (double)11)); assertFraction(6, 11, new Fraction((double)6 / (double)11)); assertFraction(7, 11, new Fraction((double)7 / (double)11)); assertFraction(8, 11, new Fraction((double)8 / (double)11)); assertFraction(9, 11, new Fraction((double)9 / (double)11)); assertFraction(10, 11, new Fraction((double)10 / (double)11)); } // MATH-181 public void testDigitLimitConstructor() throws ConvergenceException { assertFraction(2, 5, new Fraction(0.4, 9)); assertFraction(2, 5, new Fraction(0.4, 99)); assertFraction(2, 5, new Fraction(0.4, 999)); assertFraction(3, 5, new Fraction(0.6152, 9)); assertFraction(8, 13, new Fraction(0.6152, 99)); assertFraction(510, 829, new Fraction(0.6152, 999)); assertFraction(769, 1250, new Fraction(0.6152, 9999)); } public void testIntegerOverflow() { checkIntegerOverflow(0.75000000001455192); checkIntegerOverflow(1.0e10); } private void checkIntegerOverflow(double a) { try { new Fraction(a, 1.0e-12, 1000); fail("an exception should have been thrown"); } catch (ConvergenceException ce) { // expected behavior } } public void testEpsilonLimitConstructor() throws ConvergenceException { assertFraction(2, 5, new Fraction(0.4, 1.0e-5, 100)); assertFraction(3, 5, new Fraction(0.6152, 0.02, 100)); assertFraction(8, 13, new Fraction(0.6152, 1.0e-3, 100)); assertFraction(251, 408, new Fraction(0.6152, 1.0e-4, 100)); assertFraction(251, 408, new Fraction(0.6152, 1.0e-5, 100)); assertFraction(510, 829, new Fraction(0.6152, 1.0e-6, 100)); assertFraction(769, 1250, new Fraction(0.6152, 1.0e-7, 100)); } public void testCompareTo() { Fraction first = new Fraction(1, 2); Fraction second = new Fraction(1, 3); Fraction third = new Fraction(1, 2); assertEquals(0, first.compareTo(first)); assertEquals(0, first.compareTo(third)); assertEquals(1, first.compareTo(second)); assertEquals(-1, second.compareTo(first)); // these two values are different approximations of PI // the first one is approximately PI - 3.07e-18 // the second one is approximately PI + 1.936e-17 Fraction pi1 = new Fraction(1068966896, 340262731); Fraction pi2 = new Fraction( 411557987, 131002976); assertEquals(-1, pi1.compareTo(pi2)); assertEquals( 1, pi2.compareTo(pi1)); assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20); } public void testDoubleValue() { Fraction first = new Fraction(1, 2); Fraction second = new Fraction(1, 3); assertEquals(0.5, first.doubleValue(), 0.0); assertEquals(1.0 / 3.0, second.doubleValue(), 0.0); } public void testFloatValue() { Fraction first = new Fraction(1, 2); Fraction second = new Fraction(1, 3); assertEquals(0.5f, first.floatValue(), 0.0f); assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f); } public void testIntValue() { Fraction first = new Fraction(1, 2); Fraction second = new Fraction(3, 2); assertEquals(0, first.intValue()); assertEquals(1, second.intValue()); } public void testLongValue() { Fraction first = new Fraction(1, 2); Fraction second = new Fraction(3, 2); assertEquals(0L, first.longValue()); assertEquals(1L, second.longValue()); } public void testConstructorDouble() { try { assertFraction(1, 2, new Fraction(0.5)); assertFraction(1, 3, new Fraction(1.0 / 3.0)); assertFraction(17, 100, new Fraction(17.0 / 100.0)); assertFraction(317, 100, new Fraction(317.0 / 100.0)); assertFraction(-1, 2, new Fraction(-0.5)); assertFraction(-1, 3, new Fraction(-1.0 / 3.0)); assertFraction(-17, 100, new Fraction(17.0 / -100.0)); assertFraction(-317, 100, new Fraction(-317.0 / 100.0)); } catch (ConvergenceException ex) { fail(ex.getMessage()); } } public void testAbs() { Fraction a = new Fraction(10, 21); Fraction b = new Fraction(-10, 21); Fraction c = new Fraction(10, -21); assertFraction(10, 21, a.abs()); assertFraction(10, 21, b.abs()); assertFraction(10, 21, c.abs()); } public void testReciprocal() { Fraction f = null; f = new Fraction(50, 75); f = f.reciprocal(); assertEquals(3, f.getNumerator()); assertEquals(2, f.getDenominator()); f = new Fraction(4, 3); f = f.reciprocal(); assertEquals(3, f.getNumerator()); assertEquals(4, f.getDenominator()); f = new Fraction(-15, 47); f = f.reciprocal(); assertEquals(-47, f.getNumerator()); assertEquals(15, f.getDenominator()); f = new Fraction(0, 3); try { f = f.reciprocal(); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} // large values f = new Fraction(Integer.MAX_VALUE, 1); f = f.reciprocal(); assertEquals(1, f.getNumerator()); assertEquals(Integer.MAX_VALUE, f.getDenominator()); } public void testNegate() { Fraction f = null; f = new Fraction(50, 75); f = f.negate(); assertEquals(-2, f.getNumerator()); assertEquals(3, f.getDenominator()); f = new Fraction(-50, 75); f = f.negate(); assertEquals(2, f.getNumerator()); assertEquals(3, f.getDenominator()); // large values f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE); f = f.negate(); assertEquals(Integer.MIN_VALUE+2, f.getNumerator()); assertEquals(Integer.MAX_VALUE, f.getDenominator()); f = new Fraction(Integer.MIN_VALUE, 1); try { f = f.negate(); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} } public void testAdd() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(2, 3); assertFraction(1, 1, a.add(a)); assertFraction(7, 6, a.add(b)); assertFraction(7, 6, b.add(a)); assertFraction(4, 3, b.add(b)); Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1); Fraction f2 = Fraction.ONE; Fraction f = f1.add(f2); assertEquals(Integer.MAX_VALUE, f.getNumerator()); assertEquals(1, f.getDenominator()); f = f1.add(1); assertEquals(Integer.MAX_VALUE, f.getNumerator()); assertEquals(1, f.getDenominator()); f1 = new Fraction(-1, 13*13*2*2); f2 = new Fraction(-2, 13*17*2); f = f1.add(f2); assertEquals(13*13*17*2*2, f.getDenominator()); assertEquals(-17 - 2*13*2, f.getNumerator()); try { f.add(null); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) {} // if this fraction is added naively, it will overflow. // check that it doesn't. f1 = new Fraction(1,32768*3); f2 = new Fraction(1,59049); f = f1.add(f2); assertEquals(52451, f.getNumerator()); assertEquals(1934917632, f.getDenominator()); f1 = new Fraction(Integer.MIN_VALUE, 3); f2 = new Fraction(1,3); f = f1.add(f2); assertEquals(Integer.MIN_VALUE+1, f.getNumerator()); assertEquals(3, f.getDenominator()); f1 = new Fraction(Integer.MAX_VALUE - 1, 1); f2 = Fraction.ONE; f = f1.add(f2); assertEquals(Integer.MAX_VALUE, f.getNumerator()); assertEquals(1, f.getDenominator()); try { f = f.add(Fraction.ONE); // should overflow fail("expecting ArithmeticException but got: " + f.toString()); } catch (ArithmeticException ex) {} // denominator should not be a multiple of 2 or 3 to trigger overflow f1 = new Fraction(Integer.MIN_VALUE, 5); f2 = new Fraction(-1,5); try { f = f1.add(f2); // should overflow fail("expecting ArithmeticException but got: " + f.toString()); } catch (ArithmeticException ex) {} try { f= new Fraction(-Integer.MAX_VALUE, 1); f = f.add(f); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} try { f= new Fraction(-Integer.MAX_VALUE, 1); f = f.add(f); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} f1 = new Fraction(3,327680); f2 = new Fraction(2,59049); try { f = f1.add(f2); // should overflow fail("expecting ArithmeticException but got: " + f.toString()); } catch (ArithmeticException ex) {} } public void testDivide() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(2, 3); assertFraction(1, 1, a.divide(a)); assertFraction(3, 4, a.divide(b)); assertFraction(4, 3, b.divide(a)); assertFraction(1, 1, b.divide(b)); Fraction f1 = new Fraction(3, 5); Fraction f2 = Fraction.ZERO; try { f1.divide(f2); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} f1 = new Fraction(0, 5); f2 = new Fraction(2, 7); Fraction f = f1.divide(f2); assertSame(Fraction.ZERO, f); f1 = new Fraction(2, 7); f2 = Fraction.ONE; f = f1.divide(f2); assertEquals(2, f.getNumerator()); assertEquals(7, f.getDenominator()); f1 = new Fraction(1, Integer.MAX_VALUE); f = f1.divide(f1); assertEquals(1, f.getNumerator()); assertEquals(1, f.getDenominator()); f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE); f2 = new Fraction(1, Integer.MAX_VALUE); f = f1.divide(f2); assertEquals(Integer.MIN_VALUE, f.getNumerator()); assertEquals(1, f.getDenominator()); try { f.divide(null); fail("IllegalArgumentException"); } catch (IllegalArgumentException ex) {} try { f1 = new Fraction(1, Integer.MAX_VALUE); f = f1.divide(f1.reciprocal()); // should overflow fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} try { f1 = new Fraction(1, -Integer.MAX_VALUE); f = f1.divide(f1.reciprocal()); // should overflow fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} f1 = new Fraction(6, 35); f = f1.divide(15); assertEquals(2, f.getNumerator()); assertEquals(175, f.getDenominator()); } public void testMultiply() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(2, 3); assertFraction(1, 4, a.multiply(a)); assertFraction(1, 3, a.multiply(b)); assertFraction(1, 3, b.multiply(a)); assertFraction(4, 9, b.multiply(b)); Fraction f1 = new Fraction(Integer.MAX_VALUE, 1); Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE); Fraction f = f1.multiply(f2); assertEquals(Integer.MIN_VALUE, f.getNumerator()); assertEquals(1, f.getDenominator()); try { f.multiply(null); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) {} f1 = new Fraction(6, 35); f = f1.multiply(15); assertEquals(18, f.getNumerator()); assertEquals(7, f.getDenominator()); } public void testSubtract() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(2, 3); assertFraction(0, 1, a.subtract(a)); assertFraction(-1, 6, a.subtract(b)); assertFraction(1, 6, b.subtract(a)); assertFraction(0, 1, b.subtract(b)); Fraction f = new Fraction(1,1); try { f.subtract(null); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) {} // if this fraction is subtracted naively, it will overflow. // check that it doesn't. Fraction f1 = new Fraction(1,32768*3); Fraction f2 = new Fraction(1,59049); f = f1.subtract(f2); assertEquals(-13085, f.getNumerator()); assertEquals(1934917632, f.getDenominator()); f1 = new Fraction(Integer.MIN_VALUE, 3); f2 = new Fraction(1,3).negate(); f = f1.subtract(f2); assertEquals(Integer.MIN_VALUE+1, f.getNumerator()); assertEquals(3, f.getDenominator()); f1 = new Fraction(Integer.MAX_VALUE, 1); f2 = Fraction.ONE; f = f1.subtract(f2); assertEquals(Integer.MAX_VALUE-1, f.getNumerator()); assertEquals(1, f.getDenominator()); f = f1.subtract(1); assertEquals(Integer.MAX_VALUE-1, f.getNumerator()); assertEquals(1, f.getDenominator()); try { f1 = new Fraction(1, Integer.MAX_VALUE); f2 = new Fraction(1, Integer.MAX_VALUE - 1); f = f1.subtract(f2); fail("expecting ArithmeticException"); //should overflow } catch (ArithmeticException ex) {} // denominator should not be a multiple of 2 or 3 to trigger overflow f1 = new Fraction(Integer.MIN_VALUE, 5); f2 = new Fraction(1,5); try { f = f1.subtract(f2); // should overflow fail("expecting ArithmeticException but got: " + f.toString()); } catch (ArithmeticException ex) {} try { f= new Fraction(Integer.MIN_VALUE, 1); f = f.subtract(Fraction.ONE); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} try { f= new Fraction(Integer.MAX_VALUE, 1); f = f.subtract(Fraction.ONE.negate()); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} f1 = new Fraction(3,327680); f2 = new Fraction(2,59049); try { f = f1.subtract(f2); // should overflow fail("expecting ArithmeticException but got: " + f.toString()); } catch (ArithmeticException ex) {} } public void testEqualsAndHashCode() { Fraction zero = new Fraction(0,1); Fraction nullFraction = null; assertTrue( zero.equals(zero)); assertFalse(zero.equals(nullFraction)); assertFalse(zero.equals(Double.valueOf(0))); Fraction zero2 = new Fraction(0,2); assertTrue(zero.equals(zero2)); assertEquals(zero.hashCode(), zero2.hashCode()); Fraction one = new Fraction(1,1); assertFalse((one.equals(zero) ||zero.equals(one))); } public void testGetReducedFraction() { Fraction threeFourths = new Fraction(3, 4); assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8))); assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1))); try { Fraction.getReducedFraction(1, 0); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { // expected } assertEquals(Fraction.getReducedFraction (2, Integer.MIN_VALUE).getNumerator(),-1); assertEquals(Fraction.getReducedFraction (1, -1).getNumerator(), -1); } public void testToString() { assertEquals("0", new Fraction(0, 3).toString()); assertEquals("3", new Fraction(6, 2).toString()); assertEquals("2 / 3", new Fraction(18, 27).toString()); } public void testSerial() throws FractionConversionException { Fraction[] fractions = { new Fraction(3, 4), Fraction.ONE, Fraction.ZERO, new Fraction(17), new Fraction(FastMath.PI, 1000), new Fraction(-5, 2) }; for (Fraction fraction : fractions) { assertEquals(fraction, TestUtils.serializeAndRecover(fraction)); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/BigFractionFieldTest.java100644 1750 1750 3016 11532241242 31037 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.TestUtils; import org.junit.Test; public class BigFractionFieldTest { @Test public void testZero() { assertEquals(BigFraction.ZERO, BigFractionField.getInstance().getZero()); } @Test public void testOne() { assertEquals(BigFraction.ONE, BigFractionField.getInstance().getOne()); } @Test public void testSerial() { // deserializing the singleton should give the singleton itself back BigFractionField field = BigFractionField.getInstance(); assertTrue(field == TestUtils.serializeAndRecover(field)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/fraction/FractionFormatTest.java100644 1750 1750 22045 11532241242 30645 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; public class FractionFormatTest extends TestCase { FractionFormat properFormat = null; FractionFormat improperFormat = null; protected Locale getLocale() { return Locale.getDefault(); } @Override protected void setUp() throws Exception { properFormat = FractionFormat.getProperInstance(getLocale()); improperFormat = FractionFormat.getImproperInstance(getLocale()); } public void testFormat() { Fraction c = new Fraction(1, 2); String expected = "1 / 2"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatNegative() { Fraction c = new Fraction(-1, 2); String expected = "-1 / 2"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatZero() { Fraction c = new Fraction(0, 1); String expected = "0 / 1"; String actual = properFormat.format(c); assertEquals(expected, actual); actual = improperFormat.format(c); assertEquals(expected, actual); } public void testFormatImproper() { Fraction c = new Fraction(5, 3); String actual = properFormat.format(c); assertEquals("1 2 / 3", actual); actual = improperFormat.format(c); assertEquals("5 / 3", actual); } public void testFormatImproperNegative() { Fraction c = new Fraction(-5, 3); String actual = properFormat.format(c); assertEquals("-1 2 / 3", actual); actual = improperFormat.format(c); assertEquals("-5 / 3", actual); } public void testParse() { String source = "1 / 2"; try { Fraction c = properFormat.parse(source); assertNotNull(c); assertEquals(1, c.getNumerator()); assertEquals(2, c.getDenominator()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(1, c.getNumerator()); assertEquals(2, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseInteger() { String source = "10"; try { Fraction c = properFormat.parse(source); assertNotNull(c); assertEquals(10, c.getNumerator()); assertEquals(1, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } try { Fraction c = improperFormat.parse(source); assertNotNull(c); assertEquals(10, c.getNumerator()); assertEquals(1, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseInvalid() { String source = "a"; String msg = "should not be able to parse '10 / a'."; try { properFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } try { improperFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } } public void testParseInvalidDenominator() { String source = "10 / a"; String msg = "should not be able to parse '10 / a'."; try { properFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } try { improperFormat.parse(source); fail(msg); } catch (ParseException ex) { // success } } public void testParseNegative() { try { String source = "-1 / 2"; Fraction c = properFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumerator()); assertEquals(2, c.getDenominator()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumerator()); assertEquals(2, c.getDenominator()); source = "1 / -2"; c = properFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumerator()); assertEquals(2, c.getDenominator()); c = improperFormat.parse(source); assertNotNull(c); assertEquals(-1, c.getNumerator()); assertEquals(2, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } } public void testParseProper() { String source = "1 2 / 3"; try { Fraction c = properFormat.parse(source); assertNotNull(c); assertEquals(5, c.getNumerator()); assertEquals(3, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } try { improperFormat.parse(source); fail("invalid improper fraction."); } catch (ParseException ex) { // success } } public void testParseProperNegative() { String source = "-1 2 / 3"; try { Fraction c = properFormat.parse(source); assertNotNull(c); assertEquals(-5, c.getNumerator()); assertEquals(3, c.getDenominator()); } catch (ParseException ex) { fail(ex.getMessage()); } try { improperFormat.parse(source); fail("invalid improper fraction."); } catch (ParseException ex) { // success } } public void testParseProperInvalidMinus() { String source = "2 -2 / 3"; try { properFormat.parse(source); fail("invalid minus in improper fraction."); } catch (ParseException ex) { // expected } source = "2 2 / -3"; try { properFormat.parse(source); fail("invalid minus in improper fraction."); } catch (ParseException ex) { // expected } } public void testNumeratorFormat() { NumberFormat old = properFormat.getNumeratorFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); properFormat.setNumeratorFormat(nf); assertEquals(nf, properFormat.getNumeratorFormat()); properFormat.setNumeratorFormat(old); old = improperFormat.getNumeratorFormat(); nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); improperFormat.setNumeratorFormat(nf); assertEquals(nf, improperFormat.getNumeratorFormat()); improperFormat.setNumeratorFormat(old); } public void testDenominatorFormat() { NumberFormat old = properFormat.getDenominatorFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); properFormat.setDenominatorFormat(nf); assertEquals(nf, properFormat.getDenominatorFormat()); properFormat.setDenominatorFormat(old); old = improperFormat.getDenominatorFormat(); nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); improperFormat.setDenominatorFormat(nf); assertEquals(nf, improperFormat.getDenominatorFormat()); improperFormat.setDenominatorFormat(old); } public void testWholeFormat() { ProperFractionFormat format = (ProperFractionFormat)properFormat; NumberFormat old = format.getWholeFormat(); NumberFormat nf = NumberFormat.getInstance(); nf.setParseIntegerOnly(true); format.setWholeFormat(nf); assertEquals(nf, format.getWholeFormat()); format.setWholeFormat(old); } public void testLongFormat() { assertEquals("10 / 1", improperFormat.format(10l)); } public void testDoubleFormat() { assertEquals("355 / 113", improperFormat.format(FastMath.PI)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/special/ErfTest.java100644 1750 1750 17760 11532241241 26265 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 1054184 $ $Date: 2011-01-01 02:23:02 +0100 (sam. 01 janv. 2011) $ */ public class ErfTest extends TestCase { public void testErf0() throws MathException { double actual = Erf.erf(0.0); double expected = 0.0; assertEquals(expected, actual, 1.0e-15); assertEquals(1 - expected, Erf.erfc(0.0), 1.0e-15); } public void testErf1960() throws MathException { double x = 1.960 / FastMath.sqrt(2.0); double actual = Erf.erf(x); double expected = 0.95; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(x), 1.0e-15); actual = Erf.erf(-x); expected = -expected; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15); } public void testErf2576() throws MathException { double x = 2.576 / FastMath.sqrt(2.0); double actual = Erf.erf(x); double expected = 0.99; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(x), 1e-15); actual = Erf.erf(-x); expected = -expected; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15); } public void testErf2807() throws MathException { double x = 2.807 / FastMath.sqrt(2.0); double actual = Erf.erf(x); double expected = 0.995; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(x), 1.0e-15); actual = Erf.erf(-x); expected = -expected; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - actual, Erf.erfc(-x), 1.0e-15); } public void testErf3291() throws MathException { double x = 3.291 / FastMath.sqrt(2.0); double actual = Erf.erf(x); double expected = 0.999; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - expected, Erf.erfc(x), 1.0e-5); actual = Erf.erf(-x); expected = -expected; assertEquals(expected, actual, 1.0e-5); assertEquals(1 - expected, Erf.erfc(-x), 1.0e-5); } /** * MATH-301, MATH-456 */ public void testLargeValues() throws Exception { for (int i = 1; i < 200; i*=10) { double result = Erf.erf(i); assertFalse(Double.isNaN(result)); assertTrue(result > 0 && result <= 1); result = Erf.erf(-i); assertFalse(Double.isNaN(result)); assertTrue(result >= -1 && result < 0); result = Erf.erfc(i); assertFalse(Double.isNaN(result)); assertTrue(result >= 0 && result < 1); result = Erf.erfc(-i); assertFalse(Double.isNaN(result)); assertTrue(result >= 1 && result <= 2); } assertEquals(-1, Erf.erf(Double.NEGATIVE_INFINITY), 0); assertEquals(1, Erf.erf(Double.POSITIVE_INFINITY), 0); assertEquals(2, Erf.erfc(Double.NEGATIVE_INFINITY), 0); assertEquals(0, Erf.erfc(Double.POSITIVE_INFINITY), 0); } /** * Compare Erf.erf against reference values computed using GCC 4.2.1 (Apple OSX packaged version) * erfl (extended precision erf). */ public void testErfGnu() throws Exception { final double tol = 1E-15; final double[] gnuValues = new double[] {-1, -1, -1, -1, -1, -1, -1, -1, -0.99999999999999997848, -0.99999999999999264217, -0.99999999999846254017, -0.99999999980338395581, -0.99999998458274209971, -0.9999992569016276586, -0.99997790950300141459, -0.99959304798255504108, -0.99532226501895273415, -0.96610514647531072711, -0.84270079294971486948, -0.52049987781304653809, 0, 0.52049987781304653809, 0.84270079294971486948, 0.96610514647531072711, 0.99532226501895273415, 0.99959304798255504108, 0.99997790950300141459, 0.9999992569016276586, 0.99999998458274209971, 0.99999999980338395581, 0.99999999999846254017, 0.99999999999999264217, 0.99999999999999997848, 1, 1, 1, 1, 1, 1, 1, 1}; double x = -10d; for (int i = 0; i < 41; i++) { assertEquals(gnuValues[i], Erf.erf(x), tol); x += 0.5d; } } /** * Compare Erf.erfc against reference values computed using GCC 4.2.1 (Apple OSX packaged version) * erfcl (extended precision erfc). */ public void testErfcGnu() throws Exception { final double tol = 1E-15; final double[] gnuValues = new double[] { 2, 2, 2, 2, 2, 2, 2, 2, 1.9999999999999999785, 1.9999999999999926422, 1.9999999999984625402, 1.9999999998033839558, 1.9999999845827420998, 1.9999992569016276586, 1.9999779095030014146, 1.9995930479825550411, 1.9953222650189527342, 1.9661051464753107271, 1.8427007929497148695, 1.5204998778130465381, 1, 0.47950012218695346194, 0.15729920705028513051, 0.033894853524689272893, 0.0046777349810472658333, 0.00040695201744495893941, 2.2090496998585441366E-05, 7.4309837234141274516E-07, 1.5417257900280018858E-08, 1.966160441542887477E-10, 1.5374597944280348501E-12, 7.3578479179743980661E-15, 2.1519736712498913103E-17, 3.8421483271206474691E-20, 4.1838256077794144006E-23, 2.7766493860305691016E-26, 1.1224297172982927079E-29, 2.7623240713337714448E-33, 4.1370317465138102353E-37, 3.7692144856548799402E-41, 2.0884875837625447567E-45}; double x = -10d; for (int i = 0; i < 41; i++) { assertEquals(gnuValues[i], Erf.erfc(x), tol); x += 0.5d; } } /** * Tests erfc against reference data computed using Maple reported in Marsaglia, G,, * "Evaluating the Normal Distribution," Journal of Statistical Software, July, 2004. * http//www.jstatsoft.org/v11/a05/paper */ public void testErfcMaple() throws Exception { double[][] ref = new double[][] {{0.1, 4.60172162722971e-01}, {1.2, 1.15069670221708e-01}, {2.3, 1.07241100216758e-02}, {3.4, 3.36929265676881e-04}, {4.5, 3.39767312473006e-06}, {5.6, 1.07175902583109e-08}, {6.7, 1.04209769879652e-11}, {7.8, 3.09535877195870e-15}, {8.9, 2.79233437493966e-19}, {10.0, 7.61985302416053e-24}, {11.1, 6.27219439321703e-29}, {12.2, 1.55411978638959e-34}, {13.3, 1.15734162836904e-40}, {14.4, 2.58717592540226e-47}, {15.5, 1.73446079179387e-54}, {16.6, 3.48454651995041e-62} }; for (int i = 0; i < 15; i++) { final double result = 0.5*Erf.erfc(ref[i][0]/Math.sqrt(2)); assertEquals(ref[i][1], result, 1E-15); TestUtils.assertRelativelyEquals(ref[i][1], result, 1E-13); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/special/BetaTest.java100644 1750 1750 7140 11532241241 26373 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.TestUtils; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class BetaTest extends TestCase { /** * Constructor for BetaTest. * @param name */ public BetaTest(String name) { super(name); } private void testRegularizedBeta(double expected, double x, double a, double b) { try { double actual = Beta.regularizedBeta(x, a, b); TestUtils.assertEquals(expected, actual, 10e-15); } catch(MathException ex){ fail(ex.getMessage()); } } private void testLogBeta(double expected, double a, double b) { double actual = Beta.logBeta(a, b); TestUtils.assertEquals(expected, actual, 10e-15); } public void testRegularizedBetaNanPositivePositive() { testRegularizedBeta(Double.NaN, Double.NaN, 1.0, 1.0); } public void testRegularizedBetaPositiveNanPositive() { testRegularizedBeta(Double.NaN, 0.5, Double.NaN, 1.0); } public void testRegularizedBetaPositivePositiveNan() { testRegularizedBeta(Double.NaN, 0.5, 1.0, Double.NaN); } public void testRegularizedBetaNegativePositivePositive() { testRegularizedBeta(Double.NaN, -0.5, 1.0, 2.0); } public void testRegularizedBetaPositiveNegativePositive() { testRegularizedBeta(Double.NaN, 0.5, -1.0, 2.0); } public void testRegularizedBetaPositivePositiveNegative() { testRegularizedBeta(Double.NaN, 0.5, 1.0, -2.0); } public void testRegularizedBetaZeroPositivePositive() { testRegularizedBeta(0.0, 0.0, 1.0, 2.0); } public void testRegularizedBetaPositiveZeroPositive() { testRegularizedBeta(Double.NaN, 0.5, 0.0, 2.0); } public void testRegularizedBetaPositivePositiveZero() { testRegularizedBeta(Double.NaN, 0.5, 1.0, 0.0); } public void testRegularizedBetaPositivePositivePositive() { testRegularizedBeta(0.75, 0.5, 1.0, 2.0); } public void testLogBetaNanPositive() { testLogBeta(Double.NaN, Double.NaN, 2.0); } public void testLogBetaPositiveNan() { testLogBeta(Double.NaN, 1.0, Double.NaN); } public void testLogBetaNegativePositive() { testLogBeta(Double.NaN, -1.0, 2.0); } public void testLogBetaPositiveNegative() { testLogBeta(Double.NaN, 1.0, -2.0); } public void testLogBetaZeroPositive() { testLogBeta(Double.NaN, 0.0, 2.0); } public void testLogBetaPositiveZero() { testLogBeta(Double.NaN, 1.0, 0.0); } public void testLogBetaPositivePositive() { testLogBeta(-0.693147180559945, 1.0, 2.0); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/special/GammaTest.java100644 1750 1750 13730 11532241241 26564 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.TestUtils; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class GammaTest extends TestCase { public GammaTest(String name) { super(name); } private void testRegularizedGamma(double expected, double a, double x) { try { double actualP = Gamma.regularizedGammaP(a, x); double actualQ = Gamma.regularizedGammaQ(a, x); TestUtils.assertEquals(expected, actualP, 10e-15); TestUtils.assertEquals(actualP, 1.0 - actualQ, 10e-15); } catch(MathException ex){ fail(ex.getMessage()); } } private void testLogGamma(double expected, double x) { double actual = Gamma.logGamma(x); TestUtils.assertEquals(expected, actual, 10e-15); } public void testRegularizedGammaNanPositive() { testRegularizedGamma(Double.NaN, Double.NaN, 1.0); } public void testRegularizedGammaPositiveNan() { testRegularizedGamma(Double.NaN, 1.0, Double.NaN); } public void testRegularizedGammaNegativePositive() { testRegularizedGamma(Double.NaN, -1.5, 1.0); } public void testRegularizedGammaPositiveNegative() { testRegularizedGamma(Double.NaN, 1.0, -1.0); } public void testRegularizedGammaZeroPositive() { testRegularizedGamma(Double.NaN, 0.0, 1.0); } public void testRegularizedGammaPositiveZero() { testRegularizedGamma(0.0, 1.0, 0.0); } public void testRegularizedGammaPositivePositive() { testRegularizedGamma(0.632120558828558, 1.0, 1.0); } public void testLogGammaNan() { testLogGamma(Double.NaN, Double.NaN); } public void testLogGammaNegative() { testLogGamma(Double.NaN, -1.0); } public void testLogGammaZero() { testLogGamma(Double.NaN, 0.0); } public void testLogGammaPositive() { testLogGamma(0.6931471805599457, 3.0); } public void testDigammaLargeArgs() { double eps = 1e-8; assertEquals(4.6001618527380874002, Gamma.digamma(100), eps); assertEquals(3.9019896734278921970, Gamma.digamma(50), eps); assertEquals(2.9705239922421490509, Gamma.digamma(20), eps); assertEquals(2.9958363947076465821, Gamma.digamma(20.5), eps); assertEquals(2.2622143570941481605, Gamma.digamma(10.1), eps); assertEquals(2.1168588189004379233, Gamma.digamma(8.8), eps); assertEquals(1.8727843350984671394, Gamma.digamma(7), eps); assertEquals(0.42278433509846713939, Gamma.digamma(2), eps); assertEquals(-100.56088545786867450, Gamma.digamma(0.01), eps); assertEquals(-4.0390398965921882955, Gamma.digamma(-0.8), eps); assertEquals(4.2003210041401844726, Gamma.digamma(-6.3), eps); } public void testDigammaSmallArgs() { // values for negative powers of 10 from 1 to 30 as computed by webMathematica with 20 digits // see functions.wolfram.com double[] expected = {-10.423754940411076795, -100.56088545786867450, -1000.5755719318103005, -10000.577051183514335, -100000.57719921568107, -1.0000005772140199687e6, -1.0000000577215500408e7, -1.0000000057721564845e8, -1.0000000005772156633e9, -1.0000000000577215665e10, -1.0000000000057721566e11, -1.0000000000005772157e12, -1.0000000000000577216e13, -1.0000000000000057722e14, -1.0000000000000005772e15, -1e+16, -1e+17, -1e+18, -1e+19, -1e+20, -1e+21, -1e+22, -1e+23, -1e+24, -1e+25, -1e+26, -1e+27, -1e+28, -1e+29, -1e+30}; for (double n = 1; n < 30; n++) { checkRelativeError(String.format("Test %.0f: ", n), expected[(int) (n - 1)], Gamma.digamma(FastMath.pow(10.0, -n)), 1e-8); } } public void testTrigamma() { double eps = 1e-8; // computed using webMathematica. For example, to compute trigamma($i) = Polygamma(1, $i), use // // http://functions.wolfram.com/webMathematica/Evaluated.jsp?name=PolyGamma2&plottype=0&vars={%221%22,%22$i%22}&digits=20 double[] data = { 1e-4, 1.0000000164469368793e8, 1e-3, 1.0000016425331958690e6, 1e-2, 10001.621213528313220, 1e-1, 101.43329915079275882, 1, 1.6449340668482264365, 2, 0.64493406684822643647, 3, 0.39493406684822643647, 4, 0.28382295573711532536, 5, 0.22132295573711532536, 10, 0.10516633568168574612, 20, 0.051270822935203119832, 50, 0.020201333226697125806, 100, 0.010050166663333571395 }; for (int i = data.length - 2; i >= 0; i -= 2) { assertEquals(String.format("trigamma %.0f", data[i]), data[i + 1], Gamma.trigamma(data[i]), eps); } } private void checkRelativeError(String msg, double expected, double actual, double tolerance) { assertEquals(msg, expected, actual, FastMath.abs(tolerance * actual)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/RetryTestCase.java100644 1750 1750 3363 11532241244 26007 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import junit.framework.AssertionFailedError; import junit.framework.TestCase; /** * A TestCase that retries tests when assertions fail. *

                  * If one or more tests throw an AssertionFailedError, all tests are * repeated one time. *

                  * Errors or exceptions other than AssertionFailedError do not lead to retries. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class RetryTestCase extends TestCase { public RetryTestCase() { super(); } public RetryTestCase(String arg0) { super(arg0); } /** * Override runTest() to catch AssertionFailedError and retry */ @Override protected void runTest() throws Throwable { try { super.runTest(); } catch (AssertionFailedError err) { // System.out.println("Retrying " + this.getName()); super.runTest(); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/MaxIterationsExceededExceptionTest.java100644 1750 1750 4067 11532241244 32205 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.util.Locale; import org.apache.commons.math.exception.util.LocalizedFormats; import junit.framework.TestCase; /** * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class MaxIterationsExceededExceptionTest extends TestCase { public void testSimpleConstructor(){ MaxIterationsExceededException ex = new MaxIterationsExceededException(1000000); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("1,000,000") > 0); assertEquals(1000000, ex.getMaxIterations()); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } public void testComplexConstructor(){ MaxIterationsExceededException ex = new MaxIterationsExceededException(1000000, LocalizedFormats.NON_CONVERGENT_CONTINUED_FRACTION, 1234567); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("1,000,000") < 0); assertTrue(ex.getMessage().indexOf("1,234,567") > 0); assertEquals(1000000, ex.getMaxIterations()); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/TransformerMapTest.java100644 1750 1750 7377 11532241244 30034 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.TestUtils; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class TransformerMapTest extends TestCase { /** * */ public void testPutTransformer(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertEquals(expected, map.getTransformer(TransformerMapTest.class)); } /** * */ public void testContainsClass(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.containsClass(TransformerMapTest.class)); } /** * */ public void testContainsTransformer(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.containsTransformer(expected)); } /** * */ public void testRemoveTransformer(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.containsClass(TransformerMapTest.class)); assertTrue(map.containsTransformer(expected)); map.removeTransformer(TransformerMapTest.class); assertFalse(map.containsClass(TransformerMapTest.class)); assertFalse(map.containsTransformer(expected)); } /** * */ public void testClear(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.containsClass(TransformerMapTest.class)); map.clear(); assertFalse(map.containsClass(TransformerMapTest.class)); } /** * */ public void testClasses(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.classes().contains(TransformerMapTest.class)); } /** * */ public void testTransformers(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertTrue(map.transformers().contains(expected)); } public void testSerial(){ NumberTransformer expected = new DefaultTransformer(); TransformerMap map = new TransformerMap(); map.putTransformer(TransformerMapTest.class, expected); assertEquals(map, TestUtils.serializeAndRecover(map)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/FastMathStrictComparisonTest.java100644 1750 1750 24374 11532241244 32043 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; /** * Test to compare FastMath results against StrictMath results for boundary values. *

                  * Running all tests independently:
                  * {@code mvn test -Dtest=FastMathStrictComparisonTest}
                  * or just run tests against a single method (e.g. scalb):
                  * {@code mvn test -Dtest=FastMathStrictComparisonTest -DargLine="-DtestMethod=scalb"} */ @RunWith(Parameterized.class) public class FastMathStrictComparisonTest { // Values which often need special handling private static final Double[] DOUBLE_SPECIAL_VALUES = { -0.0, +0.0, // 1,2 Double.NaN, // 3 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, // 4,5 -Double.MAX_VALUE, Double.MAX_VALUE, // 6,7 // decreasing order of absolute value to help catch first failure -MathUtils.EPSILON, MathUtils.EPSILON, // 8,9 -MathUtils.SAFE_MIN, MathUtils.SAFE_MIN, // 10,11 -Double.MIN_VALUE, Double.MIN_VALUE, // 12,13 }; private static final Float [] FLOAT_SPECIAL_VALUES = { -0.0f, +0.0f, // 1,2 Float.NaN, // 3 Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, // 4,5 Float.MIN_VALUE, Float.MAX_VALUE, // 6,7 -Float.MIN_VALUE, -Float.MAX_VALUE, // 8,9 }; private static final Object [] LONG_SPECIAL_VALUES = { -1,0,1, // 1,2,3 Long.MIN_VALUE, Long.MAX_VALUE, // 4,5 }; private static final Object[] INT_SPECIAL_VALUES = { -1,0,1, // 1,2,3 Integer.MIN_VALUE, Integer.MAX_VALUE, // 4,5 }; private final Method mathMethod; private final Method fastMethod; private final Type[] types; private final Object[][] valueArrays; public FastMathStrictComparisonTest(Method m, Method f, Type[] types, Object[][] data) throws Exception{ this.mathMethod=m; this.fastMethod=f; this.types=types; this.valueArrays=data; } @Test public void test1() throws Exception{ setupMethodCall(mathMethod, fastMethod, types, valueArrays); } private static boolean isNumber(Double d) { return !(d.isInfinite() || d.isNaN()); } private static boolean isNumber(Float f) { return !(f.isInfinite() || f.isNaN()); } private static void reportFailedResults(Method mathMethod, Object[] params, Object expected, Object actual, int[] entries){ final String methodName = mathMethod.getName(); String format = null; long actL=0; long expL=0; if (expected instanceof Double) { Double exp = (Double) expected; Double act = (Double) actual; if (isNumber(exp) && isNumber(act) && exp != 0) { // show difference as hex actL = Double.doubleToLongBits(act); expL = Double.doubleToLongBits(exp); if (Math.abs(actL-expL)==1) { // Not 100% sure off-by-one errors are allowed everywhere, so only allow for these methods if (methodName.equals("toRadians") || methodName.equals("atan2")) { return; } } format = "%016x"; } } else if (expected instanceof Float ){ Float exp = (Float) expected; Float act = (Float) actual; if (isNumber(exp) && isNumber(act) && exp != 0) { // show difference as hex actL = Float.floatToIntBits(act); expL = Float.floatToIntBits(exp); format = "%08x"; } } StringBuilder sb = new StringBuilder(); sb.append(mathMethod.getReturnType().getSimpleName()); sb.append(" "); sb.append(methodName); sb.append("("); String sep = ""; for(Object o : params){ sb.append(sep); sb.append(o); sep=", "; } sb.append(") expected "); if (format != null){ sb.append(String.format(format, expL)); } else { sb.append(expected); } sb.append(" actual "); if (format != null){ sb.append(String.format(format, actL)); } else { sb.append(actual); } sb.append(" entries "); sb.append(Arrays.toString(entries)); String message = sb.toString(); final boolean fatal = true; if (fatal) { Assert.fail(message); } else { System.out.println(message); } } private static void callMethods(Method mathMethod, Method fastMethod, Object[] params, int[] entries) throws IllegalAccessException, InvocationTargetException { try { Object expected = mathMethod.invoke(mathMethod, params); Object actual = fastMethod.invoke(mathMethod, params); if (!expected.equals(actual)) { reportFailedResults(mathMethod, params, expected, actual, entries); } } catch (IllegalArgumentException e) { Assert.fail(mathMethod+" "+e); } } private static void setupMethodCall(Method mathMethod, Method fastMethod, Type[] types, Object[][] valueArrays) throws Exception { Object[] params = new Object[types.length]; int entry1 = 0; int[] entries = new int[types.length]; for(Object d : valueArrays[0]) { entry1++; params[0] = d; entries[0] = entry1; if (params.length > 1){ int entry2 = 0; for(Object d1 : valueArrays[1]) { entry2++; params[1] = d1; entries[1] = entry2; callMethods(mathMethod, fastMethod, params, entries); } } else { callMethods(mathMethod, fastMethod, params, entries); } } } @Parameters public static List data() throws Exception { String singleMethod = System.getProperty("testMethod"); List list = new ArrayList(); for(Method mathMethod : StrictMath.class.getDeclaredMethods()) { method: if (Modifier.isPublic(mathMethod.getModifiers())){// Only test public methods Type []types = mathMethod.getGenericParameterTypes(); if (types.length >=1) { // Only check methods with at least one parameter try { // Get the corresponding FastMath method Method fastMethod = FastMath.class.getDeclaredMethod(mathMethod.getName(), (Class[]) types); if (Modifier.isPublic(fastMethod.getModifiers())) { // It must be public too if (singleMethod != null && !fastMethod.getName().equals(singleMethod)) { break method; } Object [][] values = new Object[types.length][]; int index = 0; for(Type t : types) { if (t.equals(double.class)){ values[index]=DOUBLE_SPECIAL_VALUES; } else if (t.equals(float.class)) { values[index]=FLOAT_SPECIAL_VALUES; } else if (t.equals(long.class)) { values[index]=LONG_SPECIAL_VALUES; } else if (t.equals(int.class)) { values[index]=INT_SPECIAL_VALUES; } else { System.out.println("Cannot handle class "+t+" for "+mathMethod); break method; } index++; } // System.out.println(fastMethod); /* * The current implementation runs each method as a separate test. * Could be amended to run each value as a separate test */ list.add(new Object[]{mathMethod, fastMethod, types, values}); // setupMethodCall(mathMethod, fastMethod, params, data); } else { System.out.println("Cannot find public FastMath method corresponding to: "+mathMethod); } } catch (NoSuchMethodException e) { System.out.println("Cannot find FastMath method corresponding to: "+mathMethod); } } } } return list; } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/FastMathTest.java100644 1750 1750 140635 11532241244 26636 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import org.apache.commons.math.dfp.Dfp; import org.apache.commons.math.dfp.DfpField; import org.apache.commons.math.dfp.DfpMath; import org.apache.commons.math.random.MersenneTwister; import org.apache.commons.math.random.RandomGenerator; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; public class FastMathTest { private static final double MAX_ERROR_ULP = 0.51; private static final int NUMBER_OF_TRIALS = 1000; private DfpField field; private RandomGenerator generator; @Before public void setUp() { field = new DfpField(40); generator = new MersenneTwister(6176597458463500194l); } @Test public void testMinMaxDouble() { double[][] pairs = { { -50.0, 50.0 }, { Double.POSITIVE_INFINITY, 1.0 }, { Double.NEGATIVE_INFINITY, 1.0 }, { Double.NaN, 1.0 }, { Double.POSITIVE_INFINITY, 0.0 }, { Double.NEGATIVE_INFINITY, 0.0 }, { Double.NaN, 0.0 }, { Double.NaN, Double.NEGATIVE_INFINITY }, { Double.NaN, Double.POSITIVE_INFINITY }, { MathUtils.SAFE_MIN, MathUtils.EPSILON } }; for (double[] pair : pairs) { Assert.assertEquals("min(" + pair[0] + ", " + pair[1] + ")", Math.min(pair[0], pair[1]), FastMath.min(pair[0], pair[1]), MathUtils.EPSILON); Assert.assertEquals("min(" + pair[1] + ", " + pair[0] + ")", Math.min(pair[1], pair[0]), FastMath.min(pair[1], pair[0]), MathUtils.EPSILON); Assert.assertEquals("max(" + pair[0] + ", " + pair[1] + ")", Math.max(pair[0], pair[1]), FastMath.max(pair[0], pair[1]), MathUtils.EPSILON); Assert.assertEquals("max(" + pair[1] + ", " + pair[0] + ")", Math.max(pair[1], pair[0]), FastMath.max(pair[1], pair[0]), MathUtils.EPSILON); } } @Test public void testMinMaxFloat() { float[][] pairs = { { -50.0f, 50.0f }, { Float.POSITIVE_INFINITY, 1.0f }, { Float.NEGATIVE_INFINITY, 1.0f }, { Float.NaN, 1.0f }, { Float.POSITIVE_INFINITY, 0.0f }, { Float.NEGATIVE_INFINITY, 0.0f }, { Float.NaN, 0.0f }, { Float.NaN, Float.NEGATIVE_INFINITY }, { Float.NaN, Float.POSITIVE_INFINITY } }; for (float[] pair : pairs) { Assert.assertEquals("min(" + pair[0] + ", " + pair[1] + ")", Math.min(pair[0], pair[1]), FastMath.min(pair[0], pair[1]), MathUtils.EPSILON); Assert.assertEquals("min(" + pair[1] + ", " + pair[0] + ")", Math.min(pair[1], pair[0]), FastMath.min(pair[1], pair[0]), MathUtils.EPSILON); Assert.assertEquals("max(" + pair[0] + ", " + pair[1] + ")", Math.max(pair[0], pair[1]), FastMath.max(pair[0], pair[1]), MathUtils.EPSILON); Assert.assertEquals("max(" + pair[1] + ", " + pair[0] + ")", Math.max(pair[1], pair[0]), FastMath.max(pair[1], pair[0]), MathUtils.EPSILON); } } @Test public void testConstants() { Assert.assertEquals(Math.PI, FastMath.PI, 1.0e-20); Assert.assertEquals(Math.E, FastMath.E, 1.0e-20); } @Test public void testAtan2() { double y1 = 1.2713504628280707e10; double x1 = -5.674940885228782e-10; Assert.assertEquals(Math.atan2(y1, x1), FastMath.atan2(y1, x1), 2 * MathUtils.EPSILON); double y2 = 0.0; double x2 = Double.POSITIVE_INFINITY; Assert.assertEquals(Math.atan2(y2, x2), FastMath.atan2(y2, x2), MathUtils.SAFE_MIN); } @Test public void testHyperbolic() { double maxErr = 0; for (double x = -30; x < 30; x += 0.001) { double tst = FastMath.sinh(x); double ref = Math.sinh(x); maxErr = FastMath.max(maxErr, FastMath.abs(ref - tst) / FastMath.ulp(ref)); } Assert.assertEquals(0, maxErr, 2); maxErr = 0; for (double x = -30; x < 30; x += 0.001) { double tst = FastMath.cosh(x); double ref = Math.cosh(x); maxErr = FastMath.max(maxErr, FastMath.abs(ref - tst) / FastMath.ulp(ref)); } Assert.assertEquals(0, maxErr, 2); maxErr = 0; for (double x = -0.5; x < 0.5; x += 0.001) { double tst = FastMath.tanh(x); double ref = Math.tanh(x); maxErr = FastMath.max(maxErr, FastMath.abs(ref - tst) / FastMath.ulp(ref)); } Assert.assertEquals(0, maxErr, 4); } @Test public void testHyperbolicInverses() { double maxErr = 0; for (double x = -30; x < 30; x += 0.01) { maxErr = FastMath.max(maxErr, FastMath.abs(x - FastMath.sinh(FastMath.asinh(x))) / (2 * FastMath.ulp(x))); } Assert.assertEquals(0, maxErr, 3); maxErr = 0; for (double x = 1; x < 30; x += 0.01) { maxErr = FastMath.max(maxErr, FastMath.abs(x - FastMath.cosh(FastMath.acosh(x))) / (2 * FastMath.ulp(x))); } Assert.assertEquals(0, maxErr, 2); maxErr = 0; for (double x = -1 + MathUtils.EPSILON; x < 1 - MathUtils.EPSILON; x += 0.0001) { maxErr = FastMath.max(maxErr, FastMath.abs(x - FastMath.tanh(FastMath.atanh(x))) / (2 * FastMath.ulp(x))); } Assert.assertEquals(0, maxErr, 2); } @Test public void testLogAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = Math.exp(generator.nextDouble() * 1416.0 - 708.0) * generator.nextDouble(); // double x = generator.nextDouble()*2.0; double tst = FastMath.log(x); double ref = DfpMath.log(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0.0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double .doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.log(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("log() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testLog10Accuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = Math.exp(generator.nextDouble() * 1416.0 - 708.0) * generator.nextDouble(); // double x = generator.nextDouble()*2.0; double tst = FastMath.log10(x); double ref = DfpMath.log(field.newDfp(x)).divide(DfpMath.log(field.newDfp("10"))).toDouble(); double err = (tst - ref) / ref; if (err != 0.0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.log(field.newDfp(x)).divide(DfpMath.log(field.newDfp("10")))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("log10() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testLog1pAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = Math.exp(generator.nextDouble() * 10.0 - 5.0) * generator.nextDouble(); // double x = generator.nextDouble()*2.0; double tst = FastMath.log1p(x); double ref = DfpMath.log(field.newDfp(x).add(field.getOne())).toDouble(); double err = (tst - ref) / ref; if (err != 0.0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.log(field.newDfp(x).add(field.getOne()))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("log1p() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testLogSpecialCases() { double x; x = FastMath.log(0.0); if (x != Double.NEGATIVE_INFINITY) throw new RuntimeException("Log of zero should be -Inf"); x = FastMath.log(-0.0); if (x != Double.NEGATIVE_INFINITY) throw new RuntimeException("Log of zero should be -Inf"); x = FastMath.log(Double.NaN); if (x == x) throw new RuntimeException("Log of NaN should be NaN"); x = FastMath.log(-1.0); if (x == x) throw new RuntimeException("Log of negative number should be NaN"); x = FastMath.log(Double.MIN_VALUE); if (x != -744.4400719213812) throw new RuntimeException( "Log of Double.MIN_VALUE should be -744.4400719213812"); x = FastMath.log(-1.0); if (x == x) throw new RuntimeException("Log of negative number should be NaN"); x = FastMath.log(Double.POSITIVE_INFINITY); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("Log of infinity should be infinity"); } @Test public void testExpSpecialCases() { double x; /* Smallest value that will round up to Double.MIN_VALUE */ x = FastMath.exp(-745.1332191019411); if (x != Double.MIN_VALUE) throw new RuntimeException( "exp(-745.1332191019411) should be Double.MIN_VALUE"); x = FastMath.exp(-745.1332191019412); if (x != 0.0) throw new RuntimeException("exp(-745.1332191019412) should be 0.0"); x = FastMath.exp(Double.NaN); if (x == x) throw new RuntimeException("exp of NaN should be NaN"); x = FastMath.exp(Double.POSITIVE_INFINITY); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("exp of infinity should be infinity"); x = FastMath.exp(Double.NEGATIVE_INFINITY); if (x != 0.0) throw new RuntimeException("exp of -infinity should be 0.0"); x = FastMath.exp(1.0); if (x != Math.E) throw new RuntimeException("exp(1) should be Math.E"); } @Test public void testPowSpecialCases() { double x; x = FastMath.pow(-1.0, 0.0); if (x != 1.0) throw new RuntimeException("pow(x, 0) should be 1.0"); x = FastMath.pow(-1.0, -0.0); if (x != 1.0) throw new RuntimeException("pow(x, -0) should be 1.0"); x = FastMath.pow(Math.PI, 1.0); if (x != Math.PI) throw new RuntimeException("pow(PI, 1.0) should be PI"); x = FastMath.pow(-Math.PI, 1.0); if (x != -Math.PI) throw new RuntimeException("pow(-PI, 1.0) should be PI"); x = FastMath.pow(Math.PI, Double.NaN); if (x == x) throw new RuntimeException("pow(PI, NaN) should be NaN"); x = FastMath.pow(Double.NaN, Math.PI); if (x == x) throw new RuntimeException("pow(NaN, PI) should be NaN"); x = FastMath.pow(2.0, Double.POSITIVE_INFINITY); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(2.0, Infinity) should be Infinity"); x = FastMath.pow(0.5, Double.NEGATIVE_INFINITY); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(0.5, -Infinity) should be Infinity"); x = FastMath.pow(0.5, Double.POSITIVE_INFINITY); if (x != 0.0) throw new RuntimeException("pow(0.5, Infinity) should be 0.0"); x = FastMath.pow(2.0, Double.NEGATIVE_INFINITY); if (x != 0.0) throw new RuntimeException("pow(2.0, -Infinity) should be 0.0"); x = FastMath.pow(0.0, 0.5); if (x != 0.0) throw new RuntimeException("pow(0.0, 0.5) should be 0.0"); x = FastMath.pow(Double.POSITIVE_INFINITY, -0.5); if (x != 0.0) throw new RuntimeException("pow(Inf, -0.5) should be 0.0"); x = FastMath.pow(0.0, -0.5); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(0.0, -0.5) should be Inf"); x = FastMath.pow(Double.POSITIVE_INFINITY, 0.5); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(Inf, 0.5) should be Inf"); x = FastMath.pow(-0.0, -3.0); if (x != Double.NEGATIVE_INFINITY) throw new RuntimeException("pow(-0.0, -3.0) should be -Inf"); x = FastMath.pow(Double.NEGATIVE_INFINITY, 3.0); if (x != Double.NEGATIVE_INFINITY) throw new RuntimeException("pow(-Inf, -3.0) should be -Inf"); x = FastMath.pow(-0.0, -3.5); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(-0.0, -3.5) should be Inf"); x = FastMath.pow(Double.POSITIVE_INFINITY, 3.5); if (x != Double.POSITIVE_INFINITY) throw new RuntimeException("pow(Inf, 3.5) should be Inf"); x = FastMath.pow(-2.0, 3.0); if (x != -8.0) throw new RuntimeException("pow(-2.0, 3.0) should be -8.0"); x = FastMath.pow(-2.0, 3.5); if (x == x) throw new RuntimeException("pow(-2.0, 3.5) should be NaN"); } @Test public void testAtan2SpecialCases() { double x; x = FastMath.atan2(Double.NaN, 0.0); if (x == x) throw new RuntimeException("atan2(NaN, 0.0) should be NaN"); x = FastMath.atan2(0.0, Double.NaN); if (x == x) throw new RuntimeException("atan2(0.0, NaN) should be NaN"); x = FastMath.atan2(0.0, 0.0); if (x != 0.0 || 1 / x != Double.POSITIVE_INFINITY) throw new RuntimeException("atan2(0.0, 0.0) should be 0.0"); x = FastMath.atan2(0.0, 0.001); if (x != 0.0 || 1 / x != Double.POSITIVE_INFINITY) throw new RuntimeException("atan2(0.0, 0.001) should be 0.0"); x = FastMath.atan2(0.1, Double.POSITIVE_INFINITY); if (x != 0.0 || 1 / x != Double.POSITIVE_INFINITY) throw new RuntimeException("atan2(0.1, +Inf) should be 0.0"); x = FastMath.atan2(-0.0, 0.0); if (x != 0.0 || 1 / x != Double.NEGATIVE_INFINITY) throw new RuntimeException("atan2(-0.0, 0.0) should be -0.0"); x = FastMath.atan2(-0.0, 0.001); if (x != 0.0 || 1 / x != Double.NEGATIVE_INFINITY) throw new RuntimeException("atan2(-0.0, 0.001) should be -0.0"); x = FastMath.atan2(-0.1, Double.POSITIVE_INFINITY); if (x != 0.0 || 1 / x != Double.NEGATIVE_INFINITY) throw new RuntimeException("atan2(-0.0, +Inf) should be -0.0"); x = FastMath.atan2(0.0, -0.0); if (x != Math.PI) throw new RuntimeException("atan2(0.0, -0.0) should be PI"); x = FastMath.atan2(0.1, Double.NEGATIVE_INFINITY); if (x != Math.PI) throw new RuntimeException("atan2(0.1, -Inf) should be PI"); x = FastMath.atan2(-0.0, -0.0); if (x != -Math.PI) throw new RuntimeException("atan2(-0.0, -0.0) should be -PI"); x = FastMath.atan2(-0.1, Double.NEGATIVE_INFINITY); if (x != -Math.PI) throw new RuntimeException("atan2(0.1, -Inf) should be -PI"); x = FastMath.atan2(0.1, 0.0); if (x != Math.PI / 2) throw new RuntimeException("atan2(0.1, 0.0) should be PI/2"); x = FastMath.atan2(0.1, -0.0); if (x != Math.PI / 2) throw new RuntimeException("atan2(0.1, -0.0) should be PI/2"); x = FastMath.atan2(Double.POSITIVE_INFINITY, 0.1); if (x != Math.PI / 2) throw new RuntimeException("atan2(Inf, 0.1) should be PI/2"); x = FastMath.atan2(Double.POSITIVE_INFINITY, -0.1); if (x != Math.PI / 2) throw new RuntimeException("atan2(Inf, -0.1) should be PI/2"); x = FastMath.atan2(-0.1, 0.0); if (x != -Math.PI / 2) throw new RuntimeException("atan2(-0.1, 0.0) should be -PI/2"); x = FastMath.atan2(-0.1, -0.0); if (x != -Math.PI / 2) throw new RuntimeException("atan2(-0.1, -0.0) should be -PI/2"); x = FastMath.atan2(Double.NEGATIVE_INFINITY, 0.1); if (x != -Math.PI / 2) throw new RuntimeException("atan2(-Inf, 0.1) should be -PI/2"); x = FastMath.atan2(Double.NEGATIVE_INFINITY, -0.1); if (x != -Math.PI / 2) throw new RuntimeException("atan2(-Inf, -0.1) should be -PI/2"); x = FastMath.atan2(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); if (x != Math.PI / 4) throw new RuntimeException("atan2(Inf, Inf) should be PI/4"); x = FastMath.atan2(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); if (x != Math.PI * 3.0 / 4.0) throw new RuntimeException("atan2(Inf, -Inf) should be PI * 3/4"); x = FastMath.atan2(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); if (x != -Math.PI / 4) throw new RuntimeException("atan2(-Inf, Inf) should be -PI/4"); x = FastMath.atan2(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); if (x != -Math.PI * 3.0 / 4.0) throw new RuntimeException("atan2(-Inf, -Inf) should be -PI * 3/4"); } @Test public void testPowAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = (generator.nextDouble() * 2.0 + 0.25); double y = (generator.nextDouble() * 1200.0 - 600.0) * generator.nextDouble(); /* * double x = FastMath.floor(generator.nextDouble()*1024.0 - 512.0); double * y; if (x != 0) y = FastMath.floor(512.0 / FastMath.abs(x)); else * y = generator.nextDouble()*1200.0; y = y - y/2; x = FastMath.pow(2.0, x) * * generator.nextDouble(); y = y * generator.nextDouble(); */ // double x = generator.nextDouble()*2.0; double tst = FastMath.pow(x, y); double ref = DfpMath.pow(field.newDfp(x), field.newDfp(y)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double .doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.pow(field.newDfp(x), field.newDfp(y))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + y + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("pow() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testExpAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.exp(x); double ref = DfpMath.exp(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.exp(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("exp() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testSinAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); double x = ((generator.nextDouble() * Math.PI) - Math.PI / 2.0) * Math.pow(2, 21) * generator.nextDouble(); // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.sin(x); double ref = DfpMath.sin(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.sin(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("sin() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testCosAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); double x = ((generator.nextDouble() * Math.PI) - Math.PI / 2.0) * Math.pow(2, 21) * generator.nextDouble(); // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.cos(x); double ref = DfpMath.cos(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.cos(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("cos() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testTanAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); double x = ((generator.nextDouble() * Math.PI) - Math.PI / 2.0) * Math.pow(2, 12) * generator.nextDouble(); // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.tan(x); double ref = DfpMath.tan(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.tan(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("tan() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testAtanAccuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); // double x = ((generator.nextDouble() * Math.PI) - Math.PI/2.0) * // generator.nextDouble(); double x = ((generator.nextDouble() * 16.0) - 8.0) * generator.nextDouble(); // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.atan(x); double ref = DfpMath.atan(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.atan(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("atan() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testAtan2Accuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = ((generator.nextDouble() * 1416.0) - 708.0) * generator.nextDouble(); double x = generator.nextDouble() - 0.5; double y = generator.nextDouble() - 0.5; // double x = (generator.nextDouble() * 20.0) - 10.0; // double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.atan2(y, x); Dfp refdfp = DfpMath.atan(field.newDfp(y) .divide(field.newDfp(x))); /* Make adjustments for sign */ if (x < 0.0) { if (y > 0.0) refdfp = field.getPi().add(refdfp); else refdfp = refdfp.subtract(field.getPi()); } double ref = refdfp.toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double .doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(refdfp).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + y + "\t" + tst + "\t" + ref + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("atan2() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testExpm1Accuracy() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { /* double x = 1.0 + i/1024.0/2.0; */ // double x = (generator.nextDouble() * 20.0) - 10.0; double x = ((generator.nextDouble() * 16.0) - 8.0) * generator.nextDouble(); /* double x = 3.0 / 512.0 * i - 3.0; */ double tst = FastMath.expm1(x); double ref = DfpMath.exp(field.newDfp(x)).subtract(field.getOne()).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double .doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.exp(field.newDfp(x)).subtract(field.getOne())).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("expm1() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testAsinAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); double tst = FastMath.asin(x); double ref = DfpMath.asin(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.asin(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("asin() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testAcosAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 2.0) - 1.0) * generator.nextDouble(); double tst = FastMath.acos(x); double ref = DfpMath.acos(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.acos(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("acos() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } private Dfp cosh(Dfp x) { return DfpMath.exp(x).add(DfpMath.exp(x.negate())).divide(2); } private Dfp sinh(Dfp x) { return DfpMath.exp(x).subtract(DfpMath.exp(x.negate())).divide(2); } private Dfp tanh(Dfp x) { return sinh(x).divide(cosh(x)); } @Test public void testSinhAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 16.0) - 8.0) * generator.nextDouble(); double tst = FastMath.sinh(x); double ref = sinh(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(sinh(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("sinh() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testCoshAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 16.0) - 8.0) * generator.nextDouble(); double tst = FastMath.cosh(x); double ref = cosh(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(cosh(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("cosh() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testTanhAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 16.0) - 8.0) * generator.nextDouble(); double tst = FastMath.tanh(x); double ref = tanh(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(tanh(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("tanh() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testCbrtAccuracy() { double maxerrulp = 0.0; for (int i=0; i<10000; i++) { double x = ((generator.nextDouble() * 200.0) - 100.0) * generator.nextDouble(); double tst = FastMath.cbrt(x); double ref = cbrt(field.newDfp(x)).toDouble(); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(cbrt(field.newDfp(x))).divide(field.newDfp(ulp)).toDouble(); //System.out.println(x+"\t"+tst+"\t"+ref+"\t"+err+"\t"+errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("cbrt() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } private Dfp cbrt(Dfp x) { boolean negative=false; if (x.lessThan(field.getZero())) { negative = true; x = x.negate(); } Dfp y = DfpMath.pow(x, field.getOne().divide(3)); if (negative) { y = y.negate(); } return y; } @Test public void testToDegrees() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = generator.nextDouble(); double tst = field.newDfp(x).multiply(180).divide(field.getPi()).toDouble(); double ref = FastMath.toDegrees(x); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double.doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.exp(field.newDfp(x)).subtract(field.getOne())).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("toDegrees() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testToRadians() { double maxerrulp = 0.0; for (int i = 0; i < NUMBER_OF_TRIALS; i++) { double x = generator.nextDouble(); double tst = field.newDfp(x).multiply(field.getPi()).divide(180).toDouble(); double ref = FastMath.toRadians(x); double err = (tst - ref) / ref; if (err != 0) { double ulp = Math.abs(ref - Double.longBitsToDouble((Double .doubleToLongBits(ref) ^ 1))); double errulp = field.newDfp(tst).subtract(DfpMath.exp(field.newDfp(x)).subtract(field.getOne())).divide(field.newDfp(ulp)).toDouble(); // System.out.println(x + "\t" + tst + "\t" + ref + "\t" + err + "\t" + errulp); maxerrulp = Math.max(maxerrulp, Math.abs(errulp)); } } Assert.assertTrue("toRadians() had errors in excess of " + MAX_ERROR_ULP + " ULP", maxerrulp < MAX_ERROR_ULP); } @Test public void testNextAfter() { // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000 Assert.assertEquals(16.0, FastMath.nextAfter(15.999999999999998, 34.27555555555555), 0.0); // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 34.27555555555555), 0.0); // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe Assert.assertEquals(15.999999999999996, FastMath.nextAfter(15.999999999999998, 2.142222222222222), 0.0); // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 2.142222222222222), 0.0); // 0x4020000000000000 0x404123456789abcd -> 4020000000000001 Assert.assertEquals(8.000000000000002, FastMath.nextAfter(8.0, 34.27555555555555), 0.0); // 0xc020000000000000 0x404123456789abcd -> c01fffffffffffff Assert.assertEquals(-7.999999999999999, FastMath.nextAfter(-8.0, 34.27555555555555), 0.0); // 0x4020000000000000 0x400123456789abcd -> 401fffffffffffff Assert.assertEquals(7.999999999999999, FastMath.nextAfter(8.0, 2.142222222222222), 0.0); // 0xc020000000000000 0x400123456789abcd -> c01fffffffffffff Assert.assertEquals(-7.999999999999999, FastMath.nextAfter(-8.0, 2.142222222222222), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a224 -> 3f2e43753d36a224 Assert.assertEquals(2.308922399667661E-4, FastMath.nextAfter(2.3089223996676606E-4, 2.308922399667661E-4), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a223 -> 3f2e43753d36a223 Assert.assertEquals(2.3089223996676606E-4, FastMath.nextAfter(2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a222 -> 3f2e43753d36a222 Assert.assertEquals(2.3089223996676603E-4, FastMath.nextAfter(2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a224 -> 3f2e43753d36a222 Assert.assertEquals(2.3089223996676603E-4, FastMath.nextAfter(2.3089223996676606E-4, -2.308922399667661E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a223 -> 3f2e43753d36a222 Assert.assertEquals(2.3089223996676603E-4, FastMath.nextAfter(2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a222 -> 3f2e43753d36a222 Assert.assertEquals(2.3089223996676603E-4, FastMath.nextAfter(2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a224 -> bf2e43753d36a222 Assert.assertEquals(-2.3089223996676603E-4, FastMath.nextAfter(-2.3089223996676606E-4, 2.308922399667661E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a223 -> bf2e43753d36a222 Assert.assertEquals(-2.3089223996676603E-4, FastMath.nextAfter(-2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a222 -> bf2e43753d36a222 Assert.assertEquals(-2.3089223996676603E-4, FastMath.nextAfter(-2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a224 -> bf2e43753d36a224 Assert.assertEquals(-2.308922399667661E-4, FastMath.nextAfter(-2.3089223996676606E-4, -2.308922399667661E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a223 -> bf2e43753d36a223 Assert.assertEquals(-2.3089223996676606E-4, FastMath.nextAfter(-2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a222 -> bf2e43753d36a222 Assert.assertEquals(-2.3089223996676603E-4, FastMath.nextAfter(-2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); } @Test public void testDoubleNextAfterSpecialCases() { Assert.assertEquals(-Double.MAX_VALUE,FastMath.nextAfter(Double.NEGATIVE_INFINITY, 0D), 0D); Assert.assertEquals(Double.MAX_VALUE,FastMath.nextAfter(Double.POSITIVE_INFINITY, 0D), 0D); Assert.assertEquals(Double.NaN,FastMath.nextAfter(Double.NaN, 0D), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY,FastMath.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY,FastMath.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY), 0D); Assert.assertEquals(Double.MIN_VALUE, FastMath.nextAfter(0D, 1D), 0D); Assert.assertEquals(-Double.MIN_VALUE, FastMath.nextAfter(0D, -1D), 0D); Assert.assertEquals(0D, FastMath.nextAfter(Double.MIN_VALUE, -1), 0D); Assert.assertEquals(0D, FastMath.nextAfter(-Double.MIN_VALUE, 1), 0D); } @Test public void testFloatNextAfterSpecialCases() { Assert.assertEquals(-Float.MAX_VALUE,FastMath.nextAfter(Float.NEGATIVE_INFINITY, 0F), 0F); Assert.assertEquals(Float.MAX_VALUE,FastMath.nextAfter(Float.POSITIVE_INFINITY, 0F), 0F); Assert.assertEquals(Float.NaN,FastMath.nextAfter(Float.NaN, 0F), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY,FastMath.nextAfter(Float.MAX_VALUE, Float.POSITIVE_INFINITY), 0F); Assert.assertEquals(Float.NEGATIVE_INFINITY,FastMath.nextAfter(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY), 0F); Assert.assertEquals(Float.MIN_VALUE, FastMath.nextAfter(0F, 1F), 0F); Assert.assertEquals(-Float.MIN_VALUE, FastMath.nextAfter(0F, -1F), 0F); Assert.assertEquals(0F, FastMath.nextAfter(Float.MIN_VALUE, -1F), 0F); Assert.assertEquals(0F, FastMath.nextAfter(-Float.MIN_VALUE, 1F), 0F); } @Test public void testDoubleScalbSpecialCases() { Assert.assertEquals(2.5269841324701218E-175, FastMath.scalb(2.2250738585072014E-308, 442), 0D); Assert.assertEquals(1.307993905256674E297, FastMath.scalb(1.1102230246251565E-16, 1040), 0D); Assert.assertEquals(7.2520887996488946E-217, FastMath.scalb(Double.MIN_VALUE, 356), 0D); Assert.assertEquals(8.98846567431158E307, FastMath.scalb(Double.MIN_VALUE, 2097), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb(Double.MIN_VALUE, 2098), 0D); Assert.assertEquals(1.1125369292536007E-308, FastMath.scalb(2.225073858507201E-308, -1), 0D); Assert.assertEquals(1.0E-323, FastMath.scalb(Double.MAX_VALUE, -2097), 0D); Assert.assertEquals(Double.MIN_VALUE, FastMath.scalb(Double.MAX_VALUE, -2098), 0D); Assert.assertEquals(0, FastMath.scalb(Double.MAX_VALUE, -2099), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb(Double.POSITIVE_INFINITY, -1000000), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 1078), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 1079), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2047), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2048), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.7976931348623157E308, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 1.7976931348623157E308, 2147483647), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 1.1102230246251565E-16, 2147483647), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 2.2250738585072014E-308, 2147483647), 0D); } @Test public void testFloatScalbSpecialCases() { Assert.assertEquals(0f, FastMath.scalb(Float.MIN_VALUE, -30), 0F); Assert.assertEquals(2 * Float.MIN_VALUE, FastMath.scalb(Float.MIN_VALUE, 1), 0F); Assert.assertEquals(7.555786e22f, FastMath.scalb(Float.MAX_VALUE, -52), 0F); Assert.assertEquals(1.7014118e38f, FastMath.scalb(Float.MIN_VALUE, 276), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(Float.MIN_VALUE, 277), 0F); Assert.assertEquals(5.8774718e-39f, FastMath.scalb(1.1754944e-38f, -1), 0F); Assert.assertEquals(2 * Float.MIN_VALUE, FastMath.scalb(Float.MAX_VALUE, -276), 0F); Assert.assertEquals(Float.MIN_VALUE, FastMath.scalb(Float.MAX_VALUE, -277), 0F); Assert.assertEquals(0, FastMath.scalb(Float.MAX_VALUE, -278), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(Float.POSITIVE_INFINITY, -1000000), 0F); Assert.assertEquals(-3.13994498e38f, FastMath.scalb(-1.1e-7f, 151), 0F); Assert.assertEquals(Float.NEGATIVE_INFINITY, FastMath.scalb(-1.1e-7f, 152), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(3.4028235E38f, 2147483647), 0F); Assert.assertEquals(Float.NEGATIVE_INFINITY, FastMath.scalb(-3.4028235E38f, 2147483647), 0F); } private boolean compareClassMethods(Class class1, Class class2){ boolean allfound = true; for(Method method1 : class1.getDeclaredMethods()){ if (Modifier.isPublic(method1.getModifiers())){ Type []params = method1.getGenericParameterTypes(); try { class2.getDeclaredMethod(method1.getName(), (Class[]) params); } catch (NoSuchMethodException e) { allfound = false; System.out.println(class2.getSimpleName()+" does not implement: "+method1); } } } return allfound; } @Test public void checkMissingFastMathClasses() { boolean ok = compareClassMethods(StrictMath.class, FastMath.class); Assert.assertTrue("FastMath should implement all StrictMath methods", ok); } @Ignore @Test public void checkExtraFastMathClasses() { compareClassMethods( FastMath.class, StrictMath.class); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/ResizableDoubleArrayTest.java100644 1750 1750 47212 11532241244 31156 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.random.RandomDataImpl; import org.apache.commons.math.random.RandomData; /** * This class contains test cases for the ResizableDoubleArray. * * @version $Revision: 1053282 $ $Date: 2010-12-28 10:03:40 +0100 (mar. 28 déc. 2010) $ */ public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest { public ResizableDoubleArrayTest(String name) { super( name ); } @Override protected void tearDown() throws Exception { da = null; ra = null; } @Override protected void setUp() throws Exception { da = new ResizableDoubleArray(); ra = new ResizableDoubleArray(); } public void testConstructors() { float defaultExpansionFactor = 2.0f; float defaultContractionCriteria = 2.5f; int defaultMode = ResizableDoubleArray.MULTIPLICATIVE_MODE; ResizableDoubleArray testDa = new ResizableDoubleArray(2); assertEquals(0, testDa.getNumElements()); assertEquals(2, testDa.getInternalLength()); assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0); assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0); assertEquals(defaultMode, testDa.getExpansionMode()); try { da = new ResizableDoubleArray(-1); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } testDa = new ResizableDoubleArray((double[]) null); assertEquals(0, testDa.getNumElements()); double[] initialArray = new double[] { 0, 1, 2 }; testDa = new ResizableDoubleArray(initialArray); assertEquals(3, testDa.getNumElements()); testDa = new ResizableDoubleArray(2, 2.0f); assertEquals(0, testDa.getNumElements()); assertEquals(2, testDa.getInternalLength()); assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0); assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0); assertEquals(defaultMode, testDa.getExpansionMode()); try { da = new ResizableDoubleArray(2, 0.5f); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } testDa = new ResizableDoubleArray(2, 3.0f); assertEquals(3.0f, testDa.getExpansionFactor(), 0); assertEquals(3.5f, testDa.getContractionCriteria(), 0); testDa = new ResizableDoubleArray(2, 2.0f, 3.0f); assertEquals(0, testDa.getNumElements()); assertEquals(2, testDa.getInternalLength()); assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0); assertEquals(3.0f, testDa.getContractionCriteria(), 0); assertEquals(defaultMode, testDa.getExpansionMode()); try { da = new ResizableDoubleArray(2, 2.0f, 1.5f); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, ResizableDoubleArray.ADDITIVE_MODE); assertEquals(0, testDa.getNumElements()); assertEquals(2, testDa.getInternalLength()); assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0); assertEquals(3.0f, testDa.getContractionCriteria(), 0); assertEquals(ResizableDoubleArray.ADDITIVE_MODE, testDa.getExpansionMode()); try { da = new ResizableDoubleArray(2, 2.0f, 2.5f, -1); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } // Copy constructor testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, ResizableDoubleArray.ADDITIVE_MODE); testDa.addElement(2.0); testDa.addElement(3.2); ResizableDoubleArray copyDa = new ResizableDoubleArray(testDa); assertEquals(copyDa, testDa); assertEquals(testDa, copyDa); } public void testSetElementArbitraryExpansion() { // MULTIPLICATIVE_MODE da.addElement(2.0); da.addElement(4.0); da.addElement(6.0); da.setElement(1, 3.0); // Expand the array arbitrarily to 1000 items da.setElement(1000, 3.4); assertEquals( "The number of elements should now be 1001, it isn't", da.getNumElements(), 1001); assertEquals( "Uninitialized Elements are default value of 0.0, index 766 wasn't", 0.0, da.getElement( 760 ), Double.MIN_VALUE ); assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, da.getElement(1000), Double.MIN_VALUE ); assertEquals( "The 0th index should be 2.0, it isn't", 2.0, da.getElement(0), Double.MIN_VALUE); // Make sure numElements and expansion work correctly for expansion boundary cases da.clear(); da.addElement(2.0); da.addElement(4.0); da.addElement(6.0); assertEquals(4, ((ResizableDoubleArray) da).getInternalLength()); assertEquals(3, da.getNumElements()); da.setElement(3, 7.0); assertEquals(4, ((ResizableDoubleArray) da).getInternalLength()); assertEquals(4, da.getNumElements()); da.setElement(10, 10.0); assertEquals(11, ((ResizableDoubleArray) da).getInternalLength()); assertEquals(11, da.getNumElements()); da.setElement(9, 10.0); assertEquals(11, ((ResizableDoubleArray) da).getInternalLength()); assertEquals(11, da.getNumElements()); try { da.setElement(-2, 3); fail("Expecting ArrayIndexOutOfBoundsException for negative index"); } catch (ArrayIndexOutOfBoundsException ex) { // expected } // ADDITIVE_MODE ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, ResizableDoubleArray.ADDITIVE_MODE); assertEquals(2, testDa.getInternalLength()); testDa.addElement(1d); testDa.addElement(1d); assertEquals(2, testDa.getInternalLength()); testDa.addElement(1d); assertEquals(4, testDa.getInternalLength()); } @Override public void testAdd1000() { super.testAdd1000(); assertEquals("Internal Storage length should be 1024 if we started out with initial capacity of " + "16 and an expansion factor of 2.0", 1024, ((ResizableDoubleArray) da).getInternalLength()); } public void testAddElements() { ResizableDoubleArray testDa = new ResizableDoubleArray(); // MULTIPLICATIVE_MODE testDa.addElements(new double[] {4, 5, 6}); assertEquals(3, testDa.getNumElements(), 0); assertEquals(4, testDa.getElement(0), 0); assertEquals(5, testDa.getElement(1), 0); assertEquals(6, testDa.getElement(2), 0); testDa.addElements(new double[] {4, 5, 6}); assertEquals(6, testDa.getNumElements()); // ADDITIVE_MODE (x's are occupied storage locations, 0's are open) testDa = new ResizableDoubleArray(2, 2.0f, 2.5f, ResizableDoubleArray.ADDITIVE_MODE); assertEquals(2, testDa.getInternalLength()); testDa.addElements(new double[] { 1d }); // x,0 testDa.addElements(new double[] { 2d }); // x,x testDa.addElements(new double[] { 3d }); // x,x,x,0 -- expanded assertEquals(1d, testDa.getElement(0), 0); assertEquals(2d, testDa.getElement(1), 0); assertEquals(3d, testDa.getElement(2), 0); assertEquals(4, testDa.getInternalLength()); // x,x,x,0 assertEquals(3, testDa.getNumElements()); } @Override public void testAddElementRolling() { super.testAddElementRolling(); // MULTIPLICATIVE_MODE da.clear(); da.addElement(1); da.addElement(2); da.addElementRolling(3); assertEquals(3, da.getElement(1), 0); da.addElementRolling(4); assertEquals(3, da.getElement(0), 0); assertEquals(4, da.getElement(1), 0); da.addElement(5); assertEquals(5, da.getElement(2), 0); da.addElementRolling(6); assertEquals(4, da.getElement(0), 0); assertEquals(5, da.getElement(1), 0); assertEquals(6, da.getElement(2), 0); // ADDITIVE_MODE (x's are occupied storage locations, 0's are open) ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 2.5f, ResizableDoubleArray.ADDITIVE_MODE); assertEquals(2, testDa.getInternalLength()); testDa.addElement(1d); // x,0 testDa.addElement(2d); // x,x testDa.addElement(3d); // x,x,x,0 -- expanded assertEquals(1d, testDa.getElement(0), 0); assertEquals(2d, testDa.getElement(1), 0); assertEquals(3d, testDa.getElement(2), 0); assertEquals(4, testDa.getInternalLength()); // x,x,x,0 assertEquals(3, testDa.getNumElements()); testDa.addElementRolling(4d); assertEquals(2d, testDa.getElement(0), 0); assertEquals(3d, testDa.getElement(1), 0); assertEquals(4d, testDa.getElement(2), 0); assertEquals(4, testDa.getInternalLength()); // 0,x,x,x assertEquals(3, testDa.getNumElements()); testDa.addElementRolling(5d); // 0,0,x,x,x,0 -- time to contract assertEquals(3d, testDa.getElement(0), 0); assertEquals(4d, testDa.getElement(1), 0); assertEquals(5d, testDa.getElement(2), 0); assertEquals(4, testDa.getInternalLength()); // contracted -- x,x,x,0 assertEquals(3, testDa.getNumElements()); try { testDa.getElement(4); fail("Expecting ArrayIndexOutOfBoundsException"); } catch (ArrayIndexOutOfBoundsException ex) { // expected } try { testDa.getElement(-1); fail("Expecting ArrayIndexOutOfBoundsException"); } catch (ArrayIndexOutOfBoundsException ex) { // expected } } public void testSetNumberOfElements() { da.addElement( 1.0 ); da.addElement( 1.0 ); da.addElement( 1.0 ); da.addElement( 1.0 ); da.addElement( 1.0 ); da.addElement( 1.0 ); assertEquals( "Number of elements should equal 6", da.getNumElements(), 6); ((ResizableDoubleArray) da).setNumElements( 3 ); assertEquals( "Number of elements should equal 3", da.getNumElements(), 3); try { ((ResizableDoubleArray) da).setNumElements( -3 ); fail( "Setting number of elements to negative should've thrown an exception"); } catch( IllegalArgumentException iae ) { } ((ResizableDoubleArray) da).setNumElements(1024); assertEquals( "Number of elements should now be 1024", da.getNumElements(), 1024); assertEquals( "Element 453 should be a default double", da.getElement( 453 ), 0.0, Double.MIN_VALUE); } public void testWithInitialCapacity() { ResizableDoubleArray eDA2 = new ResizableDoubleArray(2); assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements()); RandomData randomData = new RandomDataImpl(); int iterations = randomData.nextInt(100, 1000); for( int i = 0; i < iterations; i++) { eDA2.addElement( i ); } assertEquals("Number of elements should be equal to " + iterations, iterations, eDA2.getNumElements()); eDA2.addElement( 2.0 ); assertEquals("Number of elements should be equals to " + (iterations +1), iterations + 1 , eDA2.getNumElements() ); } public void testWithInitialCapacityAndExpansionFactor() { ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0f, 3.5f); assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() ); RandomData randomData = new RandomDataImpl(); int iterations = randomData.nextInt(100, 3000); for( int i = 0; i < iterations; i++) { eDA3.addElement( i ); } assertEquals("Number of elements should be equal to " + iterations, iterations,eDA3.getNumElements()); eDA3.addElement( 2.0 ); assertEquals("Number of elements should be equals to " + (iterations +1), iterations +1, eDA3.getNumElements() ); assertEquals("Expansion factor should equal 3.0", 3.0f, eDA3.getExpansionFactor(), Double.MIN_VALUE); } public void testDiscard() { da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); assertEquals( "Number of elements should be 11", 11, da.getNumElements()); ((ResizableDoubleArray)da).discardFrontElements(5); assertEquals( "Number of elements should be 6", 6, da.getNumElements()); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); assertEquals( "Number of elements should be 10", 10, da.getNumElements()); ((ResizableDoubleArray)da).discardMostRecentElements(2); assertEquals( "Number of elements should be 8", 8, da.getNumElements()); try { ((ResizableDoubleArray)da).discardFrontElements(-1); fail( "Trying to discard a negative number of element is not allowed"); } catch( Exception e ){ } try { ((ResizableDoubleArray)da).discardMostRecentElements(-1); fail( "Trying to discard a negative number of element is not allowed"); } catch( Exception e ){ } try { ((ResizableDoubleArray)da).discardFrontElements( 10000 ); fail( "You can't discard more elements than the array contains"); } catch( Exception e ){ } try { ((ResizableDoubleArray)da).discardMostRecentElements( 10000 ); fail( "You can't discard more elements than the array contains"); } catch( Exception e ){ } } public void testSubstitute() { da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); da.addElement(2.0); assertEquals( "Number of elements should be 11", 11, da.getNumElements()); ((ResizableDoubleArray)da).substituteMostRecentElement(24); assertEquals( "Number of elements should be 11", 11, da.getNumElements()); try { ((ResizableDoubleArray)da).discardMostRecentElements(10); } catch( Exception e ){ fail( "Trying to discard a negative number of element is not allowed"); } ((ResizableDoubleArray)da).substituteMostRecentElement(24); assertEquals( "Number of elements should be 1", 1, da.getNumElements()); } public void testMutators() { ((ResizableDoubleArray)da).setContractionCriteria(10f); assertEquals(10f, ((ResizableDoubleArray)da).getContractionCriteria(), 0); ((ResizableDoubleArray)da).setExpansionFactor(8f); assertEquals(8f, ((ResizableDoubleArray)da).getExpansionFactor(), 0); try { ((ResizableDoubleArray)da).setExpansionFactor(11f); // greater than contractionCriteria fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } ((ResizableDoubleArray)da).setExpansionMode( ResizableDoubleArray.ADDITIVE_MODE); assertEquals(ResizableDoubleArray.ADDITIVE_MODE, ((ResizableDoubleArray)da).getExpansionMode()); try { ((ResizableDoubleArray)da).setExpansionMode(-1); fail ("Expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } public void testEqualsAndHashCode() throws Exception { // Wrong type ResizableDoubleArray first = new ResizableDoubleArray(); Double other = new Double(2); assertFalse(first.equals(other)); // Null other = null; assertFalse(first.equals(other)); // Reflexive assertTrue(first.equals(first)); // Argumentless constructor ResizableDoubleArray second = new ResizableDoubleArray(); verifyEquality(first, second); // Equals iff same data, same properties ResizableDoubleArray third = new ResizableDoubleArray(3, 2.0f, 2.0f); verifyInequality(third, first); ResizableDoubleArray fourth = new ResizableDoubleArray(3, 2.0f, 2.0f); ResizableDoubleArray fifth = new ResizableDoubleArray(2, 2.0f, 2.0f); verifyEquality(third, fourth); verifyInequality(third, fifth); third.addElement(4.1); third.addElement(4.2); third.addElement(4.3); fourth.addElement(4.1); fourth.addElement(4.2); fourth.addElement(4.3); verifyEquality(third, fourth); // expand fourth.addElement(4.4); verifyInequality(third, fourth); third.addElement(4.4); verifyEquality(third, fourth); fourth.addElement(4.4); verifyInequality(third, fourth); third.addElement(4.4); verifyEquality(third, fourth); fourth.addElementRolling(4.5); third.addElementRolling(4.5); verifyEquality(third, fourth); // discard third.discardFrontElements(1); verifyInequality(third, fourth); fourth.discardFrontElements(1); verifyEquality(third, fourth); // discard recent third.discardMostRecentElements(2); fourth.discardMostRecentElements(2); verifyEquality(third, fourth); // wrong order third.addElement(18); fourth.addElement(17); third.addElement(17); fourth.addElement(18); verifyInequality(third, fourth); // copy ResizableDoubleArray.copy(fourth, fifth); verifyEquality(fourth, fifth); // Copy constructor verifyEquality(fourth, new ResizableDoubleArray(fourth)); // Instance copy verifyEquality(fourth, fourth.copy()); } private void verifyEquality(ResizableDoubleArray a, ResizableDoubleArray b) { assertTrue(b.equals(a)); assertTrue(a.equals(b)); assertEquals(a.hashCode(), b.hashCode()); } private void verifyInequality(ResizableDoubleArray a, ResizableDoubleArray b) { assertFalse(b.equals(a)); assertFalse(a.equals(b)); assertFalse(a.hashCode() == b.hashCode()); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/DefaultTransformerTest.java100644 1750 1750 5737 11532241244 30701 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.math.BigDecimal; import junit.framework.TestCase; import org.apache.commons.math.MathException; import org.apache.commons.math.TestUtils; /** * @version $Revision: 1073658 $ $Date: 2011-02-23 10:45:42 +0100 (mer. 23 févr. 2011) $ */ public class DefaultTransformerTest extends TestCase { /** * */ public void testTransformDouble() throws Exception { double expected = 1.0; Double input = Double.valueOf(expected); DefaultTransformer t = new DefaultTransformer(); assertEquals(expected, t.transform(input), 1.0e-4); } /** * */ public void testTransformNull() throws Exception { DefaultTransformer t = new DefaultTransformer(); try { t.transform(null); fail("Expecting MathException"); } catch (MathException e) { // expected } } /** * */ public void testTransformInteger() throws Exception { double expected = 1.0; Integer input = Integer.valueOf(1); DefaultTransformer t = new DefaultTransformer(); assertEquals(expected, t.transform(input), 1.0e-4); } /** * */ public void testTransformBigDecimal() throws Exception { double expected = 1.0; BigDecimal input = new BigDecimal("1.0"); DefaultTransformer t = new DefaultTransformer(); assertEquals(expected, t.transform(input), 1.0e-4); } /** * */ public void testTransformString() throws Exception { double expected = 1.0; String input = "1.0"; DefaultTransformer t = new DefaultTransformer(); assertEquals(expected, t.transform(input), 1.0e-4); } /** * */ public void testTransformObject(){ Boolean input = Boolean.TRUE; DefaultTransformer t = new DefaultTransformer(); try { t.transform(input); fail("Expecting MathException"); } catch (MathException e) { // expected } } public void testSerial() { assertEquals(new DefaultTransformer(), TestUtils.serializeAndRecover(new DefaultTransformer())); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/FastMathTestPerformance.java100644 1750 1750 27127 11532241244 31000 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.junit.BeforeClass; import org.junit.Test; /** * Performance tests for FastMath. * Not enabled by default, as the class does not end in Test. * * Invoke by running
                  * {@code mvn test -Dtest=FastMathTestPerformance}
                  * or by running
                  * {@code mvn test -Dtest=FastMathTestPerformance -DargLine="-DtestRuns=1234 -server"}
                  */ public class FastMathTestPerformance { private static final int RUNS = Integer.parseInt(System.getProperty("testRuns","10000000")); // Header format private static final String FMT_HDR = "%-5s %13s %13s %13s Runs=%d Java %s (%s) %s (%s)"; // Detail format private static final String FMT_DTL = "%-5s %6d %6.2f %6d %6.2f %6d %6.2f"; @BeforeClass public static void header() { System.out.println(String.format(FMT_HDR, "Name","StrictMath","FastMath","Math",RUNS, System.getProperty("java.version"), System.getProperty("java.runtime.version","?"), System.getProperty("java.vm.name"), System.getProperty("java.vm.version") )); } private static void report(String name, long strictMathTime, long fastMathTime, long mathTime) { long unitTime = strictMathTime; System.out.println(String.format(FMT_DTL, name, strictMathTime / RUNS, (double) strictMathTime / unitTime, fastMathTime / RUNS, (double) fastMathTime / unitTime, mathTime / RUNS, (double) mathTime / unitTime )); } @Test public void testLog() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.log(Math.PI + i/* 1.0 + i/1e9 */); long strictMath = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.log(Math.PI + i/* 1.0 + i/1e9 */); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.log(Math.PI + i/* 1.0 + i/1e9 */); long mathTime = System.nanoTime() - time; report("log",strictMath,fastTime,mathTime); } @Test public void testPow() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.pow(Math.PI + i / 1e6, i / 1e6); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.pow(Math.PI + i / 1e6, i / 1e6); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.pow(Math.PI + i / 1e6, i / 1e6); long mathTime = System.nanoTime() - time; report("pow",strictTime,fastTime,mathTime); } @Test public void testExp() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.exp(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.exp(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.exp(i / 1000000.0); long mathTime = System.nanoTime() - time; report("exp",strictTime,fastTime,mathTime); } @Test public void testSin() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.sin(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.sin(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.sin(i / 1000000.0); long mathTime = System.nanoTime() - time; report("sin",strictTime,fastTime,mathTime); } @Test public void testAsin() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.asin(i / 10000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.asin(i / 10000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.asin(i / 10000000.0); long mathTime = System.nanoTime() - time; report("asin",strictTime,fastTime,mathTime); } @Test public void testCos() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.cos(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.cos(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.cos(i / 1000000.0); long mathTime = System.nanoTime() - time; report("cos",strictTime,fastTime,mathTime); } @Test public void testAcos() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.acos(i / 10000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.acos(i / 10000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.acos(i / 10000000.0); long mathTime = System.nanoTime() - time; report("acos",strictTime,fastTime,mathTime); } @Test public void testTan() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.tan(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.tan(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.tan(i / 1000000.0); long mathTime = System.nanoTime() - time; report("tan",strictTime,fastTime,mathTime); } @Test public void testAtan() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.atan(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.atan(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.atan(i / 1000000.0); long mathTime = System.nanoTime() - time; report("atan",strictTime,fastTime,mathTime); } @Test public void testCbrt() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.cbrt(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.cbrt(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.cbrt(i / 1000000.0); long mathTime = System.nanoTime() - time; report("cbrt",strictTime,fastTime,mathTime); } @Test public void testCosh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.cosh(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.cosh(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.cosh(i / 1000000.0); long mathTime = System.nanoTime() - time; report("cosh",strictTime,fastTime,mathTime); } @Test public void testSinh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.sinh(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.sinh(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.sinh(i / 1000000.0); long mathTime = System.nanoTime() - time; report("sinh",strictTime,fastTime,mathTime); } @Test public void testTanh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.tanh(i / 1000000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.tanh(i / 1000000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.tanh(i / 1000000.0); long mathTime = System.nanoTime() - time; report("tanh",strictTime,fastTime,mathTime); } @Test public void testExpm1() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += StrictMath.expm1(-i / 100000.0); long strictTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += FastMath.expm1(-i / 100000.0); long fastTime = System.nanoTime() - time; x = 0; time = System.nanoTime(); for (int i = 0; i < RUNS; i++) x += Math.expm1(-i / 100000.0); long mathTime = System.nanoTime() - time; report("expm1",strictTime,fastTime,mathTime); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/ContinuedFractionTest.java100644 1750 1750 3344 11532241244 30500 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.MathException; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class ContinuedFractionTest extends TestCase { /** * Constructor for ContinuedFractionTest. * @param name */ public ContinuedFractionTest(String name) { super(name); } public void testGoldenRatio(){ ContinuedFraction cf = new ContinuedFraction() { @Override public double getA(int n, double x) { return 1.0; } @Override public double getB(int n, double x) { return 1.0; } }; try { double gr = cf.evaluate(0.0, 10e-9); assertEquals(1.61803399, gr, 10e-9); } catch (MathException e) { fail(e.getMessage()); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/BigRealTest.java100644 1750 1750 12373 11532241244 26411 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; import org.apache.commons.math.TestUtils; import org.junit.Test; public class BigRealTest { @Test public void testConstructor() { assertEquals(1.625, new BigReal(new BigDecimal("1.625")).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(new BigInteger("-5")).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(new BigInteger("-5"), MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(0.125, new BigReal(new BigInteger("125"), 3).doubleValue(), 1.0e-15); assertEquals(0.125, new BigReal(new BigInteger("125"), 3, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(new char[] { '1', '.', '6', '2', '5' }).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(new char[] { 'A', 'A', '1', '.', '6', '2', '5', '9' }, 2, 5).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(new char[] { 'A', 'A', '1', '.', '6', '2', '5', '9' }, 2, 5, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(new char[] { '1', '.', '6', '2', '5' }, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(1.625).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal(1.625, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(-5).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(-5, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(-5l).doubleValue(), 1.0e-15); assertEquals(-5.0, new BigReal(-5l, MathContext.DECIMAL64).doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal("1.625").doubleValue(), 1.0e-15); assertEquals(1.625, new BigReal("1.625", MathContext.DECIMAL64).doubleValue(), 1.0e-15); } @Test public void testCompareTo() { BigReal first = new BigReal(1.0 / 2.0); BigReal second = new BigReal(1.0 / 3.0); BigReal third = new BigReal(1.0 / 2.0); assertEquals(0, first.compareTo(first)); assertEquals(0, first.compareTo(third)); assertEquals(1, first.compareTo(second)); assertEquals(-1, second.compareTo(first)); } public void testAdd() { BigReal a = new BigReal("1.2345678"); BigReal b = new BigReal("8.7654321"); assertEquals(9.9999999, a.add(b).doubleValue(), 1.0e-15); } public void testSubtract() { BigReal a = new BigReal("1.2345678"); BigReal b = new BigReal("8.7654321"); assertEquals( -7.5308643, a.subtract(b).doubleValue(), 1.0e-15); } public void testDivide() { BigReal a = new BigReal("1.0000000000"); BigReal b = new BigReal("0.0009765625"); assertEquals(1024.0, a.divide(b).doubleValue(), 1.0e-15); } public void testMultiply() { BigReal a = new BigReal("1024.0"); BigReal b = new BigReal("0.0009765625"); assertEquals(1.0, a.multiply(b).doubleValue(), 1.0e-15); } @Test public void testDoubleValue() { assertEquals(0.5, new BigReal(0.5).doubleValue(), 1.0e-15); } @Test public void testBigDecimalValue() { BigDecimal pi = new BigDecimal("3.1415926535897932384626433832795028841971693993751"); assertEquals(pi, new BigReal(pi).bigDecimalValue()); assertEquals(new BigDecimal(0.5), new BigReal(1.0 / 2.0).bigDecimalValue()); } @Test public void testEqualsAndHashCode() { BigReal zero = new BigReal(0.0); BigReal nullReal = null; assertTrue(zero.equals(zero)); assertFalse(zero.equals(nullReal)); assertFalse(zero.equals(Double.valueOf(0))); BigReal zero2 = new BigReal(0.0); assertTrue(zero.equals(zero2)); assertEquals(zero.hashCode(), zero2.hashCode()); BigReal one = new BigReal(1.0); assertFalse((one.equals(zero) || zero.equals(one))); assertTrue(one.equals(BigReal.ONE)); } public void testSerial() { BigReal[] Reals = { new BigReal(3.0), BigReal.ONE, BigReal.ZERO, new BigReal(17), new BigReal(FastMath.PI), new BigReal(-2.5) }; for (BigReal Real : Reals) { assertEquals(Real, TestUtils.serializeAndRecover(Real)); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/TestBean.java100644 1750 1750 3233 11532241244 25724 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class TestBean { private Double x = Double.valueOf(1.0); private String y = "1.0"; /** * */ public Double getX() { return x; } /** * */ public String getY() { return y; } /** * */ public void setX(Double double1) { x = double1; } /** * */ public void setY(String string) { y = string; } /** * */ public Double getZ() { throw new MathRuntimeException(LocalizedFormats.SIMPLE_MESSAGE, "?"); } /** * */ public void setZ(Double double1) { } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/DoubleArrayAbstractTest.java100644 1750 1750 7453 11532241244 30764 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.stat.StatUtils; import junit.framework.TestCase; /** * This class contains test cases for the ExpandableDoubleArray. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class DoubleArrayAbstractTest extends TestCase { protected DoubleArray da = null; // Array used to test rolling protected DoubleArray ra = null; public DoubleArrayAbstractTest(String name) { super(name); } public void testAdd1000() { for (int i = 0; i < 1000; i++) { da.addElement(i); } assertEquals( "Number of elements should be equal to 1000 after adding 1000 values", 1000, da.getNumElements()); assertEquals( "The element at the 56th index should be 56", 56.0, da.getElement(56), Double.MIN_VALUE); } public void testGetValues() { double[] controlArray = { 2.0, 4.0, 6.0 }; da.addElement(2.0); da.addElement(4.0); da.addElement(6.0); double[] testArray = da.getElements(); for (int i = 0; i < da.getNumElements(); i++) { assertEquals( "The testArray values should equal the controlArray values, index i: " + i + " does not match", testArray[i], controlArray[i], Double.MIN_VALUE); } } public void testAddElementRolling() { ra.addElement(0.5); ra.addElement(1.0); ra.addElement(1.0); ra.addElement(1.0); ra.addElement(1.0); ra.addElement(1.0); ra.addElementRolling(2.0); assertEquals( "There should be 6 elements in the eda", 6, ra.getNumElements()); assertEquals( "The max element should be 2.0", 2.0, StatUtils.max(ra.getElements()), Double.MIN_VALUE); assertEquals( "The min element should be 1.0", 1.0, StatUtils.min(ra.getElements()), Double.MIN_VALUE); for (int i = 0; i < 1024; i++) { ra.addElementRolling(i); } assertEquals( "We just inserted 1024 rolling elements, num elements should still be 6", 6, ra.getNumElements()); } public void testMinMax() { da.addElement(2.0); da.addElement(22.0); da.addElement(-2.0); da.addElement(21.0); da.addElement(22.0); da.addElement(42.0); da.addElement(62.0); da.addElement(22.0); da.addElement(122.0); da.addElement(1212.0); assertEquals("Min should be -2.0", -2.0, StatUtils.min(da.getElements()), Double.MIN_VALUE); assertEquals( "Max should be 1212.0", 1212.0, StatUtils.max(da.getElements()), Double.MIN_VALUE); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/MathUtilsTest.java100644 1750 1750 213230 11532241244 27031 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law * or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.apache.commons.math.util; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.apache.commons.math.TestUtils; import org.apache.commons.math.exception.NonMonotonousSequenceException; import org.apache.commons.math.random.RandomDataImpl; /** * Test cases for the MathUtils class. * @version $Revision: 1070122 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug * 2007) $ */ public final class MathUtilsTest extends TestCase { public MathUtilsTest(String name) { super(name); } /** cached binomial coefficients */ private static final List> binomialCache = new ArrayList>(); /** * Exact (caching) recursive implementation to test against */ private long binomialCoefficient(int n, int k) throws ArithmeticException { if (binomialCache.size() > n) { Long cachedResult = binomialCache.get(n).get(Integer.valueOf(k)); if (cachedResult != null) { return cachedResult.longValue(); } } long result = -1; if ((n == k) || (k == 0)) { result = 1; } else if ((k == 1) || (k == n - 1)) { result = n; } else { // Reduce stack depth for larger values of n if (k < n - 100) { binomialCoefficient(n - 100, k); } if (k > 100) { binomialCoefficient(n - 100, k - 100); } result = MathUtils.addAndCheck(binomialCoefficient(n - 1, k - 1), binomialCoefficient(n - 1, k)); } if (result == -1) { throw new ArithmeticException( "error computing binomial coefficient"); } for (int i = binomialCache.size(); i < n + 1; i++) { binomialCache.add(new HashMap()); } binomialCache.get(n).put(Integer.valueOf(k), Long.valueOf(result)); return result; } /** * Exact direct multiplication implementation to test against */ private long factorial(int n) { long result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; } /** Verify that b(0,0) = 1 */ public void test0Choose0() { assertEquals(MathUtils.binomialCoefficientDouble(0, 0), 1d, 0); assertEquals(MathUtils.binomialCoefficientLog(0, 0), 0d, 0); assertEquals(MathUtils.binomialCoefficient(0, 0), 1); } public void testAddAndCheck() { int big = Integer.MAX_VALUE; int bigNeg = Integer.MIN_VALUE; assertEquals(big, MathUtils.addAndCheck(big, 0)); try { MathUtils.addAndCheck(big, 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } try { MathUtils.addAndCheck(bigNeg, -1); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } } public void testAddAndCheckLong() { long max = Long.MAX_VALUE; long min = Long.MIN_VALUE; assertEquals(max, MathUtils.addAndCheck(max, 0L)); assertEquals(min, MathUtils.addAndCheck(min, 0L)); assertEquals(max, MathUtils.addAndCheck(0L, max)); assertEquals(min, MathUtils.addAndCheck(0L, min)); assertEquals(1, MathUtils.addAndCheck(-1L, 2L)); assertEquals(1, MathUtils.addAndCheck(2L, -1L)); assertEquals(-3, MathUtils.addAndCheck(-2L, -1L)); assertEquals(min, MathUtils.addAndCheck(min + 1, -1L)); testAddAndCheckLongFailure(max, 1L); testAddAndCheckLongFailure(min, -1L); testAddAndCheckLongFailure(1L, max); testAddAndCheckLongFailure(-1L, min); } private void testAddAndCheckLongFailure(long a, long b) { try { MathUtils.addAndCheck(a, b); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // success } } public void testBinomialCoefficient() { long[] bcoef5 = { 1, 5, 10, 10, 5, 1 }; long[] bcoef6 = { 1, 6, 15, 20, 15, 6, 1 }; for (int i = 0; i < 6; i++) { assertEquals("5 choose " + i, bcoef5[i], MathUtils.binomialCoefficient(5, i)); } for (int i = 0; i < 7; i++) { assertEquals("6 choose " + i, bcoef6[i], MathUtils.binomialCoefficient(6, i)); } for (int n = 1; n < 10; n++) { for (int k = 0; k <= n; k++) { assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficient(n, k)); assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE); assertEquals(n + " choose " + k, FastMath.log(binomialCoefficient(n, k)), MathUtils.binomialCoefficientLog(n, k), 10E-12); } } int[] n = { 34, 66, 100, 1500, 1500 }; int[] k = { 17, 33, 10, 1500 - 4, 4 }; for (int i = 0; i < n.length; i++) { long expected = binomialCoefficient(n[i], k[i]); assertEquals(n[i] + " choose " + k[i], expected, MathUtils.binomialCoefficient(n[i], k[i])); assertEquals(n[i] + " choose " + k[i], expected, MathUtils.binomialCoefficientDouble(n[i], k[i]), 0.0); assertEquals("log(" + n[i] + " choose " + k[i] + ")", FastMath.log(expected), MathUtils.binomialCoefficientLog(n[i], k[i]), 0.0); } } /** * Tests correctness for large n and sharpness of upper bound in API doc * JIRA: MATH-241 */ public void testBinomialCoefficientLarge() throws Exception { // This tests all legal and illegal values for n <= 200. for (int n = 0; n <= 200; n++) { for (int k = 0; k <= n; k++) { long ourResult = -1; long exactResult = -1; boolean shouldThrow = false; boolean didThrow = false; try { ourResult = MathUtils.binomialCoefficient(n, k); } catch (ArithmeticException ex) { didThrow = true; } try { exactResult = binomialCoefficient(n, k); } catch (ArithmeticException ex) { shouldThrow = true; } assertEquals(n + " choose " + k, exactResult, ourResult); assertEquals(n + " choose " + k, shouldThrow, didThrow); assertTrue(n + " choose " + k, (n > 66 || !didThrow)); if (!shouldThrow && exactResult > 1) { assertEquals(n + " choose " + k, 1., MathUtils.binomialCoefficientDouble(n, k) / exactResult, 1e-10); assertEquals(n + " choose " + k, 1, MathUtils.binomialCoefficientLog(n, k) / FastMath.log(exactResult), 1e-10); } } } long ourResult = MathUtils.binomialCoefficient(300, 3); long exactResult = binomialCoefficient(300, 3); assertEquals(exactResult, ourResult); ourResult = MathUtils.binomialCoefficient(700, 697); exactResult = binomialCoefficient(700, 697); assertEquals(exactResult, ourResult); // This one should throw try { MathUtils.binomialCoefficient(700, 300); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // Expected } int n = 10000; ourResult = MathUtils.binomialCoefficient(n, 3); exactResult = binomialCoefficient(n, 3); assertEquals(exactResult, ourResult); assertEquals(1, MathUtils.binomialCoefficientDouble(n, 3) / exactResult, 1e-10); assertEquals(1, MathUtils.binomialCoefficientLog(n, 3) / FastMath.log(exactResult), 1e-10); } public void testBinomialCoefficientFail() { try { MathUtils.binomialCoefficient(4, 5); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficientDouble(4, 5); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficientLog(4, 5); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficient(-1, -2); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficientDouble(-1, -2); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficientLog(-1, -2); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.binomialCoefficient(67, 30); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { // ignored } try { MathUtils.binomialCoefficient(67, 34); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { // ignored } double x = MathUtils.binomialCoefficientDouble(1030, 515); assertTrue("expecting infinite binomial coefficient", Double .isInfinite(x)); } public void testCompareTo() { assertEquals(0, MathUtils.compareTo(152.33, 152.32, .011)); assertTrue(MathUtils.compareTo(152.308, 152.32, .011) < 0); assertTrue(MathUtils.compareTo(152.33, 152.318, .011) > 0); } public void testCosh() { double x = 3.0; double expected = 10.06766; assertEquals(expected, MathUtils.cosh(x), 1.0e-5); } public void testCoshNaN() { assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN))); } public void testEquals() { double[] testArray = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }; for (int i = 0; i < testArray.length; i++) { for (int j = 0; j < testArray.length; j++) { if (i == j) { assertTrue(MathUtils.equals(testArray[i], testArray[j])); assertTrue(MathUtils.equals(testArray[j], testArray[i])); } else { assertTrue(!MathUtils.equals(testArray[i], testArray[j])); assertTrue(!MathUtils.equals(testArray[j], testArray[i])); } } } } public void testEqualsIncludingNaN() { double[] testArray = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }; for (int i = 0; i < testArray.length; i++) { for (int j = 0; j < testArray.length; j++) { if (i == j) { assertTrue(MathUtils.equalsIncludingNaN(testArray[i], testArray[j])); assertTrue(MathUtils.equalsIncludingNaN(testArray[j], testArray[i])); } else { assertTrue(!MathUtils.equalsIncludingNaN(testArray[i], testArray[j])); assertTrue(!MathUtils.equalsIncludingNaN(testArray[j], testArray[i])); } } } } public void testEqualsWithAllowedDelta() { assertTrue(MathUtils.equals(153.0000, 153.0000, .0625)); assertTrue(MathUtils.equals(153.0000, 153.0625, .0625)); assertTrue(MathUtils.equals(152.9375, 153.0000, .0625)); assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1.0)); // This will change in 3.0 assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0)); assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); assertFalse(MathUtils.equals(153.0000, 153.0625, .0624)); assertFalse(MathUtils.equals(152.9374, 153.0000, .0625)); } public void testEqualsIncludingNaNWithAllowedDelta() { assertTrue(MathUtils.equalsIncludingNaN(153.0000, 153.0000, .0625)); assertTrue(MathUtils.equalsIncludingNaN(153.0000, 153.0625, .0625)); assertTrue(MathUtils.equalsIncludingNaN(152.9375, 153.0000, .0625)); assertTrue(MathUtils.equalsIncludingNaN(Double.NaN, Double.NaN, 1.0)); assertTrue(MathUtils.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); assertTrue(MathUtils.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0)); assertFalse(MathUtils.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); assertFalse(MathUtils.equalsIncludingNaN(153.0000, 153.0625, .0624)); assertFalse(MathUtils.equalsIncludingNaN(152.9374, 153.0000, .0625)); } // Tests for floating point equality @SuppressWarnings("deprecation") // Math.equals(float, float) public void testFloatEqualsWithAllowedUlps() { assertTrue("+0.0f == -0.0f",MathUtils.equals(0.0f, -0.0f)); assertTrue("+0.0f == -0.0f (1 ulp)",MathUtils.equals(0.0f, -0.0f, 1)); float oneFloat = 1.0f; // Deprecated method - requires parameters to be strictly equal assertFalse("1.0f != 1.0f + 1 ulp",MathUtils.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat)))); assertTrue("1.0f == 1.0f + 1 ulp (1 ulp)",MathUtils.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat)), 1)); assertFalse("1.0f != 1.0f + 2 ulp (1 ulp)",MathUtils.equals(oneFloat, Float.intBitsToFloat(2 + Float.floatToIntBits(oneFloat)), 1)); assertTrue(MathUtils.equals(153.0f, 153.0f, 1)); // These tests need adjusting for floating point precision // assertTrue(MathUtils.equals(153.0f, 153.00000000000003f, 1)); // assertFalse(MathUtils.equals(153.0f, 153.00000000000006f, 1)); // assertTrue(MathUtils.equals(153.0f, 152.99999999999997f, 1)); // assertFalse(MathUtils.equals(153f, 152.99999999999994f, 1)); // // assertTrue(MathUtils.equals(-128.0f, -127.99999999999999f, 1)); // assertFalse(MathUtils.equals(-128.0f, -127.99999999999997f, 1)); // assertTrue(MathUtils.equals(-128.0f, -128.00000000000003f, 1)); // assertFalse(MathUtils.equals(-128.0f, -128.00000000000006f, 1)); assertTrue(MathUtils.equals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.MAX_VALUE, Float.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equals(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY, 1)); assertFalse(MathUtils.equals(Float.NaN, Float.NaN, 1)); assertFalse(MathUtils.equals(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, 100000)); } public void testEqualsWithAllowedUlps21() { // From 2.1 assertTrue(MathUtils.equals(153, 153, 1)); assertTrue(MathUtils.equals(153, 153.00000000000003, 1)); assertFalse(MathUtils.equals(153, 153.00000000000006, 1)); assertTrue(MathUtils.equals(153, 152.99999999999997, 1)); assertFalse(MathUtils.equals(153, 152.99999999999994, 1)); assertTrue(MathUtils.equals(-128, -127.99999999999999, 1)); assertFalse(MathUtils.equals(-128, -127.99999999999997, 1)); assertTrue(MathUtils.equals(-128, -128.00000000000003, 1)); assertFalse(MathUtils.equals(-128, -128.00000000000006, 1)); assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1)); assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000)); } public void testEqualsWithAllowedUlps() { assertTrue(MathUtils.equals(0.0, -0.0, 1)); assertTrue(MathUtils.equals(1.0, 1 + FastMath.ulp(1d), 1)); assertFalse(MathUtils.equals(1.0, 1 + 2 * FastMath.ulp(1d), 1)); final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY); final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY); assertTrue(MathUtils.equals(1.0, nUp1, 1)); assertTrue(MathUtils.equals(nUp1, nnUp1, 1)); assertFalse(MathUtils.equals(1.0, nnUp1, 1)); assertTrue(MathUtils.equals(0.0, FastMath.ulp(0d), 1)); assertTrue(MathUtils.equals(0.0, -FastMath.ulp(0d), 1)); assertTrue(MathUtils.equals(153.0, 153.0, 1)); assertTrue(MathUtils.equals(153.0, 153.00000000000003, 1)); assertFalse(MathUtils.equals(153.0, 153.00000000000006, 1)); assertTrue(MathUtils.equals(153.0, 152.99999999999997, 1)); assertFalse(MathUtils.equals(153, 152.99999999999994, 1)); assertTrue(MathUtils.equals(-128.0, -127.99999999999999, 1)); assertFalse(MathUtils.equals(-128.0, -127.99999999999997, 1)); assertTrue(MathUtils.equals(-128.0, -128.00000000000003, 1)); assertFalse(MathUtils.equals(-128.0, -128.00000000000006, 1)); assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1)); // This will change in 3.0 assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000)); } public void testEqualsIncludingNaNWithAllowedUlps() { assertTrue(MathUtils.equalsIncludingNaN(0.0, -0.0, 1)); assertTrue(MathUtils.equalsIncludingNaN(1.0, 1 + FastMath.ulp(1d), 1)); assertFalse(MathUtils.equalsIncludingNaN(1.0, 1 + 2 * FastMath.ulp(1d), 1)); final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY); final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY); assertTrue(MathUtils.equalsIncludingNaN(1.0, nUp1, 1)); assertTrue(MathUtils.equalsIncludingNaN(nUp1, nnUp1, 1)); assertFalse(MathUtils.equalsIncludingNaN(1.0, nnUp1, 1)); assertTrue(MathUtils.equalsIncludingNaN(0.0, FastMath.ulp(0d), 1)); assertTrue(MathUtils.equalsIncludingNaN(0.0, -FastMath.ulp(0d), 1)); assertTrue(MathUtils.equalsIncludingNaN(153.0, 153.0, 1)); assertTrue(MathUtils.equalsIncludingNaN(153.0, 153.00000000000003, 1)); assertFalse(MathUtils.equalsIncludingNaN(153.0, 153.00000000000006, 1)); assertTrue(MathUtils.equalsIncludingNaN(153.0, 152.99999999999997, 1)); assertFalse(MathUtils.equalsIncludingNaN(153, 152.99999999999994, 1)); assertTrue(MathUtils.equalsIncludingNaN(-128.0, -127.99999999999999, 1)); assertFalse(MathUtils.equalsIncludingNaN(-128.0, -127.99999999999997, 1)); assertTrue(MathUtils.equalsIncludingNaN(-128.0, -128.00000000000003, 1)); assertFalse(MathUtils.equalsIncludingNaN(-128.0, -128.00000000000006, 1)); assertTrue(MathUtils.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equalsIncludingNaN(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1)); assertTrue(MathUtils.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equalsIncludingNaN(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1)); assertTrue(MathUtils.equalsIncludingNaN(Double.NaN, Double.NaN, 1)); assertFalse(MathUtils.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000)); } @SuppressWarnings("deprecation") // specific tests of deprecated methods public void testArrayEquals() { assertFalse(MathUtils.equals(new double[] { 1d }, null)); assertFalse(MathUtils.equals(null, new double[] { 1d })); assertTrue(MathUtils.equals((double[]) null, (double[]) null)); assertFalse(MathUtils.equals(new double[] { 1d }, new double[0])); assertTrue(MathUtils.equals(new double[] { 1d }, new double[] { 1d })); assertTrue(MathUtils.equals(new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }, new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d })); assertFalse(MathUtils.equals(new double[] { Double.POSITIVE_INFINITY }, new double[] { Double.NEGATIVE_INFINITY })); assertFalse(MathUtils.equals(new double[] { 1d }, new double[] { FastMath.nextAfter(1d, 2d) })); } public void testArrayEqualsIncludingNaN() { assertFalse(MathUtils.equalsIncludingNaN(new double[] { 1d }, null)); assertFalse(MathUtils.equalsIncludingNaN(null, new double[] { 1d })); assertTrue(MathUtils.equalsIncludingNaN((double[]) null, (double[]) null)); assertFalse(MathUtils.equalsIncludingNaN(new double[] { 1d }, new double[0])); assertTrue(MathUtils.equalsIncludingNaN(new double[] { 1d }, new double[] { 1d })); assertTrue(MathUtils.equalsIncludingNaN(new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }, new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d })); assertFalse(MathUtils.equalsIncludingNaN(new double[] { Double.POSITIVE_INFINITY }, new double[] { Double.NEGATIVE_INFINITY })); assertFalse(MathUtils.equalsIncludingNaN(new double[] { 1d }, new double[] { FastMath.nextAfter(FastMath.nextAfter(1d, 2d), 2d) })); } public void testFloatArrayEqualsIncludingNaN() { assertFalse(MathUtils.equalsIncludingNaN(new float[] { 1f }, null)); assertFalse(MathUtils.equalsIncludingNaN(null, new float[] { 1f })); assertTrue(MathUtils.equalsIncludingNaN((float[]) null, (float[]) null)); assertFalse(MathUtils.equalsIncludingNaN(new float[] { 1f }, new float[0])); assertTrue(MathUtils.equalsIncludingNaN(new float[] { 1f }, new float[] { 1f })); assertTrue(MathUtils.equalsIncludingNaN(new float[] { Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 1f, 0f }, new float[] { Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 1f, 0f })); assertFalse(MathUtils.equalsIncludingNaN(new float[] { Float.POSITIVE_INFINITY }, new float[] { Float.NEGATIVE_INFINITY })); // assertFalse(MathUtils.equalsIncludingNaN(new float[] { 1f }, // new float[] { FastMath.nextAfter(FastMath.nextAfter(1f, 2f), 2f) })); } public void testFactorial() { for (int i = 1; i < 21; i++) { assertEquals(i + "! ", factorial(i), MathUtils.factorial(i)); assertEquals(i + "! ", factorial(i), MathUtils.factorialDouble(i), Double.MIN_VALUE); assertEquals(i + "! ", FastMath.log(factorial(i)), MathUtils.factorialLog(i), 10E-12); } assertEquals("0", 1, MathUtils.factorial(0)); assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14); assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14); } public void testFactorialFail() { try { MathUtils.factorial(-1); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.factorialDouble(-1); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.factorialLog(-1); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) { // ignored } try { MathUtils.factorial(21); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) { // ignored } assertTrue("expecting infinite factorial value", Double.isInfinite(MathUtils.factorialDouble(171))); } public void testGcd() { int a = 30; int b = 50; int c = 77; assertEquals(0, MathUtils.gcd(0, 0)); assertEquals(b, MathUtils.gcd(0, b)); assertEquals(a, MathUtils.gcd(a, 0)); assertEquals(b, MathUtils.gcd(0, -b)); assertEquals(a, MathUtils.gcd(-a, 0)); assertEquals(10, MathUtils.gcd(a, b)); assertEquals(10, MathUtils.gcd(-a, b)); assertEquals(10, MathUtils.gcd(a, -b)); assertEquals(10, MathUtils.gcd(-a, -b)); assertEquals(1, MathUtils.gcd(a, c)); assertEquals(1, MathUtils.gcd(-a, c)); assertEquals(1, MathUtils.gcd(a, -c)); assertEquals(1, MathUtils.gcd(-a, -c)); assertEquals(3 * (1<<15), MathUtils.gcd(3 * (1<<20), 9 * (1<<15))); assertEquals(Integer.MAX_VALUE, MathUtils.gcd(Integer.MAX_VALUE, 0)); assertEquals(Integer.MAX_VALUE, MathUtils.gcd(-Integer.MAX_VALUE, 0)); assertEquals(1<<30, MathUtils.gcd(1<<30, -Integer.MIN_VALUE)); try { // gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE MathUtils.gcd(Integer.MIN_VALUE, 0); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE MathUtils.gcd(0, Integer.MIN_VALUE); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE MathUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } } public void testGcdLong(){ long a = 30; long b = 50; long c = 77; assertEquals(0, MathUtils.gcd(0L, 0)); assertEquals(b, MathUtils.gcd(0, b)); assertEquals(a, MathUtils.gcd(a, 0)); assertEquals(b, MathUtils.gcd(0, -b)); assertEquals(a, MathUtils.gcd(-a, 0)); assertEquals(10, MathUtils.gcd(a, b)); assertEquals(10, MathUtils.gcd(-a, b)); assertEquals(10, MathUtils.gcd(a, -b)); assertEquals(10, MathUtils.gcd(-a, -b)); assertEquals(1, MathUtils.gcd(a, c)); assertEquals(1, MathUtils.gcd(-a, c)); assertEquals(1, MathUtils.gcd(a, -c)); assertEquals(1, MathUtils.gcd(-a, -c)); assertEquals(3L * (1L<<45), MathUtils.gcd(3L * (1L<<50), 9L * (1L<<45))); assertEquals(1L<<45, MathUtils.gcd(1L<<45, Long.MIN_VALUE)); assertEquals(Long.MAX_VALUE, MathUtils.gcd(Long.MAX_VALUE, 0L)); assertEquals(Long.MAX_VALUE, MathUtils.gcd(-Long.MAX_VALUE, 0L)); assertEquals(1, MathUtils.gcd(60247241209L, 153092023L)); try { // gcd(Long.MIN_VALUE, 0) > Long.MAX_VALUE MathUtils.gcd(Long.MIN_VALUE, 0); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // gcd(0, Long.MIN_VALUE) > Long.MAX_VALUE MathUtils.gcd(0, Long.MIN_VALUE); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // gcd(Long.MIN_VALUE, Long.MIN_VALUE) > Long.MAX_VALUE MathUtils.gcd(Long.MIN_VALUE, Long.MIN_VALUE); fail("expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } } public void testGcdConsistency() { int[] primeList = {19, 23, 53, 67, 73, 79, 101, 103, 111, 131}; ArrayList primes = new ArrayList(); for (int i = 0; i < primeList.length; i++) { primes.add(Integer.valueOf(primeList[i])); } RandomDataImpl randomData = new RandomDataImpl(); for (int i = 0; i < 20; i++) { Object[] sample = randomData.nextSample(primes, 4); int p1 = ((Integer) sample[0]).intValue(); int p2 = ((Integer) sample[1]).intValue(); int p3 = ((Integer) sample[2]).intValue(); int p4 = ((Integer) sample[3]).intValue(); int i1 = p1 * p2 * p3; int i2 = p1 * p2 * p4; int gcd = p1 * p2; assertEquals(gcd, MathUtils.gcd(i1, i2)); long l1 = i1; long l2 = i2; assertEquals(gcd, MathUtils.gcd(l1, l2)); } } public void testHash() { double[] testArray = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d, 1E-14, (1 + 1E-14), Double.MIN_VALUE, Double.MAX_VALUE }; for (int i = 0; i < testArray.length; i++) { for (int j = 0; j < testArray.length; j++) { if (i == j) { assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j])); assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i])); } else { assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j])); assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i])); } } } } public void testArrayHash() { assertEquals(0, MathUtils.hash((double[]) null)); assertEquals(MathUtils.hash(new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }), MathUtils.hash(new double[] { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d })); assertFalse(MathUtils.hash(new double[] { 1d }) == MathUtils.hash(new double[] { FastMath.nextAfter(1d, 2d) })); assertFalse(MathUtils.hash(new double[] { 1d }) == MathUtils.hash(new double[] { 1d, 1d })); } /** * Make sure that permuted arrays do not hash to the same value. */ public void testPermutedArrayHash() { double[] original = new double[10]; double[] permuted = new double[10]; RandomDataImpl random = new RandomDataImpl(); // Generate 10 distinct random values for (int i = 0; i < 10; i++) { original[i] = random.nextUniform(i + 0.5, i + 0.75); } // Generate a random permutation, making sure it is not the identity boolean isIdentity = true; do { int[] permutation = random.nextPermutation(10, 10); for (int i = 0; i < 10; i++) { if (i != permutation[i]) { isIdentity = false; } permuted[i] = original[permutation[i]]; } } while (isIdentity); // Verify that permuted array has different hash assertFalse(MathUtils.hash(original) == MathUtils.hash(permuted)); } public void testIndicatorByte() { assertEquals((byte)1, MathUtils.indicator((byte)2)); assertEquals((byte)1, MathUtils.indicator((byte)0)); assertEquals((byte)(-1), MathUtils.indicator((byte)(-2))); } public void testIndicatorDouble() { double delta = 0.0; assertEquals(1.0, MathUtils.indicator(2.0), delta); assertEquals(1.0, MathUtils.indicator(0.0), delta); assertEquals(-1.0, MathUtils.indicator(-2.0), delta); assertEquals(Double.NaN, MathUtils.indicator(Double.NaN)); } public void testIndicatorFloat() { float delta = 0.0F; assertEquals(1.0F, MathUtils.indicator(2.0F), delta); assertEquals(1.0F, MathUtils.indicator(0.0F), delta); assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta); } public void testIndicatorInt() { assertEquals(1, MathUtils.indicator((2))); assertEquals(1, MathUtils.indicator((0))); assertEquals((-1), MathUtils.indicator((-2))); } public void testIndicatorLong() { assertEquals(1L, MathUtils.indicator(2L)); assertEquals(1L, MathUtils.indicator(0L)); assertEquals(-1L, MathUtils.indicator(-2L)); } public void testIndicatorShort() { assertEquals((short)1, MathUtils.indicator((short)2)); assertEquals((short)1, MathUtils.indicator((short)0)); assertEquals((short)(-1), MathUtils.indicator((short)(-2))); } public void testLcm() { int a = 30; int b = 50; int c = 77; assertEquals(0, MathUtils.lcm(0, b)); assertEquals(0, MathUtils.lcm(a, 0)); assertEquals(b, MathUtils.lcm(1, b)); assertEquals(a, MathUtils.lcm(a, 1)); assertEquals(150, MathUtils.lcm(a, b)); assertEquals(150, MathUtils.lcm(-a, b)); assertEquals(150, MathUtils.lcm(a, -b)); assertEquals(150, MathUtils.lcm(-a, -b)); assertEquals(2310, MathUtils.lcm(a, c)); // Assert that no intermediate value overflows: // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b) assertEquals((1<<20)*15, MathUtils.lcm((1<<20)*3, (1<<20)*5)); // Special case assertEquals(0, MathUtils.lcm(0, 0)); try { // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int MathUtils.lcm(Integer.MIN_VALUE, 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int MathUtils.lcm(Integer.MIN_VALUE, 1<<20); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { MathUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } } public void testLcmLong() { long a = 30; long b = 50; long c = 77; assertEquals(0, MathUtils.lcm(0, b)); assertEquals(0, MathUtils.lcm(a, 0)); assertEquals(b, MathUtils.lcm(1, b)); assertEquals(a, MathUtils.lcm(a, 1)); assertEquals(150, MathUtils.lcm(a, b)); assertEquals(150, MathUtils.lcm(-a, b)); assertEquals(150, MathUtils.lcm(a, -b)); assertEquals(150, MathUtils.lcm(-a, -b)); assertEquals(2310, MathUtils.lcm(a, c)); assertEquals(Long.MAX_VALUE, MathUtils.lcm(60247241209L, 153092023L)); // Assert that no intermediate value overflows: // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b) assertEquals((1L<<50)*15, MathUtils.lcm((1L<<45)*3, (1L<<50)*5)); // Special case assertEquals(0L, MathUtils.lcm(0L, 0L)); try { // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int MathUtils.lcm(Long.MIN_VALUE, 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } try { // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int MathUtils.lcm(Long.MIN_VALUE, 1<<20); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } assertEquals((long) Integer.MAX_VALUE * (Integer.MAX_VALUE - 1), MathUtils.lcm((long)Integer.MAX_VALUE, Integer.MAX_VALUE - 1)); try { MathUtils.lcm(Long.MAX_VALUE, Long.MAX_VALUE - 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException expected) { // expected } } public void testLog() { assertEquals(2.0, MathUtils.log(2, 4), 0); assertEquals(3.0, MathUtils.log(2, 8), 0); assertTrue(Double.isNaN(MathUtils.log(-1, 1))); assertTrue(Double.isNaN(MathUtils.log(1, -1))); assertTrue(Double.isNaN(MathUtils.log(0, 0))); assertEquals(0, MathUtils.log(0, 10), 0); assertEquals(Double.NEGATIVE_INFINITY, MathUtils.log(10, 0), 0); } public void testMulAndCheck() { int big = Integer.MAX_VALUE; int bigNeg = Integer.MIN_VALUE; assertEquals(big, MathUtils.mulAndCheck(big, 1)); try { MathUtils.mulAndCheck(big, 2); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } try { MathUtils.mulAndCheck(bigNeg, 2); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } } public void testMulAndCheckLong() { long max = Long.MAX_VALUE; long min = Long.MIN_VALUE; assertEquals(max, MathUtils.mulAndCheck(max, 1L)); assertEquals(min, MathUtils.mulAndCheck(min, 1L)); assertEquals(0L, MathUtils.mulAndCheck(max, 0L)); assertEquals(0L, MathUtils.mulAndCheck(min, 0L)); assertEquals(max, MathUtils.mulAndCheck(1L, max)); assertEquals(min, MathUtils.mulAndCheck(1L, min)); assertEquals(0L, MathUtils.mulAndCheck(0L, max)); assertEquals(0L, MathUtils.mulAndCheck(0L, min)); assertEquals(1L, MathUtils.mulAndCheck(-1L, -1L)); assertEquals(min, MathUtils.mulAndCheck(min / 2, 2)); testMulAndCheckLongFailure(max, 2L); testMulAndCheckLongFailure(2L, max); testMulAndCheckLongFailure(min, 2L); testMulAndCheckLongFailure(2L, min); testMulAndCheckLongFailure(min, -1L); testMulAndCheckLongFailure(-1L, min); } private void testMulAndCheckLongFailure(long a, long b) { try { MathUtils.mulAndCheck(a, b); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // success } } public void testNextAfter() { // Test from Math 2.1 // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000 assertEquals(16.0, MathUtils.nextAfter(15.999999999999998, 34.27555555555555), 0.0); // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 34.27555555555555), 0.0); // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe assertEquals(15.999999999999996, MathUtils.nextAfter(15.999999999999998, 2.142222222222222), 0.0); // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 2.142222222222222), 0.0); // 0x4020000000000000 0x404123456789abcd -> 4020000000000001 assertEquals(8.000000000000002, MathUtils.nextAfter(8.0, 34.27555555555555), 0.0); // 0xc020000000000000 0x404123456789abcd -> c01fffffffffffff assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 34.27555555555555), 0.0); // 0x4020000000000000 0x400123456789abcd -> 401fffffffffffff assertEquals(7.999999999999999, MathUtils.nextAfter(8.0, 2.142222222222222), 0.0); // 0xc020000000000000 0x400123456789abcd -> c01fffffffffffff assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 2.142222222222222), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a224 -> 3f2e43753d36a224 assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.308922399667661E-4), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a223 -> 3f2e43753d36a224 assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); // 0x3f2e43753d36a223 0x3f2e43753d36a222 -> 3f2e43753d36a222 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a224 -> 3f2e43753d36a222 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.308922399667661E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a223 -> 3f2e43753d36a222 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); // 0x3f2e43753d36a223 0xbf2e43753d36a222 -> 3f2e43753d36a222 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a224 -> bf2e43753d36a222 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.308922399667661E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a223 -> bf2e43753d36a222 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); // 0xbf2e43753d36a223 0x3f2e43753d36a222 -> bf2e43753d36a222 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a224 -> bf2e43753d36a224 assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.308922399667661E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a223 -> bf2e43753d36a224 assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); // 0xbf2e43753d36a223 0xbf2e43753d36a222 -> bf2e43753d36a222 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); } public void testNextAfterSpecialCases() { assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0))); assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0))); assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0))); assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY))); assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY))); assertEquals(Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0); assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0); assertEquals(0, MathUtils.nextAfter(Double.MIN_VALUE, -1), 0); assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0); } public void testScalb() { // Math 2.1 assertEquals( 0.0, MathUtils.scalb(0.0, 5), 1.0e-15); assertEquals(32.0, MathUtils.scalb(1.0, 5), 1.0e-15); assertEquals(1.0 / 32.0, MathUtils.scalb(1.0, -5), 1.0e-15); assertEquals(Math.PI, MathUtils.scalb(Math.PI, 0), 1.0e-15); assertTrue(Double.isInfinite(MathUtils.scalb(Double.POSITIVE_INFINITY, 1))); assertTrue(Double.isInfinite(MathUtils.scalb(Double.NEGATIVE_INFINITY, 1))); assertTrue(Double.isNaN(MathUtils.scalb(Double.NaN, 1))); } public void testNormalizeAngle() { for (double a = -15.0; a <= 15.0; a += 0.1) { for (double b = -15.0; b <= 15.0; b += 0.2) { double c = MathUtils.normalizeAngle(a, b); assertTrue((b - FastMath.PI) <= c); assertTrue(c <= (b + FastMath.PI)); double twoK = FastMath.rint((a - c) / FastMath.PI); assertEquals(c, a - twoK * FastMath.PI, 1.0e-14); } } } public void testNormalizeArray() { double[] testValues1 = new double[] {1, 1, 2}; TestUtils.assertEquals( new double[] {.25, .25, .5}, MathUtils.normalizeArray(testValues1, 1), Double.MIN_VALUE); double[] testValues2 = new double[] {-1, -1, 1}; TestUtils.assertEquals( new double[] {1, 1, -1}, MathUtils.normalizeArray(testValues2, 1), Double.MIN_VALUE); // Ignore NaNs double[] testValues3 = new double[] {-1, -1, Double.NaN, 1, Double.NaN}; TestUtils.assertEquals( new double[] {1, 1,Double.NaN, -1, Double.NaN}, MathUtils.normalizeArray(testValues3, 1), Double.MIN_VALUE); // Zero sum -> ArithmeticException double[] zeroSum = new double[] {-1, 1}; try { MathUtils.normalizeArray(zeroSum, 1); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} // Infinite elements -> ArithmeticException double[] hasInf = new double[] {1, 2, 1, Double.NEGATIVE_INFINITY}; try { MathUtils.normalizeArray(hasInf, 1); fail("expecting ArithmeticException"); } catch (ArithmeticException ex) {} // Infinite target -> IllegalArgumentException try { MathUtils.normalizeArray(testValues1, Double.POSITIVE_INFINITY); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) {} // NaN target -> IllegalArgumentException try { MathUtils.normalizeArray(testValues1, Double.NaN); fail("expecting IllegalArgumentException"); } catch (IllegalArgumentException ex) {} } public void testRoundDouble() { double x = 1.234567890; assertEquals(1.23, MathUtils.round(x, 2), 0.0); assertEquals(1.235, MathUtils.round(x, 3), 0.0); assertEquals(1.2346, MathUtils.round(x, 4), 0.0); // JIRA MATH-151 assertEquals(39.25, MathUtils.round(39.245, 2), 0.0); assertEquals(39.24, MathUtils.round(39.245, 2, BigDecimal.ROUND_DOWN), 0.0); double xx = 39.0; xx = xx + 245d / 1000d; assertEquals(39.25, MathUtils.round(xx, 2), 0.0); // BZ 35904 assertEquals(30.1d, MathUtils.round(30.095d, 2), 0.0d); assertEquals(30.1d, MathUtils.round(30.095d, 1), 0.0d); assertEquals(33.1d, MathUtils.round(33.095d, 1), 0.0d); assertEquals(33.1d, MathUtils.round(33.095d, 2), 0.0d); assertEquals(50.09d, MathUtils.round(50.085d, 2), 0.0d); assertEquals(50.19d, MathUtils.round(50.185d, 2), 0.0d); assertEquals(50.01d, MathUtils.round(50.005d, 2), 0.0d); assertEquals(30.01d, MathUtils.round(30.005d, 2), 0.0d); assertEquals(30.65d, MathUtils.round(30.645d, 2), 0.0d); assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.236, MathUtils.round(1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.236, MathUtils.round(-1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.235, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.235, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.23, MathUtils.round(-1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); assertEquals(1.23, MathUtils.round(1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); try { MathUtils.round(1.234, 2, BigDecimal.ROUND_UNNECESSARY); fail(); } catch (ArithmeticException ex) { // success } assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0); assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0); assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0); try { MathUtils.round(1.234, 2, 1923); fail(); } catch (IllegalArgumentException ex) { // success } // MATH-151 assertEquals(39.25, MathUtils.round(39.245, 2, BigDecimal.ROUND_HALF_UP), 0.0); // special values TestUtils.assertEquals(Double.NaN, MathUtils.round(Double.NaN, 2), 0.0); assertEquals(0.0, MathUtils.round(0.0, 2), 0.0); assertEquals(Double.POSITIVE_INFINITY, MathUtils.round(Double.POSITIVE_INFINITY, 2), 0.0); assertEquals(Double.NEGATIVE_INFINITY, MathUtils.round(Double.NEGATIVE_INFINITY, 2), 0.0); } public void testRoundFloat() { float x = 1.234567890f; assertEquals(1.23f, MathUtils.round(x, 2), 0.0); assertEquals(1.235f, MathUtils.round(x, 3), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4), 0.0); // BZ 35904 assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f); assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f); assertEquals(50.09f, MathUtils.round(50.085f, 2), 0.0f); assertEquals(50.19f, MathUtils.round(50.185f, 2), 0.0f); assertEquals(50.01f, MathUtils.round(50.005f, 2), 0.0f); assertEquals(30.01f, MathUtils.round(30.005f, 2), 0.0f); assertEquals(30.65f, MathUtils.round(30.645f, 2), 0.0f); assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0); assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0); assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0); assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0); assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0); assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0); assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); try { MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY); fail(); } catch (ArithmeticException ex) { // success } assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0); assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0); assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0); assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0); try { MathUtils.round(1.234f, 2, 1923); fail(); } catch (IllegalArgumentException ex) { // success } // special values TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f); assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f); assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f); assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f); } public void testSignByte() { assertEquals((byte) 1, MathUtils.sign((byte) 2)); assertEquals((byte) 0, MathUtils.sign((byte) 0)); assertEquals((byte) (-1), MathUtils.sign((byte) (-2))); } public void testSignDouble() { double delta = 0.0; assertEquals(1.0, MathUtils.sign(2.0), delta); assertEquals(0.0, MathUtils.sign(0.0), delta); assertEquals(-1.0, MathUtils.sign(-2.0), delta); TestUtils.assertSame(-0. / 0., MathUtils.sign(Double.NaN)); } public void testSignFloat() { float delta = 0.0F; assertEquals(1.0F, MathUtils.sign(2.0F), delta); assertEquals(0.0F, MathUtils.sign(0.0F), delta); assertEquals(-1.0F, MathUtils.sign(-2.0F), delta); TestUtils.assertSame(Float.NaN, MathUtils.sign(Float.NaN)); } public void testSignInt() { assertEquals(1, MathUtils.sign(2)); assertEquals(0, MathUtils.sign(0)); assertEquals((-1), MathUtils.sign((-2))); } public void testSignLong() { assertEquals(1L, MathUtils.sign(2L)); assertEquals(0L, MathUtils.sign(0L)); assertEquals(-1L, MathUtils.sign(-2L)); } public void testSignShort() { assertEquals((short) 1, MathUtils.sign((short) 2)); assertEquals((short) 0, MathUtils.sign((short) 0)); assertEquals((short) (-1), MathUtils.sign((short) (-2))); } public void testSinh() { double x = 3.0; double expected = 10.01787; assertEquals(expected, MathUtils.sinh(x), 1.0e-5); } public void testSinhNaN() { assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN))); } public void testSubAndCheck() { int big = Integer.MAX_VALUE; int bigNeg = Integer.MIN_VALUE; assertEquals(big, MathUtils.subAndCheck(big, 0)); assertEquals(bigNeg + 1, MathUtils.subAndCheck(bigNeg, -1)); assertEquals(-1, MathUtils.subAndCheck(bigNeg, -big)); try { MathUtils.subAndCheck(big, -1); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } try { MathUtils.subAndCheck(bigNeg, 1); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { } } public void testSubAndCheckErrorMessage() { int big = Integer.MAX_VALUE; try { MathUtils.subAndCheck(big, -1); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { assertTrue(ex.getMessage().length() > 1); } } public void testSubAndCheckLong() { long max = Long.MAX_VALUE; long min = Long.MIN_VALUE; assertEquals(max, MathUtils.subAndCheck(max, 0)); assertEquals(min, MathUtils.subAndCheck(min, 0)); assertEquals(-max, MathUtils.subAndCheck(0, max)); assertEquals(min + 1, MathUtils.subAndCheck(min, -1)); // min == -1-max assertEquals(-1, MathUtils.subAndCheck(-max - 1, -max)); assertEquals(max, MathUtils.subAndCheck(-1, -1 - max)); testSubAndCheckLongFailure(0L, min); testSubAndCheckLongFailure(max, -1L); testSubAndCheckLongFailure(min, 1L); } private void testSubAndCheckLongFailure(long a, long b) { try { MathUtils.subAndCheck(a, b); fail("Expecting ArithmeticException"); } catch (ArithmeticException ex) { // success } } public void testPow() { assertEquals(1801088541, MathUtils.pow(21, 7)); assertEquals(1, MathUtils.pow(21, 0)); try { MathUtils.pow(21, -7); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } assertEquals(1801088541, MathUtils.pow(21, 7l)); assertEquals(1, MathUtils.pow(21, 0l)); try { MathUtils.pow(21, -7l); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } assertEquals(1801088541l, MathUtils.pow(21l, 7)); assertEquals(1l, MathUtils.pow(21l, 0)); try { MathUtils.pow(21l, -7); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } assertEquals(1801088541l, MathUtils.pow(21l, 7l)); assertEquals(1l, MathUtils.pow(21l, 0l)); try { MathUtils.pow(21l, -7l); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } BigInteger twentyOne = BigInteger.valueOf(21l); assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7)); assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0)); try { MathUtils.pow(twentyOne, -7); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7l)); assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0l)); try { MathUtils.pow(twentyOne, -7l); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, BigInteger.valueOf(7l))); assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, BigInteger.ZERO)); try { MathUtils.pow(twentyOne, BigInteger.valueOf(-7l)); fail("Expecting IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected behavior } BigInteger bigOne = new BigInteger("1543786922199448028351389769265814882661837148" + "4763915343722775611762713982220306372888519211" + "560905579993523402015636025177602059044911261"); assertEquals(bigOne, MathUtils.pow(twentyOne, 103)); assertEquals(bigOne, MathUtils.pow(twentyOne, 103l)); assertEquals(bigOne, MathUtils.pow(twentyOne, BigInteger.valueOf(103l))); } public void testL1DistanceDouble() { double[] p1 = { 2.5, 0.0 }; double[] p2 = { -0.5, 4.0 }; assertEquals(7.0, MathUtils.distance1(p1, p2)); } public void testL1DistanceInt() { int[] p1 = { 3, 0 }; int[] p2 = { 0, 4 }; assertEquals(7, MathUtils.distance1(p1, p2)); } public void testL2DistanceDouble() { double[] p1 = { 2.5, 0.0 }; double[] p2 = { -0.5, 4.0 }; assertEquals(5.0, MathUtils.distance(p1, p2)); } public void testL2DistanceInt() { int[] p1 = { 3, 0 }; int[] p2 = { 0, 4 }; assertEquals(5.0, MathUtils.distance(p1, p2)); } public void testLInfDistanceDouble() { double[] p1 = { 2.5, 0.0 }; double[] p2 = { -0.5, 4.0 }; assertEquals(4.0, MathUtils.distanceInf(p1, p2)); } public void testLInfDistanceInt() { int[] p1 = { 3, 0 }; int[] p2 = { 0, 4 }; assertEquals(4, MathUtils.distanceInf(p1, p2)); } public void testCheckOrder21() { // Test from 2.1 MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 15}, 1, true); MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 2}, 1, false); MathUtils.checkOrder(new double[] {3, -5.5, -11, -27.5}, -1, true); MathUtils.checkOrder(new double[] {3, 0, 0, -5.5, -11, -27.5}, -1, false); try { MathUtils.checkOrder(new double[] {-15, -5.5, -1, -1, 2, 15}, 1, true); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } try { MathUtils.checkOrder(new double[] {-15, -5.5, -1, -2, 2}, 1, false); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } try { MathUtils.checkOrder(new double[] {3, 3, -5.5, -11, -27.5}, -1, true); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } try { MathUtils.checkOrder(new double[] {3, -1, 0, -5.5, -11, -27.5}, -1, false); fail("an exception should have been thrown"); } catch (IllegalArgumentException e) { // Expected } } public void testCheckOrder() { MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 15}, MathUtils.OrderDirection.INCREASING, true); MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 2}, MathUtils.OrderDirection.INCREASING, false); MathUtils.checkOrder(new double[] {3, -5.5, -11, -27.5}, MathUtils.OrderDirection.DECREASING, true); MathUtils.checkOrder(new double[] {3, 0, 0, -5.5, -11, -27.5}, MathUtils.OrderDirection.DECREASING, false); try { MathUtils.checkOrder(new double[] {-15, -5.5, -1, -1, 2, 15}, MathUtils.OrderDirection.INCREASING, true); fail("an exception should have been thrown"); } catch (NonMonotonousSequenceException e) { // Expected } try { MathUtils.checkOrder(new double[] {-15, -5.5, -1, -2, 2}, MathUtils.OrderDirection.INCREASING, false); fail("an exception should have been thrown"); } catch (NonMonotonousSequenceException e) { // Expected } try { MathUtils.checkOrder(new double[] {3, 3, -5.5, -11, -27.5}, MathUtils.OrderDirection.DECREASING, true); fail("an exception should have been thrown"); } catch (NonMonotonousSequenceException e) { // Expected } try { MathUtils.checkOrder(new double[] {3, -1, 0, -5.5, -11, -27.5}, MathUtils.OrderDirection.DECREASING, false); fail("an exception should have been thrown"); } catch (NonMonotonousSequenceException e) { // Expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/BigRealFieldTest.java100644 1750 1750 2756 11532241244 27341 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.math.TestUtils; import org.junit.Test; public class BigRealFieldTest { @Test public void testZero() { assertEquals(BigReal.ZERO, BigRealField.getInstance().getZero()); } @Test public void testOne() { assertEquals(BigReal.ONE, BigRealField.getInstance().getOne()); } @Test public void testSerial() { // deserializing the singleton should give the singleton itself back BigRealField field = BigRealField.getInstance(); assertTrue(field == TestUtils.serializeAndRecover(field)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/MultidimensionalCounterTest.java100644 1750 1750 13207 11532241244 31756 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.junit.Assert; import org.junit.Test; /** * */ public class MultidimensionalCounterTest { @Test public void testPreconditions() { MultidimensionalCounter c; try { c = new MultidimensionalCounter(0, 1); Assert.fail("NotStrictlyPositiveException expected"); } catch (NotStrictlyPositiveException e) { // Expected. } try { c = new MultidimensionalCounter(2, 0); Assert.fail("NotStrictlyPositiveException expected"); } catch (NotStrictlyPositiveException e) { // Expected. } try { c = new MultidimensionalCounter(-1, 1); Assert.fail("NotStrictlyPositiveException expected"); } catch (NotStrictlyPositiveException e) { // Expected. } c = new MultidimensionalCounter(2, 3); try { c.getCount(1, 1, 1); Assert.fail("DimensionMismatchException expected"); } catch (DimensionMismatchException e) { // Expected. } try { c.getCount(3, 1); Assert.fail("OutOfRangeException expected"); } catch (OutOfRangeException e) { // Expected. } try { c.getCount(0, -1); Assert.fail("OutOfRangeException expected"); } catch (OutOfRangeException e) { // Expected. } try { c.getCounts(-1); Assert.fail("OutOfRangeException expected"); } catch (OutOfRangeException e) { // Expected. } try { c.getCounts(6); Assert.fail("OutOfRangeException expected"); } catch (OutOfRangeException e) { // Expected. } } @Test public void testIteratorPreconditions() { MultidimensionalCounter.Iterator iter = (new MultidimensionalCounter(2, 3)).iterator(); try { iter.getCount(-1); Assert.fail("IndexOutOfBoundsException expected"); } catch (IndexOutOfBoundsException e) { // Expected. } try { iter.getCount(2); Assert.fail("IndexOutOfBoundsException expected"); } catch (IndexOutOfBoundsException e) { // Expected. } } @Test public void testMulti2UniConversion() { final MultidimensionalCounter c = new MultidimensionalCounter(2, 4, 5); Assert.assertEquals(c.getCount(1, 2, 3), 33); } @Test public void testAccessors() { final int[] originalSize = new int[] {2, 6, 5}; final MultidimensionalCounter c = new MultidimensionalCounter(originalSize); final int nDim = c.getDimension(); Assert.assertEquals(nDim, originalSize.length); final int[] size = c.getSizes(); for (int i = 0; i < nDim; i++) { Assert.assertEquals(originalSize[i], size[i]); } } @Test public void testIterationConsistency() { final MultidimensionalCounter c = new MultidimensionalCounter(2, 3, 2); final int[][] expected = new int[][] { { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 1 }, { 0, 2, 0 }, { 0, 2, 1 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, { 1, 2, 0 }, { 1, 2, 1 } }; final int totalSize = c.getSize(); final int nDim = c.getDimension(); final MultidimensionalCounter.Iterator iter = c.iterator(); for (int i = 0; i < totalSize; i++) { if (!iter.hasNext()) { Assert.fail("Too short"); } final int uniDimIndex = iter.next(); Assert.assertEquals("Wrong iteration at " + i, i, uniDimIndex); for (int dimIndex = 0; dimIndex < nDim; dimIndex++) { Assert.assertEquals("Wrong multidimensional index for [" + i + "][" + dimIndex + "]", expected[i][dimIndex], iter.getCount(dimIndex)); } Assert.assertEquals("Wrong unidimensional index for [" + i + "]", c.getCount(expected[i]), uniDimIndex); final int[] indices = c.getCounts(uniDimIndex); for (int dimIndex = 0; dimIndex < nDim; dimIndex++) { Assert.assertEquals("Wrong multidimensional index for [" + i + "][" + dimIndex + "]", expected[i][dimIndex], indices[dimIndex]); } } if (iter.hasNext()) { Assert.fail("Too long"); } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java100644 1750 1750 25116 11532241244 31357 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Random; import java.util.Set; import junit.framework.TestCase; /** * Test cases for the {@link OpenIntToDoubleHashMap}. */ public class OpenIntToDoubleHashMapTest extends TestCase { private Map javaMap = new HashMap(); @Override protected void setUp() throws Exception { javaMap.put(50, 100.0); javaMap.put(75, 75.0); javaMap.put(25, 500.0); javaMap.put(Integer.MAX_VALUE, Double.MAX_VALUE); javaMap.put(0, -1.0); javaMap.put(1, 0.0); javaMap.put(33, -0.1); javaMap.put(23234234, -242343.0); javaMap.put(23321, Double.MIN_VALUE); javaMap.put(-4444, 332.0); javaMap.put(-1, -2323.0); javaMap.put(Integer.MIN_VALUE, 44.0); /* Add a few more to cause the table to rehash */ javaMap.putAll(generate()); } private Map generate() { Map map = new HashMap(); Random r = new Random(); for (int i = 0; i < 2000; ++i) map.put(r.nextInt(), r.nextDouble()); return map; } private OpenIntToDoubleHashMap createFromJavaMap() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); } return map; } public void testPutAndGetWith0ExpectedSize() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(0); assertPutAndGet(map); } public void testPutAndGetWithExpectedSize() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(500); assertPutAndGet(map); } public void testPutAndGet() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); assertPutAndGet(map); } private void assertPutAndGet(OpenIntToDoubleHashMap map) { assertPutAndGet(map, 0, new HashSet()); } private void assertPutAndGet(OpenIntToDoubleHashMap map, int mapSize, Set keysInMap) { assertEquals(mapSize, map.size()); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); if (!keysInMap.contains(mapEntry.getKey())) ++mapSize; assertEquals(mapSize, map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testPutAbsentOnExisting() { OpenIntToDoubleHashMap map = createFromJavaMap(); int size = javaMap.size(); for (Map.Entry mapEntry : generateAbsent().entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); assertEquals(++size, map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testPutOnExisting() { OpenIntToDoubleHashMap map = createFromJavaMap(); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); assertEquals(javaMap.size(), map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testGetAbsent() { Map generated = generateAbsent(); OpenIntToDoubleHashMap map = createFromJavaMap(); for (Map.Entry mapEntry : generated.entrySet()) assertTrue(Double.isNaN(map.get(mapEntry.getKey()))); } public void testGetFromEmpty() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); assertTrue(Double.isNaN(map.get(5))); assertTrue(Double.isNaN(map.get(0))); assertTrue(Double.isNaN(map.get(50))); } public void testRemove() { OpenIntToDoubleHashMap map = createFromJavaMap(); int mapSize = javaMap.size(); assertEquals(mapSize, map.size()); for (Map.Entry mapEntry : javaMap.entrySet()) { map.remove(mapEntry.getKey()); assertEquals(--mapSize, map.size()); assertTrue(Double.isNaN(map.get(mapEntry.getKey()))); } /* Ensure that put and get still work correctly after removals */ assertPutAndGet(map); } /* This time only remove some entries */ public void testRemove2() { OpenIntToDoubleHashMap map = createFromJavaMap(); int mapSize = javaMap.size(); int count = 0; Set keysInMap = new HashSet(javaMap.keySet()); for (Map.Entry mapEntry : javaMap.entrySet()) { keysInMap.remove(mapEntry.getKey()); map.remove(mapEntry.getKey()); assertEquals(--mapSize, map.size()); assertTrue(Double.isNaN(map.get(mapEntry.getKey()))); if (count++ > 5) break; } /* Ensure that put and get still work correctly after removals */ assertPutAndGet(map, mapSize, keysInMap); } public void testRemoveFromEmpty() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); assertTrue(Double.isNaN(map.remove(50))); } public void testRemoveAbsent() { Map generated = generateAbsent(); OpenIntToDoubleHashMap map = createFromJavaMap(); int mapSize = map.size(); for (Map.Entry mapEntry : generated.entrySet()) { map.remove(mapEntry.getKey()); assertEquals(mapSize, map.size()); assertTrue(Double.isNaN(map.get(mapEntry.getKey()))); } } /** * Returns a map with at least 100 elements where each element is absent from javaMap. */ private Map generateAbsent() { Map generated = new HashMap(); do { generated.putAll(generate()); for (Integer key : javaMap.keySet()) generated.remove(key); } while (generated.size() < 100); return generated; } public void testCopy() { OpenIntToDoubleHashMap copy = new OpenIntToDoubleHashMap(createFromJavaMap()); assertEquals(javaMap.size(), copy.size()); for (Map.Entry mapEntry : javaMap.entrySet()) assertEquals(mapEntry.getValue(), copy.get(mapEntry.getKey())); } public void testContainsKey() { OpenIntToDoubleHashMap map = createFromJavaMap(); for (Map.Entry mapEntry : javaMap.entrySet()) { assertTrue(map.containsKey(mapEntry.getKey())); } for (Map.Entry mapEntry : generateAbsent().entrySet()) { assertFalse(map.containsKey(mapEntry.getKey())); } for (Map.Entry mapEntry : javaMap.entrySet()) { int key = mapEntry.getKey(); assertTrue(map.containsKey(key)); map.remove(key); assertFalse(map.containsKey(key)); } } public void testIterator() { OpenIntToDoubleHashMap map = createFromJavaMap(); OpenIntToDoubleHashMap.Iterator iterator = map.iterator(); for (int i = 0; i < map.size(); ++i) { assertTrue(iterator.hasNext()); iterator.advance(); int key = iterator.key(); assertTrue(map.containsKey(key)); assertEquals(javaMap.get(key), map.get(key), 0); assertEquals(javaMap.get(key), iterator.value(), 0); assertTrue(javaMap.containsKey(key)); } assertFalse(iterator.hasNext()); try { iterator.advance(); fail("an exception should have been thrown"); } catch (NoSuchElementException nsee) { // expected } } public void testConcurrentModification() { OpenIntToDoubleHashMap map = createFromJavaMap(); OpenIntToDoubleHashMap.Iterator iterator = map.iterator(); map.put(3, 3); try { iterator.advance(); fail("an exception should have been thrown"); } catch (ConcurrentModificationException cme) { // expected } } /** * Regression test for a bug in findInsertionIndex where the hashing in the second probing * loop was inconsistent with the first causing duplicate keys after the right sequence * of puts and removes. */ public void testPutKeysWithCollisions() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); int key1 = -1996012590; double value1 = 1.0; map.put(key1, value1); int key2 = 835099822; map.put(key2, value1); int key3 = 1008859686; map.put(key3, value1); assertEquals(value1, map.get(key3)); assertEquals(3, map.size()); map.remove(key2); double value2 = 2.0; map.put(key3, value2); assertEquals(value2, map.get(key3)); assertEquals(2, map.size()); } /** * Similar to testPutKeysWithCollisions() but exercises the codepaths in a slightly * different manner. */ public void testPutKeysWithCollision2() { OpenIntToDoubleHashMap map = new OpenIntToDoubleHashMap(); int key1 = 837989881; double value1 = 1.0; map.put(key1, value1); int key2 = 476463321; map.put(key2, value1); assertEquals(2, map.size()); assertEquals(value1, map.get(key2)); map.remove(key1); double value2 = 2.0; map.put(key2, value2); assertEquals(1, map.size()); assertEquals(value2, map.get(key2)); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/util/OpenIntToFieldTest.java100644 1750 1750 27376 11532241244 27740 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Random; import java.util.Set; import java.util.Map.Entry; import org.apache.commons.math.Field; import org.apache.commons.math.fraction.Fraction; import org.apache.commons.math.fraction.FractionConversionException; import org.apache.commons.math.fraction.FractionField; import junit.framework.TestCase; public class OpenIntToFieldTest extends TestCase { private Map javaMap = new HashMap(); private FractionField field = FractionField.getInstance(); @Override protected void setUp() throws Exception { javaMap.put(50, new Fraction(100.0)); javaMap.put(75, new Fraction(75.0)); javaMap.put(25, new Fraction(500.0)); javaMap.put(Integer.MAX_VALUE, new Fraction(Integer.MAX_VALUE)); javaMap.put(0, new Fraction(-1.0)); javaMap.put(1, new Fraction(0.0)); javaMap.put(33, new Fraction(-0.1)); javaMap.put(23234234, new Fraction(-242343.0)); javaMap.put(23321, new Fraction (Integer.MIN_VALUE)); javaMap.put(-4444, new Fraction(332.0)); javaMap.put(-1, new Fraction(-2323.0)); javaMap.put(Integer.MIN_VALUE, new Fraction(44.0)); /* Add a few more to cause the table to rehash */ javaMap.putAll(generate()); } private Map generate() { Map map = new HashMap(); Random r = new Random(); double dd=0; for (int i = 0; i < 2000; ++i) dd = r.nextDouble(); try { map.put(r.nextInt(), new Fraction(dd)); } catch (FractionConversionException e) { throw new IllegalStateException("Invalid :"+dd, e); } return map; } private OpenIntToFieldHashMap createFromJavaMap(Field field) { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); } return map; } public void testPutAndGetWith0ExpectedSize() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field,0); assertPutAndGet(map); } public void testPutAndGetWithExpectedSize() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field,500); assertPutAndGet(map); } public void testPutAndGet() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field); assertPutAndGet(map); } private void assertPutAndGet(OpenIntToFieldHashMap map) { assertPutAndGet(map, 0, new HashSet()); } private void assertPutAndGet(OpenIntToFieldHashMap map, int mapSize, Set keysInMap) { assertEquals(mapSize, map.size()); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); if (!keysInMap.contains(mapEntry.getKey())) ++mapSize; assertEquals(mapSize, map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testPutAbsentOnExisting() { OpenIntToFieldHashMap map = createFromJavaMap(field); int size = javaMap.size(); for (Map.Entry mapEntry : generateAbsent().entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); assertEquals(++size, map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testPutOnExisting() { OpenIntToFieldHashMap map = createFromJavaMap(field); for (Map.Entry mapEntry : javaMap.entrySet()) { map.put(mapEntry.getKey(), mapEntry.getValue()); assertEquals(javaMap.size(), map.size()); assertEquals(mapEntry.getValue(), map.get(mapEntry.getKey())); } } public void testGetAbsent() { Map generated = generateAbsent(); OpenIntToFieldHashMap map = createFromJavaMap(field); for (Map.Entry mapEntry : generated.entrySet()) assertTrue(field.getZero().equals(map.get(mapEntry.getKey()))); } public void testGetFromEmpty() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field); assertTrue(field.getZero().equals(map.get(5))); assertTrue(field.getZero().equals(map.get(0))); assertTrue(field.getZero().equals(map.get(50))); } public void testRemove() { OpenIntToFieldHashMap map = createFromJavaMap(field); int mapSize = javaMap.size(); assertEquals(mapSize, map.size()); for (Map.Entry mapEntry : javaMap.entrySet()) { map.remove(mapEntry.getKey()); assertEquals(--mapSize, map.size()); assertTrue(field.getZero().equals(map.get(mapEntry.getKey()))); } /* Ensure that put and get still work correctly after removals */ assertPutAndGet(map); } /* This time only remove some entries */ public void testRemove2() { OpenIntToFieldHashMap map = createFromJavaMap(field); int mapSize = javaMap.size(); int count = 0; Set keysInMap = new HashSet(javaMap.keySet()); for (Map.Entry mapEntry : javaMap.entrySet()) { keysInMap.remove(mapEntry.getKey()); map.remove(mapEntry.getKey()); assertEquals(--mapSize, map.size()); assertTrue(field.getZero().equals(map.get(mapEntry.getKey()))); if (count++ > 5) break; } /* Ensure that put and get still work correctly after removals */ assertPutAndGet(map, mapSize, keysInMap); } public void testRemoveFromEmpty() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field); assertTrue(field.getZero().equals(map.remove(50))); } public void testRemoveAbsent() { Map generated = generateAbsent(); OpenIntToFieldHashMap map = createFromJavaMap(field); int mapSize = map.size(); for (Map.Entry mapEntry : generated.entrySet()) { map.remove(mapEntry.getKey()); assertEquals(mapSize, map.size()); assertTrue(field.getZero().equals(map.get(mapEntry.getKey()))); } } /** * Returns a map with at least 100 elements where each element is absent from javaMap. */ private Map generateAbsent() { Map generated = new HashMap(); do { generated.putAll(generate()); for (Integer key : javaMap.keySet()) generated.remove(key); } while (generated.size() < 100); return generated; } public void testCopy() { OpenIntToFieldHashMap copy = new OpenIntToFieldHashMap(createFromJavaMap(field)); assertEquals(javaMap.size(), copy.size()); for (Map.Entry mapEntry : javaMap.entrySet()) assertEquals(mapEntry.getValue(), copy.get(mapEntry.getKey())); } public void testContainsKey() { OpenIntToFieldHashMap map = createFromJavaMap(field); for (Entry mapEntry : javaMap.entrySet()) { assertTrue(map.containsKey(mapEntry.getKey())); } for (Map.Entry mapEntry : generateAbsent().entrySet()) { assertFalse(map.containsKey(mapEntry.getKey())); } for (Entry mapEntry : javaMap.entrySet()) { int key = mapEntry.getKey(); assertTrue(map.containsKey(key)); map.remove(key); assertFalse(map.containsKey(key)); } } public void testIterator() { OpenIntToFieldHashMap map = createFromJavaMap(field); OpenIntToFieldHashMap.Iterator iterator = map.iterator(); for (int i = 0; i < map.size(); ++i) { assertTrue(iterator.hasNext()); iterator.advance(); int key = iterator.key(); assertTrue(map.containsKey(key)); assertEquals(javaMap.get(key), map.get(key)); assertEquals(javaMap.get(key), iterator.value()); assertTrue(javaMap.containsKey(key)); } assertFalse(iterator.hasNext()); try { iterator.advance(); fail("an exception should have been thrown"); } catch (NoSuchElementException nsee) { // expected } } public void testConcurrentModification() { OpenIntToFieldHashMap map = createFromJavaMap(field); OpenIntToFieldHashMap.Iterator iterator = map.iterator(); map.put(3, new Fraction(3)); try { iterator.advance(); fail("an exception should have been thrown"); } catch (ConcurrentModificationException cme) { // expected } } /** * Regression test for a bug in findInsertionIndex where the hashing in the second probing * loop was inconsistent with the first causing duplicate keys after the right sequence * of puts and removes. */ public void testPutKeysWithCollisions() { OpenIntToFieldHashMap map = new OpenIntToFieldHashMap(field); int key1 = -1996012590; Fraction value1 = new Fraction(1); map.put(key1, value1); int key2 = 835099822; map.put(key2, value1); int key3 = 1008859686; map.put(key3, value1); assertEquals(value1, map.get(key3)); assertEquals(3, map.size()); map.remove(key2); Fraction value2 = new Fraction(2); map.put(key3, value2); assertEquals(value2, map.get(key3)); assertEquals(2, map.size()); } /** * Similar to testPutKeysWithCollisions() but exercises the codepaths in a slightly * different manner. */ public void testPutKeysWithCollision2() { OpenIntToFieldHashMapmap = new OpenIntToFieldHashMap(field); int key1 = 837989881; Fraction value1 = new Fraction(1); map.put(key1, value1); int key2 = 476463321; map.put(key2, value1); assertEquals(2, map.size()); assertEquals(value1, map.get(key2)); map.remove(key1); Fraction value2 = new Fraction(2); map.put(key2, value2); assertEquals(1, map.size()); assertEquals(value2, map.get(key2)); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/DuplicateSampleAbscissaExceptionTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/DuplicateSampleAbscissaExceptionTest.java100644 1750 1750 2674 11532241244 32516 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.util.Locale; import junit.framework.TestCase; /** * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class DuplicateSampleAbscissaExceptionTest extends TestCase { public void testConstructor(){ DuplicateSampleAbscissaException ex = new DuplicateSampleAbscissaException(1.2, 10, 11); assertNull(ex.getCause()); assertNotNull(ex.getMessage()); assertTrue(ex.getMessage().indexOf("1.2") > 0); assertEquals(1.2, ex.getDuplicateAbscissa(), 0); assertFalse(ex.getMessage().equals(ex.getMessage(Locale.FRENCH))); } } commons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java100644 1750 1750 10405 11532241243 32072 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.analysis.*; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for fast sine transformer. *

                  * FST algorithm is exact, the small tolerance number is used only * to account for round-off errors. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public final class FastSineTransformerTest extends TestCase { /** * Test of transformer for the ad hoc data. */ public void testAdHocData() { FastSineTransformer transformer = new FastSineTransformer(); double result[], tolerance = 1E-12; double x[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; double y[] = { 0.0, 20.1093579685034, -9.65685424949238, 5.98642305066196, -4.0, 2.67271455167720, -1.65685424949238, 0.795649469518633 }; result = transformer.transform(x); for (int i = 0; i < result.length; i++) { assertEquals(y[i], result[i], tolerance); } result = transformer.inversetransform(y); for (int i = 0; i < result.length; i++) { assertEquals(x[i], result[i], tolerance); } FastFourierTransformer.scaleArray(x, FastMath.sqrt(x.length / 2.0)); result = transformer.transform2(y); for (int i = 0; i < result.length; i++) { assertEquals(x[i], result[i], tolerance); } result = transformer.inversetransform2(x); for (int i = 0; i < result.length; i++) { assertEquals(y[i], result[i], tolerance); } } /** * Test of transformer for the sine function. */ public void testSinFunction() throws Exception { UnivariateRealFunction f = new SinFunction(); FastSineTransformer transformer = new FastSineTransformer(); double min, max, result[], tolerance = 1E-12; int N = 1 << 8; min = 0.0; max = 2.0 * FastMath.PI; result = transformer.transform(f, min, max, N); assertEquals(N >> 1, result[2], tolerance); for (int i = 0; i < N; i += (i == 1 ? 2 : 1)) { assertEquals(0.0, result[i], tolerance); } min = -FastMath.PI; max = FastMath.PI; result = transformer.transform(f, min, max, N); assertEquals(-(N >> 1), result[2], tolerance); for (int i = 0; i < N; i += (i == 1 ? 2 : 1)) { assertEquals(0.0, result[i], tolerance); } } /** * Test of parameters for the transformer. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); FastSineTransformer transformer = new FastSineTransformer(); try { // bad interval transformer.transform(f, 1, -1, 64); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 0); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 100); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java100644 1750 1750 10603 11532241243 32414 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.analysis.*; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for fast cosine transformer. *

                  * FCT algorithm is exact, the small tolerance number is used only * to account for round-off errors. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public final class FastCosineTransformerTest extends TestCase { /** * Test of transformer for the ad hoc data. */ public void testAdHocData() { FastCosineTransformer transformer = new FastCosineTransformer(); double result[], tolerance = 1E-12; double x[] = { 0.0, 1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0 }; double y[] = { 172.0, -105.096569476353, 27.3137084989848, -12.9593152353742, 8.0, -5.78585076868676, 4.68629150101524, -4.15826451958632, 4.0 }; result = transformer.transform(x); for (int i = 0; i < result.length; i++) { assertEquals(y[i], result[i], tolerance); } result = transformer.inversetransform(y); for (int i = 0; i < result.length; i++) { assertEquals(x[i], result[i], tolerance); } FastFourierTransformer.scaleArray(x, FastMath.sqrt(0.5 * (x.length-1))); result = transformer.transform2(y); for (int i = 0; i < result.length; i++) { assertEquals(x[i], result[i], tolerance); } result = transformer.inversetransform2(x); for (int i = 0; i < result.length; i++) { assertEquals(y[i], result[i], tolerance); } } /** * Test of transformer for the sine function. */ public void testSinFunction() throws Exception { UnivariateRealFunction f = new SinFunction(); FastCosineTransformer transformer = new FastCosineTransformer(); double min, max, result[], tolerance = 1E-12; int N = 9; double expected[] = { 0.0, 3.26197262739567, 0.0, -2.17958042710327, 0.0, -0.648846697642915, 0.0, -0.433545502649478, 0.0 }; min = 0.0; max = 2.0 * FastMath.PI * N / (N-1); result = transformer.transform(f, min, max, N); for (int i = 0; i < N; i++) { assertEquals(expected[i], result[i], tolerance); } min = -FastMath.PI; max = FastMath.PI * (N+1) / (N-1); result = transformer.transform(f, min, max, N); for (int i = 0; i < N; i++) { assertEquals(-expected[i], result[i], tolerance); } } /** * Test of parameters for the transformer. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); FastCosineTransformer transformer = new FastCosineTransformer(); try { // bad interval transformer.transform(f, 1, -1, 65); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 1); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 64); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastHadamardTransformerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastHadamardTransformerTest.jav100644 1750 1750 7762 11532241243 32530 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import junit.framework.TestCase; /** * JUnit Test for HadamardTransformerTest * @see org.apache.commons.math.transform.FastHadamardTransformer */ public final class FastHadamardTransformerTest extends TestCase { /** * Test of transformer for the a 8-point FHT (means n=8) */ public void test8Points() { checkAllTransforms(new int[] { 1, 4, -2, 3, 0, 1, 4, -1 }, new int[] { 10, -4, 2, -4, 2, -12, 6, 8 }); } /** * Test of transformer for the a 4-points FHT (means n=4) */ public void test4Points() { checkAllTransforms(new int[] { 1, 2, 3, 4 }, new int[] { 10, -2, -4, 0 }); } /** * Test the inverse transform of an integer vector is not always an integer vector */ public void testNoIntInverse() { FastHadamardTransformer transformer = new FastHadamardTransformer(); double[] x = transformer.inversetransform(new double[] { 0, 1, 0, 1}); assertEquals( 0.5, x[0], 0); assertEquals(-0.5, x[1], 0); assertEquals( 0.0, x[2], 0); assertEquals( 0.0, x[3], 0); } /** * Test of transformer for wrong number of points */ public void test3Points() { try { new FastHadamardTransformer().transform(new double[3]); fail("an exception should have been thrown"); } catch (IllegalArgumentException iae) { // expected } } private void checkAllTransforms(int[]x, int[] y) { checkDoubleTransform(x, y); checkInverseDoubleTransform(x, y); checkIntTransform(x, y); } private void checkDoubleTransform(int[]x, int[] y) { // Initiate the transformer FastHadamardTransformer transformer = new FastHadamardTransformer(); // check double transform double[] dX = new double[x.length]; for (int i = 0; i < dX.length; ++i) { dX[i] = x[i]; } double dResult[] = transformer.transform(dX); for (int i = 0; i < dResult.length; i++) { // compare computed results to precomputed results assertEquals((double) y[i], dResult[i]); } } private void checkIntTransform(int[]x, int[] y) { // Initiate the transformer FastHadamardTransformer transformer = new FastHadamardTransformer(); // check integer transform int iResult[] = transformer.transform(x); for (int i = 0; i < iResult.length; i++) { // compare computed results to precomputed results assertEquals(y[i], iResult[i]); } } private void checkInverseDoubleTransform(int[]x, int[] y) { // Initiate the transformer FastHadamardTransformer transformer = new FastHadamardTransformer(); // check double transform double[] dY = new double[y.length]; for (int i = 0; i < dY.length; ++i) { dY[i] = y[i]; } double dResult[] = transformer.inversetransform(dY); for (int i = 0; i < dResult.length; i++) { // compare computed results to precomputed results assertEquals((double) x[i], dResult[i]); } } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastFourierTransformerTest.javacommons-math-2.2-src/src/test/java/org/apache/commons/math/transform/FastFourierTransformerTest.java100644 1750 1750 16442 11532241243 32616 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.analysis.*; import org.apache.commons.math.complex.*; import org.apache.commons.math.util.FastMath; import junit.framework.TestCase; /** * Testcase for fast Fourier transformer. *

                  * FFT algorithm is exact, the small tolerance number is used only * to account for round-off errors. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public final class FastFourierTransformerTest extends TestCase { /** * Test of transformer for the ad hoc data taken from Mathematica. */ public void testAdHocData() { FastFourierTransformer transformer = new FastFourierTransformer(); Complex result[]; double tolerance = 1E-12; double x[] = {1.3, 2.4, 1.7, 4.1, 2.9, 1.7, 5.1, 2.7}; Complex y[] = { new Complex(21.9, 0.0), new Complex(-2.09497474683058, 1.91507575950825), new Complex(-2.6, 2.7), new Complex(-1.10502525316942, -4.88492424049175), new Complex(0.1, 0.0), new Complex(-1.10502525316942, 4.88492424049175), new Complex(-2.6, -2.7), new Complex(-2.09497474683058, -1.91507575950825)}; result = transformer.transform(x); for (int i = 0; i < result.length; i++) { assertEquals(y[i].getReal(), result[i].getReal(), tolerance); assertEquals(y[i].getImaginary(), result[i].getImaginary(), tolerance); } result = transformer.inversetransform(y); for (int i = 0; i < result.length; i++) { assertEquals(x[i], result[i].getReal(), tolerance); assertEquals(0.0, result[i].getImaginary(), tolerance); } double x2[] = {10.4, 21.6, 40.8, 13.6, 23.2, 32.8, 13.6, 19.2}; FastFourierTransformer.scaleArray(x2, 1.0 / FastMath.sqrt(x2.length)); Complex y2[] = y; result = transformer.transform2(y2); for (int i = 0; i < result.length; i++) { assertEquals(x2[i], result[i].getReal(), tolerance); assertEquals(0.0, result[i].getImaginary(), tolerance); } result = transformer.inversetransform2(x2); for (int i = 0; i < result.length; i++) { assertEquals(y2[i].getReal(), result[i].getReal(), tolerance); assertEquals(y2[i].getImaginary(), result[i].getImaginary(), tolerance); } } public void test2DData() { FastFourierTransformer transformer = new FastFourierTransformer(); double tolerance = 1E-12; Complex[][] input = new Complex[][] {new Complex[] {new Complex(1, 0), new Complex(2, 0)}, new Complex[] {new Complex(3, 1), new Complex(4, 2)}}; Complex[][] goodOutput = new Complex[][] {new Complex[] {new Complex(5, 1.5), new Complex(-1, -.5)}, new Complex[] {new Complex(-2, -1.5), new Complex(0, .5)}}; Complex[][] output = (Complex[][])transformer.mdfft(input, true); Complex[][] output2 = (Complex[][])transformer.mdfft(output, false); assertEquals(input.length, output.length); assertEquals(input.length, output2.length); assertEquals(input[0].length, output[0].length); assertEquals(input[0].length, output2[0].length); assertEquals(input[1].length, output[1].length); assertEquals(input[1].length, output2[1].length); for (int i = 0; i < input.length; i++) { for (int j = 0; j < input[0].length; j++) { assertEquals(input[i][j].getImaginary(), output2[i][j].getImaginary(), tolerance); assertEquals(input[i][j].getReal(), output2[i][j].getReal(), tolerance); assertEquals(goodOutput[i][j].getImaginary(), output[i][j].getImaginary(), tolerance); assertEquals(goodOutput[i][j].getReal(), output[i][j].getReal(), tolerance); } } } /** * Test of transformer for the sine function. */ public void testSinFunction() throws Exception { UnivariateRealFunction f = new SinFunction(); FastFourierTransformer transformer = new FastFourierTransformer(); Complex result[]; int N = 1 << 8; double min, max, tolerance = 1E-12; min = 0.0; max = 2.0 * FastMath.PI; result = transformer.transform(f, min, max, N); assertEquals(0.0, result[1].getReal(), tolerance); assertEquals(-(N >> 1), result[1].getImaginary(), tolerance); assertEquals(0.0, result[N-1].getReal(), tolerance); assertEquals(N >> 1, result[N-1].getImaginary(), tolerance); for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { assertEquals(0.0, result[i].getReal(), tolerance); assertEquals(0.0, result[i].getImaginary(), tolerance); } min = -FastMath.PI; max = FastMath.PI; result = transformer.inversetransform(f, min, max, N); assertEquals(0.0, result[1].getReal(), tolerance); assertEquals(-0.5, result[1].getImaginary(), tolerance); assertEquals(0.0, result[N-1].getReal(), tolerance); assertEquals(0.5, result[N-1].getImaginary(), tolerance); for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { assertEquals(0.0, result[i].getReal(), tolerance); assertEquals(0.0, result[i].getImaginary(), tolerance); } } /** * Test of parameters for the transformer. */ public void testParameters() throws Exception { UnivariateRealFunction f = new SinFunction(); FastFourierTransformer transformer = new FastFourierTransformer(); try { // bad interval transformer.transform(f, 1, -1, 64); fail("Expecting IllegalArgumentException - bad interval"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 0); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } try { // bad samples number transformer.transform(f, -1, 1, 100); fail("Expecting IllegalArgumentException - bad samples number"); } catch (IllegalArgumentException ex) { // expected } } } commons-math-2.2-src/src/site/xdoc/userguide/analysis.xml100644 1750 1750 57505 11532241247 22363 0ustarlucluc 0 0 The Commons Math User Guide - Numerical Analysis

                  The analysis package is the parent package for algorithms dealing with real-valued functions of one real variable. It contains dedicated sub-packages providing numerical root-finding, integration, and interpolation. It also contains a polynomials sub-package that considers polynomials with real coefficients as differentiable real functions.

                  Functions interfaces are intended to be implemented by user code to represent their domain problems. The algorithms provided by the library will then operate on these function to find their roots, or integrate them, or ... Functions can be multivariate or univariate, real vectorial or matrix valued, and they can be differentiable or not.

                  Possible future additions may include numerical differentiation.

                  A UnivariateRealSolver provides the means to find roots of univariate real-valued functions. A root is the value where the function takes the value 0. Commons-Math includes implementations of the following root-finding algorithms:

                  There are numerous non-obvious traps and pitfalls in root finding. First, the usual disclaimers due to the way real world computers calculate values apply. If the computation of the function provides numerical instabilities, for example due to bit cancellation, the root finding algorithms may behave badly and fail to converge or even return bogus values. There will not necessarily be an indication that the computed root is way off the true value. Secondly, the root finding problem itself may be inherently ill-conditioned. There is a "domain of indeterminacy", the interval for which the function has near zero absolute values around the true root, which may be large. Even worse, small problems like roundoff error may cause the function value to "numerically oscillate" between negative and positive values. This may again result in roots way off the true value, without indication. There is not much a generic algorithm can do if ill-conditioned problems are met. A way around this is to transform the problem in order to get a better conditioned function. Proper selection of a root-finding algorithm and its configuration parameters requires knowledge of the analytical properties of the function under analysis and numerical analysis techniques. Users are encouraged to consult a numerical analysis text (or a numerical analyst) when selecting and configuring a solver.

                  In order to use the root-finding features, first a solver object must be created. It is encouraged that all solver object creation occurs via the UnivariateRealSolverFactory class. UnivariateRealSolverFactory is a simple factory used to create all of the solver objects supported by Commons-Math. The typical usage of UnivariateRealSolverFactory to create a solver object would be:

                  UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); UnivariateRealSolver solver = factory.newDefaultSolver();

                  The solvers that can be instantiated via the UnivariateRealSolverFactory are detailed below:
                  SolverFactory MethodNotes on Use
                  BisectionnewBisectionSolver
                  Root must be bracketted.
                  Linear, guaranteed convergence
                  BrentnewBrentSolver
                  Root must be bracketted.
                  Super-linear, guaranteed convergence
                  NewtonnewNewtonSolver
                  Uses single value for initialization.
                  Super-linear, non-guaranteed convergence
                  Function must be differentiable
                  SecantnewSecantSolver
                  Root must be bracketted.
                  Super-linear, non-guaranteed convergence
                  MullernewMullerSolver
                  Root must be bracketted.
                  We restrict ourselves to real valued functions, not complex ones
                  LaguerrenewLaguerreSolver
                  Root must be bracketted.
                  Function must be a polynomial
                  RiddernewRidderSolver
                  Root must be bracketted.

                  Using a solver object, roots of functions are easily found using the solve methods. For a function f, and two domain values, min and max, solve computes a value c such that:

                  • f(c) = 0.0 (see "function value accuracy")
                  • min <= c <= max

                  Typical usage:

                  UnivariateRealFunction function = // some user defined function object UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); UnivariateRealSolver solver = factory.newBisectionSolver(); double c = solver.solve(function, 1.0, 5.0);

                  The BrentSolve uses the Brent-Dekker algorithm which is fast and robust. This algorithm is recommended for most users and the BrentSolver is the default solver provided by the UnivariateRealSolverFactory. If there are multiple roots in the interval, or there is a large domain of indeterminacy, the algorithm will converge to a random root in the interval without indication that there are problems. Interestingly, the examined text book implementations all disagree in details of the convergence criteria. Also each implementation had problems for one of the test cases, so the expressions had to be fudged further. Don't expect to get exactly the same root values as for other implementations of this algorithm.

                  The SecantSolver uses a variant of the well known secant algorithm. It may be a bit faster than the Brent solver for a class of well-behaved functions.

                  The BisectionSolver is included for completeness and for establishing a fall back in cases of emergency. The algorithm is simple, most likely bug free and guaranteed to converge even in very adverse circumstances which might cause other algorithms to malfunction. The drawback is of course that it is also guaranteed to be slow.

                  The UnivariateRealSolver interface exposes many properties to control the convergence of a solver. For the most part, these properties should not have to change from their default values to produce good results. In the circumstances where changing these property values is needed, it is easily done through getter and setter methods on UnivariateRealSolver:
                  PropertyMethodsPurpose
                  Absolute accuracy
                  getAbsoluteAccuracy
                  resetAbsoluteAccuracy
                  setAbsoluteAccuracy
                  The Absolute Accuracy is (estimated) maximal difference between the computed root and the true root of the function. This is what most people think of as "accuracy" intuitively. The default value is chosen as a sane value for most real world problems, for roots in the range from -100 to +100. For accurate computation of roots near zero, in the range form -0.0001 to +0.0001, the value may be decreased. For computing roots much larger in absolute value than 100, the default absolute accuracy may never be reached because the given relative accuracy is reached first.
                  Relative accuracy
                  getRelativeAccuracy
                  resetRelativeAccuracy
                  setRelativeAccuracy
                  The Relative Accuracy is the maximal difference between the computed root and the true root, divided by the maximum of the absolute values of the numbers. This accuracy measurement is better suited for numerical calculations with computers, due to the way floating point numbers are represented. The default value is chosen so that algorithms will get a result even for roots with large absolute values, even while it may be impossible to reach the given absolute accuracy.
                  Function value accuracy
                  getFunctionValueAccuracy
                  resetFunctionValueAccuracy
                  setFunctionValueAccuracy
                  This value is used by some algorithms in order to prevent numerical instabilities. If the function is evaluated to an absolute value smaller than the Function Value Accuracy, the algorithms assume they hit a root and return the value immediately. The default value is a "very small value". If the goal is to get a near zero function value rather than an accurate root, computation may be sped up by setting this value appropriately.
                  Maximum iteration count
                  getMaximumIterationCount
                  resetMaximumIterationCount
                  setMaximumIterationCount
                  This is the maximal number of iterations the algorithm will try. If this number is exceeded, non-convergence is assumed and a ConvergenceException exception is thrown. The default value is 100, which should be plenty, given that a bisection algorithm can't get any more accurate after 52 iterations because of the number of mantissa bits in a double precision floating point number. If a number of ill-conditioned problems is to be solved, this number can be decreased in order to avoid wasting time.

                  A UnivariateRealInterpolator is used to find a univariate real-valued function f which for a given set of ordered pairs (xi,yi) yields f(xi)=yi to the best accuracy possible. The result is provided as an object implementing the UnivariateRealFunction interface. It can therefore be evaluated at any point, including point not belonging to the original set. Currently, only an interpolator for generating natural cubic splines and a polynomial interpolator are available. There is no interpolator factory, mainly because the interpolation algorithm is more determined by the kind of the interpolated function rather than the set of points to interpolate. There aren't currently any accuracy controls either, as interpolation accuracy is in general determined by the algorithm.

                  Typical usage:

                  double x[] = { 0.0, 1.0, 2.0 }; double y[] = { 1.0, -1.0, 2.0); UnivariateRealInterpolator interpolator = new SplineInterpolator(); UnivariateRealFunction function = interpolator.interpolate(x, y); double interpolationX = 0.5; double interpolatedY = function.evaluate(x); System.out println("f(" + interpolationX + ") = " + interpolatedY);

                  A natural cubic spline is a function consisting of a polynomial of third degree for each subinterval determined by the x-coordinates of the interpolated points. A function interpolating N value pairs consists of N-1 polynomials. The function is continuous, smooth and can be differentiated twice. The second derivative is continuous but not smooth. The x values passed to the interpolator must be ordered in ascending order. It is not valid to evaluate the function for values outside the range x0..xN.

                  The polynomial function returned by the Neville's algorithm is a single polynomial guaranteed to pass exactly through the interpolation points. The degree of the polynomial is the number of points minus 1 (i.e. the interpolation polynomial for a three points set will be a quadratic polynomial). Despite the fact the interpolating polynomials is a perfect approximation of a function at interpolation points, it may be a loose approximation between the points. Due to Runge's phenomenom the error can get worse as the degree of the polynomial increases, so adding more points does not always lead to a better interpolation.

                  Loess (or Lowess) interpolation is a robust interpolation useful for smoothing univariate scaterplots. It has been described by William Cleveland in his 1979 seminal paper Robust Locally Weighted Regression and Smoothing Scatterplots. This kind of interpolation is computationally intensive but robust.

                  Microsphere interpolation is a robust multidimensional interpolation algorithm. It has been described in William Dudziak's MS thesis.

                  A BivariateRealGridInterpolator is used to find a bivariate real-valued function f which for a given set of tuples (xi,yj,fij) yields f(xi,yj)=fij to the best accuracy possible. The result is provided as an object implementing the BivariateRealFunction interface. It can therefore be evaluated at any point, including a point not belonging to the original set. The arrays xi and yj must be sorted in increasing order in order to define a two-dimensional grid.

                  In bicubic interpolation, the interpolation function is a 3rd-degree polynomial of two variables. The coefficients are computed from the function values sampled on a grid, as well as the values of the partial derivatives of the function at those grid points. From two-dimensional data sampled on a grid, the BicubicSplineInterpolator computes a bicubic interpolating function. Prior to computing an interpolating function, the SmoothingPolynomialBicubicSplineInterpolator class performs smoothing of the data by computing the polynomial that best fits each of the one-dimensional curves along each of the coordinate axes.

                  A TrivariateRealGridInterpolator is used to find a trivariate real-valued function f which for a given set of tuples (xi,yj,zk, fijk) yields f(xi,yj,zk)=fijk to the best accuracy possible. The result is provided as an object implementing the TrivariateRealFunction interface. It can therefore be evaluated at any point, including a point not belonging to the original set. The arrays xi, yj and zk must be sorted in increasing order in order to define a three-dimensional grid.

                  In tricubic interpolation, the interpolation function is a 3rd-degree polynomial of three variables. The coefficients are computed from the function values sampled on a grid, as well as the values of the partial derivatives of the function at those grid points. From three-dimensional data sampled on a grid, the TricubicSplineInterpolator computes a tricubic interpolating function.

                  A UnivariateRealIntegrator provides the means to numerically integrate univariate real-valued functions. Commons-Math includes implementations of the following integration algorithms:

                  The org.apache.commons.math.analysis.polynomials package provides real coefficients polynomials.

                  The PolynomialFunction class is the most general one, using traditional coefficients arrays. The PolynomialsUtils utility class provides static factory methods to build Chebyshev, Hermite, Lagrange and Legendre polynomials. Coefficients are computed using exact fractions so these factory methods can build polynomials up to any degree.

                  commons-math-2.2-src/src/site/xdoc/userguide/genetics.xml100644 1750 1750 15055 11532241247 22333 0ustarlucluc 0 0 The Commons Math User Guide - Genetic Algorithms

                  The genetics package provides a framework and implementations for genetic algorithms.

                  GeneticAlgorithm provides an execution framework for Genetic Algorithms (GA). Populations, consisting of Chromosomes are evolved by the GeneticAlgorithm until a StoppingCondition is reached. Evolution is determined by SelectionPolicy, MutationPolicy and Fitness.

                  The GA itself is implemented by the evolve method of the GeneticAlgorithm class, which looks like this: public Population evolve(Population initial, StoppingCondition condition) { Population current = initial; while (!condition.isSatisfied(current)) { current = nextGeneration(current); } return current; } The nextGeneration method implements the following algorithm:

                  1. Get nextGeneration population to fill from current generation, using its nextGeneration method
                  2. Loop until new generation is filled:
                    • Apply configured SelectionPolicy to select a pair of parents from current
                    • With probability = getCrossoverRate(), apply configured CrossoverPolicy to parents
                    • With probability = getMutationRate(), apply configured MutationPolicy to each of the offspring
                    • Add offspring individually to nextGeneration, space permitting
                  3. Return nextGeneration

                  Here is an example GA execution: // initialize a new genetic algorithm GeneticAlgorithm ga = new GeneticAlgorithm( new OnePointCrossover<Integer>(), 1, new RandomKeyMutation(), 0.10, new TournamentSelection(TOURNAMENT_ARITY) ); // initial population Population initial = getInitialPopulation(); // stopping condition StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS); // run the algorithm Population finalPopulation = ga.evolve(initial, stopCond); // best chromosome from the final population Chromosome bestFinal = finalPopulation.getFittestChromosome(); The arguments to the GeneticAlgorithm constructor above are:
                  Parametervalue in examplemeaning
                  crossoverPolicy OnePointCrossover A random crossover point is selected and the first part from each parent is copied to the corresponding child, and the second parts are copied crosswise.
                  crossoverRate 1 Always apply crossover
                  mutationPolicy RandomKeyMutation Changes a randomly chosen element of the array representation to a random value uniformly distributed in [0,1].
                  mutationRate .1 Apply mutation with probability 0.1 - that is, 10% of the time.
                  selectionPolicy TournamentSelection Each of the two selected chromosomes is selected based on an n-ary tournament -- this is done by drawing n random chromosomes without replacement from the population, and then selecting the fittest chromosome among them.

                  The algorithm starts with an initial population of Chromosomes. and executes until the specified StoppingCondition is reached. In the example above, a FixedGenerationCount stopping condition is used, which means the algorithm proceeds through a fixed number of generations.

                  commons-math-2.2-src/src/site/xdoc/userguide/index.xml100644 1750 1750 23227 11532241247 21641 0ustarlucluc 0 0 The Commons Math User Guide - Table of Contents
                  commons-math-2.2-src/src/site/xdoc/userguide/random.xml100644 1750 1750 70320 11532241247 22006 0ustarlucluc 0 0 The Commons Math User Guide - Data Generation

                  The Commons Math random package includes utilities for

                  • generating random numbers
                  • generating random vectors
                  • generating random strings
                  • generating cryptographically secure sequences of random numbers or strings
                  • generating random samples and permutations
                  • analyzing distributions of values in an input file and generating values "like" the values in the file
                  • generating data for grouped frequency distributions or histograms

                  The source of random data used by the data generation utilities is pluggable. By default, the JDK-supplied PseudoRandom Number Generator (PRNG) is used, but alternative generators can be "plugged in" using an adaptor framework, which provides a generic facility for replacing java.util.Random with an alternative PRNG. Other very good PRNG suitable for Monte-Carlo analysis (but not for cryptography) provided by the library are the Mersenne twister from Makoto Matsumoto and Takuji Nishimura and the more recent WELL generators (Well Equidistributed Long-period Linear) from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.

                  Sections 2.2-2.6 below show how to use the commons math API to generate different kinds of random data. The examples all use the default JDK-supplied PRNG. PRNG pluggability is covered in 2.7. The only modification required to the examples to use alternative PRNGs is to replace the argumentless constructor calls with invocations including a RandomGenerator instance as a parameter.

                  The RandomData interface defines methods for generating random sequences of numbers. The API contracts of these methods use the following concepts:

                  Random sequence of numbers from a probability distribution
                  There is no such thing as a single "random number." What can be generated are sequences of numbers that appear to be random. When using the built-in JDK function Math.random(), sequences of values generated follow the Uniform Distribution, which means that the values are evenly spread over the interval between 0 and 1, with no sub-interval having a greater probability of containing generated values than any other interval of the same length. The mathematical concept of a probability distribution basically amounts to asserting that different ranges in the set of possible values of a random variable have different probabilities of containing the value. Commons Math supports generating random sequences from each of the distributions in the distributions package. The javadoc for the nextXxx methods in RandomDataImpl describes the algorithms used to generate random deviates.
                  Cryptographically secure random sequences
                  It is possible for a sequence of numbers to appear random, but nonetheless to be predictable based on the algorithm used to generate the sequence. If in addition to randomness, strong unpredictability is required, it is best to use a secure random number generator to generate values (or strings). The nextSecureXxx methods in the RandomDataImpl implementation of the RandomData interface use the JDK SecureRandom PRNG to generate cryptographically secure sequences. The setSecureAlgorithm method allows you to change the underlying PRNG. These methods are much slower than the corresponding "non-secure" versions, so they should only be used when cryptographic security is required.
                  Seeding pseudo-random number generators
                  By default, the implementation provided in RandomDataImpl uses the JDK-provided PRNG. Like most other PRNGs, the JDK generator generates sequences of random numbers based on an initial "seed value". For the non-secure methods, starting with the same seed always produces the same sequence of values. Secure sequences started with the same seeds will diverge. When a new RandomDataImpl is created, the underlying random number generators are not initialized. The first call to a data generation method, or to a reSeed() method initializes the appropriate generator. If you do not explicitly seed the generator, it is by default seeded with the current time in milliseconds. Therefore, to generate sequences of random data values, you should always instantiate one RandomDataImpl and use it repeatedly instead of creating new instances for subsequent values in the sequence. For example, the following will generate a random sequence of 50 long integers between 1 and 1,000,000, using the current time in milliseconds as the seed for the JDK PRNG: RandomData randomData = new RandomDataImpl(); for (int i = 0; i < 1000; i++) { value = randomData.nextLong(1, 1000000); } The following will not in general produce a good random sequence, since the PRNG is reseeded each time through the loop with the current time in milliseconds: for (int i = 0; i < 1000; i++) { RandomDataImpl randomData = new RandomDataImpl(); value = randomData.nextLong(1, 1000000); } The following will produce the same random sequence each time it is executed: RandomData randomData = new RandomDataImpl(); randomData.reSeed(1000); for (int i = 0; i = 1000; i++) { value = randomData.nextLong(1, 1000000); } The following will produce a different random sequence each time it is executed. RandomData randomData = new RandomDataImpl(); randomData.reSeedSecure(1000); for (int i = 0; i < 1000; i++) { value = randomData.nextSecureLong(1, 1000000); }

                  Some algorithms require random vectors instead of random scalars. When the components of these vectors are uncorrelated, they may be generated simply one at a time and packed together in the vector. The UncorrelatedRandomVectorGenerator class simplifies this process by setting the mean and deviation of each component once and generating complete vectors. When the components are correlated however, generating them is much more difficult. The CorrelatedRandomVectorGenerator class provides this service. In this case, the user must set up a complete covariance matrix instead of a simple standard deviations vector. This matrix gathers both the variance and the correlation information of the probability law.

                  The main use for correlated random vector generation is for Monte-Carlo simulation of physical problems with several variables, for example to generate error vectors to be added to a nominal vector. A particularly common case is when the generated vector should be drawn from a Multivariate Normal Distribution.

                  Generating random vectors from a bivariate normal distribution
                  // Create and seed a RandomGenerator (could use any of the generators in the random package here) RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(17399225432l); // Fixed seed means same results every time // Create a GassianRandomGenerator using rg as its source of randomness GaussianRandomGenerator rawGenerator = new GaussianRandomGenerator(rg); // Create a CorrelatedRandomVectorGenerator using rawGenerator for the components CorrelatedRandomVectorGenerator generator = new CorrelatedRandomVectorGenerator(mean, covariance, 1.0e-12 * covariance.getNorm(), rawGenerator); // Use the generator to generate correlated vectors double[] randomVector = generator.nextVector(); ... The mean argument is a double[] array holding the means of the random vector components. In the bivariate case, it must have length 2. The covariance argument is a RealMatrix, which needs to be 2 x 2. The main diagonal elements are the variances of the vector components and the off-diagonal elements are the covariances. For example, if the means are 1 and 2 respectively, and the desired standard deviations are 3 and 4, respectively, then we need to use double[] mean = {1, 2}; double[][] cov = {{9, c}, {c, 16}}; RealMatrix covariance = MatrixUtils.createRealMatrix(cov); where c is the desired covariance. If you are starting with a desired correlation, you need to translate this to a covariance by multiplying it by the product of the standard deviations. For example, if you want to generate data that will give Pearson's R of 0.5, you would use c = 3 * 4 * .5 = 6.

                  In addition to multivariate normal distributions, correlated vectors from multivariate uniform distributions can be generated by creating a UniformRandomGenerator in place of the GaussianRandomGenerator above. More generally, any NormalizedRandomGenerator may be used.

                  The methods nextHexString and nextSecureHexString can be used to generate random strings of hexadecimal characters. Both of these methods produce sequences of strings with good dispersion properties. The difference between the two methods is that the second is cryptographically secure. Specifically, the implementation of nextHexString(n) in RandomDataImpl uses the following simple algorithm to generate a string of n hex digits:

                  1. n/2+1 binary bytes are generated using the underlying Random
                  2. Each binary byte is translated into 2 hex digits
                  The RandomDataImpl implementation of the "secure" version, nextSecureHexString generates hex characters in 40-byte "chunks" using a 3-step process:
                  1. 20 random bytes are generated using the underlying SecureRandom.
                  2. SHA-1 hash is applied to yield a 20-byte binary digest.
                  3. Each byte of the binary digest is converted to 2 hex digits
                  Similarly to the secure random number generation methods, nextSecureHexString is much slower than the non-secure version. It should be used only for applications such as generating unique session or transaction ids where predictability of subsequent ids based on observation of previous values is a security concern. If all that is needed is an even distribution of hex characters in the generated strings, the non-secure method should be used.

                  To select a random sample of objects in a collection, you can use the nextSample method in the RandomData interface. Specifically, if c is a collection containing at least k objects, and randomData is a RandomData instance randomData.nextSample(c, k) will return an object[] array of length k consisting of elements randomly selected from the collection. If c contains duplicate references, there may be duplicate references in the returned array; otherwise returned elements will be unique -- i.e., the sampling is without replacement among the object references in the collection.

                  If randomData is a RandomData instance, and n and k are integers with k <= n, then randomData.nextPermutation(n, k) returns an int[] array of length k whose whose entries are selected randomly, without repetition, from the integers 0 through n-1 (inclusive), i.e., randomData.nextPermutation(n, k) returns a random permutation of n taken k at a time.

                  Using the ValueServer class, you can generate data based on the values in an input file in one of two ways:

                  Replay Mode
                  The following code will read data from url (a java.net.URL instance), cycling through the values in the file in sequence, reopening and starting at the beginning again when all values have been read. ValueServer vs = new ValueServer(); vs.setValuesFileURL(url); vs.setMode(ValueServer.REPLAY_MODE); vs.resetReplayFile(); double value = vs.getNext(); // ...Generate and use more values... vs.closeReplayFile(); The values in the file are not stored in memory, so it does not matter how large the file is, but you do need to explicitly close the file as above. The expected file format is \n -delimited (i.e. one per line) strings representing valid floating point numbers.
                  Digest Mode
                  When used in Digest Mode, the ValueServer reads the entire input file and estimates a probability density function based on data from the file. The estimation method is essentially the Variable Kernel Method with Gaussian smoothing. Once the density has been estimated, getNext() returns random values whose probability distribution matches the empirical distribution -- i.e., if you generate a large number of such values, their distribution should "look like" the distribution of the values in the input file. The values are not stored in memory in this case either, so there is no limit to the size of the input file. Here is an example: ValueServer vs = new ValueServer(); vs.setValuesFileURL(url); vs.setMode(ValueServer.DIGEST_MODE); vs.computeDistribution(500); //Read file and estimate distribution using 500 bins double value = vs.getNext(); // ...Generate and use more values... See the javadoc for ValueServer and EmpiricalDistribution for more details. Note that computeDistribution() opens and closes the input file by itself.

                  To enable alternative PRNGs to be "plugged in" to the commons-math data generation utilities and to provide a generic means to replace java.util.Random in applications, a random generator adaptor framework has been added to commons-math. The RandomGenerator interface abstracts the public interface of java.util.Random and any implementation of this interface can be used as the source of random data for the commons-math data generation classes. An abstract base class, AbstractRandomGenerator is provided to make implementation easier. This class provides default implementations of "derived" data generation methods based on the primitive, nextDouble(). To support generic replacement of java.util.Random, the RandomAdaptor class is provided, which extends java.util.Random and wraps and delegates calls to a RandomGenerator instance.

                  Commons-math provides by itself several implementations of the RandomGenerator interface:

                  The JDK provided generator is a simple one that can be used only for very simple needs. The Mersenne Twister is a fast generator with very good properties well suited for Monte-Carlo simulation. It is equidistributed for generating vectors up to dimension 623 and has a huge period: 219937 - 1 (which is a Mersenne prime). This generator is described in a paper by Makoto Matsumoto and Takuji Nishimura in 1998: Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30. The WELL generators are a family of generators with period ranging from 2512 - 1 to 244497 - 1 (this last one is also a Mersenne prime) with even better properties than Mersenne Twister. These generators are described in a paper by François Panneton, Pierre L'Ecuyer and Makoto Matsumoto Improved Long-Period Generators Based on Linear Recurrences Modulo 2 ACM Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper are in wellrng-errata.txt.

                  For simple sampling, any of these generators is sufficient. For Monte-Carlo simulations the JDK generator does not have any of the good mathematical properties of the other generators, so it should be avoided. The Mersenne twister and WELL generators have equidistribution properties proven according to their bits pool size which is directly linked to their period (all of them have maximal period, i.e. a generator with size n pool has a period 2n-1). They also have equidistribution properties for 32 bits blocks up to s/32 dimension where s is their pool size. So WELL19937c for exemple is equidistributed up to dimension 623 (19937/32). This means a Monte-Carlo simulation generating a vector of n variables at each iteration has some guarantees on the properties of the vector as long as its dimension does not exceed the limit. However, since we use bits from two successive 32 bits generated integers to create one double, this limit is smaller when the variables are of type double. so for Monte-Carlo simulation where less the 16 doubles are generated at each round, WELL1024 may be sufficient. If a larger number of doubles are needed a generator with a larger pool would be useful.

                  The WELL generators are more modern then MersenneTwister (the paper describing than has been published in 2006 instead of 1998) and fix some of its (few) drawbacks. If initialization array contains many zero bits, MersenneTwister may take a very long time (several hundreds of thousands of iterations to reach a steady state with a balanced number of zero and one in its bits pool). So the WELL generators are better to escape zeroland as explained by the WELL generators creators. The Well19937a and Well44497a generator are not maximally equidistributed (i.e. there are some dimensions or bits blocks size for which they are not equidistributed). The Well512a, Well1024a, Well19937c and Well44497b are maximally equidistributed for blocks size up to 32 bits (they should behave correctly also for double based on more than 32 bits blocks, but equidistribution is not proven at these blocks sizes).

                  The MersenneTwister generator uses a 624 elements integer array, so it consumes less than 2.5 kilobytes. The WELL generators use 6 integer arrays with a size equal to the pool size, so for example the WELL44497b generator uses about 33 kilobytes. This may be important if a very large number of generator instances were used at the same time.

                  All generators are quite fast. As an example, here are some comparisons, obtained on a 64 bits JVM on a linux computer with a 2008 processor (AMD phenom Quad 9550 at 2.2 GHz). The generation rate for MersenneTwister was between 25 and 27 millions doubles per second (remember we generate two 32 bits integers for each double). Generation rates for other PRNG, relative to MersenneTwister:

                  Example of performances
                  Namegeneration rate (relative to MersenneTwister)
                  MersenneTwister1
                  JDKRandomGeneratorbetween 0.96 and 1.16
                  Well512abetween 0.85 and 0.88
                  Well1024abetween 0.63 and 0.73
                  Well19937abetween 0.70 and 0.71
                  Well19937cbetween 0.57 and 0.71
                  Well44497abetween 0.69 and 0.71
                  Well44497bbetween 0.65 and 0.71

                  So for most simulation problems, the better generators like Well19937c and Well44497b are probably very good choices.

                  Note that none of these generators are suitable for cryptography. They are devoted to simulation, and to generate very long series with strong properties on the series as a whole (equidistribution, no correlation ...). They do not attempt to create small series but with very strong properties of unpredictability as needed in cryptography.

                  Examples:

                  Create a RandomGenerator based on RngPack's Mersenne Twister
                  To create a RandomGenerator using the RngPack Mersenne Twister PRNG as the source of randomness, extend AbstractRandomGenerator overriding the derived methods that the RngPack implementation provides: import edu.cornell.lassp.houle.RngPack.RanMT; /** * AbstractRandomGenerator based on RngPack RanMT generator. */ public class RngPackGenerator extends AbstractRandomGenerator { private RanMT random = new RanMT(); public void setSeed(long seed) { random = new RanMT(seed); } public double nextDouble() { return random.raw(); } public double nextGaussian() { return random.gaussian(); } public int nextInt(int n) { return random.choose(n); } public boolean nextBoolean() { return random.coin(); } }
                  Use the Mersenne Twister RandomGenerator in place of java.util.Random in RandomData
                  RandomData randomData = new RandomDataImpl(new RngPackGenerator());
                  Create an adaptor instance based on the Mersenne Twister generator that can be used in place of a Random
                  RandomGenerator generator = new RngPackGenerator(); Random random = RandomAdaptor.createAdaptor(generator); // random can now be used in place of a Random instance, data generation // calls will be delegated to the wrapped Mersenne Twister

                  commons-math-2.2-src/src/site/xdoc/userguide/geometry.xml100644 1750 1750 16672 11532241247 22373 0ustarlucluc 0 0 The Commons Math User Guide - Geometry

                  The geometry package provides classes useful for many physical simulations in the real 3D space, namely vectors and rotations.

                  Vector3D provides a simple vector type. One important feature is that instances of this class are guaranteed to be immutable, this greatly simplifies modelling dynamical systems with changing states: once a vector has been computed, a reference to it is known to preserve its state as long as the reference itself is preserved.

                  Numerous constructors are available to create vectors. In addition to the straightforward cartesian coordinates constructor, a constructor using azimuthal coordinates can build normalized vectors and linear constructors from one, two, three or four base vectors are also available. Constants have been defined for the most commons vectors (plus and minus canonical axes, null vector, and special vectors with infinite or NaN coordinates).

                  The generic vectorial space operations are available including dot product, normalization, orthogonal vector finding and angular separation computation which have a specific meaning in 3D. The 3D geometry specific cross product is of course also implemented.

                  Vector3DFormat is a specialized format for formatting output or parsing input with text representation of 3D vectors.

                  Rotation represents 3D rotations. Rotation instances are also immutable objects, as Vector3D instances.

                  Rotations can be represented by several different mathematical entities (matrices, axe and angle, Cardan or Euler angles, quaternions). This class presents a higher level abstraction, more user-oriented and hiding implementation details. Well, for the curious, we use quaternions for the internal representation. The user can build a rotation from any of these representations, and any of these representations can be retrieved from a Rotation instance (see the various constructors and getters). In addition, a rotation can also be built implicitely from a set of vectors and their image.

                  This implies that this class can be used to convert from one representation to another one. For example, converting a rotation matrix into a set of Cardan angles can be done using the following single line of code:

                  double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ);

                  Focus is oriented on what a rotation does rather than on its underlying representation. Once it has been built, and regardless of its internal representation, a rotation is an operator which basically transforms three dimensional vectors into other three dimensional vectors. Depending on the application, the meaning of these vectors may vary as well as the semantics of the rotation.

                  For example in a spacecraft attitude simulation tool, users will often consider the vectors are fixed (say the Earth direction for example) and the rotation transforms the coordinates coordinates of this vector in inertial frame into the coordinates of the same vector in satellite frame. In this case, the rotation implicitly defines the relation between the two frames (we have fixed vectors and moving frame). Another example could be a telescope control application, where the rotation would transform the sighting direction at rest into the desired observing direction when the telescope is pointed towards an object of interest. In this case the rotation transforms the direction at rest in a topocentric frame into the sighting direction in the same topocentric frame (we have moving vectors in fixed frame). In many case, both approaches will be combined, in our telescope example, we will probably also need to transform the observing direction in the topocentric frame into the observing direction in inertial frame taking into account the observatory location and the Earth rotation.

                  These examples show that a rotation means what the user wants it to mean, so this class does not push the user towards one specific definition and hence does not provide methods like projectVectorIntoDestinationFrame or computeTransformedDirection. It provides simpler and more generic methods: applyTo(Vector3D) and applyInverseTo(Vector3D).

                  Since a rotation is basically a vectorial operator, several rotations can be composed together and the composite operation r = r1 o r2 (which means that for each vector u, r(u) = r1(r2(u))) is also a rotation. Hence we can consider that in addition to vectors, a rotation can be applied to other rotations as well (or to itself). With our previous notations, we would say we can apply r1 to r2 and the result we get is r = r1 o r2. For this purpose, the class provides the methods: applyTo(Rotation) and applyInverseTo(Rotation).

                  commons-math-2.2-src/src/site/xdoc/userguide/fraction.xml100644 1750 1750 12316 11532241247 22334 0ustarlucluc 0 0 The Commons Math User Guide - Fractions

                  The fraction packages provides a fraction number type as well as fraction number formatting.

                  Fraction and BigFraction provide fraction number type that forms the basis for the fraction functionality found in Commons-Math. The former one can be used for fractions whose numerators and denominators are small enough to fit in an int (taking care of intermediate values) while the second class should be used when there is a risk the numerator and denominator grow very large.

                  A fraction number, can be built from two integer arguments representing numerator and denominator or from a double which will be approximated: Fraction f = new Fraction(1, 3); // 1 / 3 Fraction g = new Fraction(0.25); // 1 / 4

                  Of special note with fraction construction, when a fraction is created it is always reduced to lowest terms.

                  The Fraction class provides many unary and binary fraction operations. These operations provide the means to add, subtract, multiple and, divide fractions along with other functions similar to the real number functions found in java.math.BigDecimal: Fraction lhs = new Fraction(1, 3); Fraction rhs = new Fraction(2, 5); Fraction answer = lhs.add(rhs); // add two fractions answer = lhs.subtract(rhs); // subtract two fractions answer = lhs.abs(); // absolute value answer = lhs.reciprocal(); // reciprocal of lhs

                  Like fraction construction, for each of the fraction functions, the resulting fraction is reduced to lowest terms.

                  Fraction instances can be converted to and from strings using the FractionFormat class. FractionFormat is a java.text.Format extension and, as such, is used like other formatting objects (e.g. java.text.SimpleDateFormat): FractionFormat format = new FractionFormat(); // default format Fraction f = new Fraction(2, 4); String s = format.format(f); // s contains "1 / 2", note the reduced fraction

                  To customize the formatting output, one or two java.text.NumberFormat instances can be used to construct a FractionFormat. These number formats control the formatting of the numerator and denominator of the fraction: NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); // create fraction format with custom number format // when one number format is used, both numerator and // denominator are formatted the same FractionFormat format = new FractionFormat(nf); Fraction f = new Fraction(2000, 3333); String s = format.format(c); // s contains "2.000 / 3.333" NumberFormat nf2 = NumberFormat.getInstance(Locale.US); // create fraction format with custom number formats format = new FractionFormat(nf, nf2); s = format.format(f); // s contains "2.000 / 3,333"

                  Formatting's inverse operation, parsing, can also be performed by FractionFormat. To parse a fraction from a string, simply call the parse method: FractionFormat ff = new FractionFormat(); Fraction f = ff.parse("-10 / 21");

                  commons-math-2.2-src/src/site/xdoc/userguide/ode.xml100644 1750 1750 56526 11532241247 21311 0ustarlucluc 0 0 The Commons Math User Guide - Ordinary Differential Equations Integration

                  The ode package provides classes to solve Ordinary Differential Equations problems.

                  This package solves Initial Value Problems of the form y'=f(t,y) with t0 and y(t0)=y0 known. The provided integrators compute an estimate of y(t) from t=t0 to t=t1.

                  All integrators provide dense output. This means that besides computing the state vector at discrete times, they also provide a cheap mean to get both the state and its derivative between the time steps. They do so through classes extending the StepInterpolator abstract class, which are made available to the user at the end of each step.

                  All integrators handle multiple discrete events detection based on switching functions. This means that the integrator can be driven by user specified discrete events (occurring when the sign of user-supplied switching function changes). The steps are shortened as needed to ensure the events occur at step boundaries (even if the integrator is a fixed-step integrator). When the events are triggered, integration can be stopped (this is called a G-stop facility), the state vector can be changed, or integration can simply go on. The latter case is useful to handle discontinuities in the differential equations gracefully and get accurate dense output even close to the discontinuity.

                  All integrators support setting a maximal number of evaluations of differential equations function. If this number is exceeded, an exception will be thrown during integration. This can be used to prevent infinite loops if for example error control or discrete events create a really large number of extremely small steps. By default, the maximal number of evaluation is set to Integer.MAX_VALUE (i.e. 231-1 or 2147483647). It is recommended to set this maximal number to a value suited to the ODE problem, integration range, and step size or error control settings.

                  The user should describe his problem in his own classes which should implement the FirstOrderDifferentialEquations interface. Then he should pass it to the integrator he prefers among all the classes that implement the FirstOrderIntegrator interface. The following example shows how to implement the simple two-dimensional problem:

                  • y'0(t) = ω × (c1 - y1(t))
                  • y'1(t) = ω × (y0(t) - c0)
                  with some initial state y(t0) = (y0(t0), y1(t0)). In fact, the exact solution of this problem is that y(t) moves along a circle centered at c = (c0, c1) with constant angular rate ω.

                  private static class CircleODE implements FirstOrderDifferentialEquations { private double[] c; private double omega; public CircleODE(double[] c, double omega) { this.c = c; this.omega = omega; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (c[1] - y[1]); yDot[1] = omega * (y[0] - c[0]); } }

                  Computing the state y(16.0) starting from y(0.0) = (0.0, 1.0) and integrating the ODE is done as follows (using Dormand-Prince 8(5,3) integrator as an example):

                  FirstOrderIntegrator dp853 = new DormandPrince853Integrator(1.0e-8, 100.0, 1.0e-10, 1.0e-10); FirstOrderDifferentialEquations ode = new CircleODE(new double[] { 1.0, 1.0 }, 0.1); double[] y = new double[] { 0.0, 1.0 }; // initial state dp853.integrate(ode, 0.0, y, 16.0, y); // now y contains final state at time t=16.0

                  The solution of the integration problem is provided by two means. The first one is aimed towards simple use: the state vector at the end of the integration process is copied in the y array of the FirstOrderIntegrator.integrate method, as shown by previous example. The second one should be used when more in-depth information is needed throughout the integration process. The user can register an object implementing the StepHandler interface or a StepNormalizer object wrapping a user-specified object implementing the FixedStepHandler interface into the integrator before calling the FirstOrderIntegrator.integrate method. The user object will be called appropriately during the integration process, allowing the user to process intermediate results. The default step handler does nothing. Considering again the previous example, we want to print the trajectory of the point to check it really is a circle arc. We simply add the following before the call to integrator.integrate:

                  StepHandler stepHandler = new StepHandler() { public void reset() {} public boolean requiresDenseOutput() { return false; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MathUserException { double t = interpolator.getCurrentTime(); double[] y = interpolator.getInterpolatedState(); System.out.println(t + " " + y[0] + " " + y[1]); } }; integrator.addStepHandler(stepHandler);

                  ContinuousOutputModel is a special-purpose step handler that is able to store all steps and to provide transparent access to any intermediate result once the integration is over. An important feature of this class is that it implements the Serializable interface. This means that a complete continuous model of the integrated function throughout the integration range can be serialized and reused later (if stored into a persistent medium like a file system or a database) or elsewhere (if sent to another application). Only the result of the integration is stored, there is no reference to the integrated problem by itself.

                  Other default implementations of the StepHandler interface are available for general needs (DummyStepHandler, StepNormalizer) and custom implementations can be developed for specific needs. As an example, if an application is to be completely driven by the integration process, then most of the application code will be run inside a step handler specific to this application.

                  Some integrators (the simple ones) use fixed steps that are set at creation time. The more efficient integrators use variable steps that are handled internally in order to control the integration error with respect to a specified accuracy (these integrators extend the AdaptiveStepsizeIntegrator abstract class). In this case, the step handler which is called after each successful step shows up the variable stepsize. The StepNormalizer class can be used to convert the variable stepsize into a fixed stepsize that can be handled by classes implementing the FixedStepHandler interface. Adaptive stepsize integrators can automatically compute the initial stepsize by themselves, however the user can specify it if he prefers to retain full control over the integration or if the automatic guess is wrong.

                  ODE problems are continuous ones. However, sometimes discrete events must be taken into account. The most frequent case is the stop condition of the integrator is not defined by the time t but by a target condition on state y (say y[0] = 1.0 for example).

                  Discrete events detection is based on switching functions. The user provides a simple g(t, y) function depending on the current time and state. The integrator will monitor the value of the function throughout integration range and will trigger the event when its sign changes. The magnitude of the value is almost irrelevant, it should however be continuous (but not necessarily smooth) for the sake of root finding. The steps are shortened as needed to ensure the events occur at step boundaries (even if the integrator is a fixed-step integrator). Note that g function signs changes at the very beginning of the integration (from t0 to t0 + ε where ε is the events detection convergence threshold) are explicitely ignored. This prevents having the integration stuck at its initial point when a new integration is restarted just at the same point a previous one had been stopped by an event.

                  When an event is triggered, the event time, current state and an indicator whether the switching function was increasing or decreasing at event time are provided to the user. Several different options are available to him:

                  • integration can be stopped (this is called a G-stop facility),
                  • the state vector or the derivatives can be changed,
                  • or integration can simply go on.

                  The first case, G-stop, is the most common one. A typical use case is when an ODE must be solved up to some target state is reached, with a known value of the state but an unknown occurrence time. As an example, if we want to monitor a chemical reaction up to some predefined concentration for the first substance, we can use the following switching function setting:

                  public double g(double t, double[] y) { return y[0] - targetConcentration; } public int eventOccurred(double t, double[] y, boolean increasing) { return STOP; }

                  The second case, change state vector or derivatives is encountered when dealing with discontinuous dynamical models. A typical case would be the motion of a spacecraft when thrusters are fired for orbital maneuvers. The acceleration is smooth as long as no maneuvers are performed, depending only on gravity, drag, third body attraction, radiation pressure. Firing a thruster introduces a discontinuity that must be handled appropriately by the integrator. In such a case, we would use a switching function setting similar to this:

                  public double g(double t, double[] y) { return (t - tManeuverStart) * (t - tManeuverStop); } public int eventOccurred(double t, double[] y, boolean increasing) { return RESET_DERIVATIVES; }

                  The third case is useful mainly for monitoring purposes, a simple example is:

                  public double g(double t, double[] y) { return y[0] - y[1]; } public int eventOccurred(double t, double[] y, boolean increasing) { logger.log("y0(t) and y1(t) curves cross at t = " + t); return CONTINUE; }

                  The tables below show the various integrators available for non-stiff problems. Note that the implementations of Adams-Bashforth and Adams-Moulton are adaptive stepsize, not fixed stepsize as is usual for these multi-step integrators. This is due to the fact the implementation relies on the Nordsieck vector representation of the state.

                  Fixed Step Integrators
                  NameOrder
                  Euler1
                  Midpoint2
                  Classical Runge-Kutta4
                  Gill4
                  3/84

                  Adaptive Stepsize Integrators
                  NameIntegration OrderError Estimation Order
                  Higham and Hall54
                  Dormand-Prince 5(4)54
                  Dormand-Prince 8(5,3)85 and 3
                  Gragg-Bulirsch-Stoervariable (up to 18 by default)variable
                  Adams-Bashforthvariablevariable
                  Adams-Moultonvariablevariable

                  If in addition to state y(t) the user needs to compute the sensitivity of the state to the initial state or some parameter of the ODE, he will use the classes and interfaces from the org.apache.commons.ode.jacobians package instead of the top level ode package. These classes compute the jacobians dy(t)/dy0 and dy(t)/dp where y0 is the initial state and p is some ODE parameter.

                  The classes and interfaces in this package mimic the behavior of the classes and interfaces of the top level ode package, only adding parameters arrays for the jacobians. The behavior of these classes is to create a compound state vector z containing both the state y(t) and its derivatives dy(t)/dy0 and dy(t)/dp and to set up an extended problem by adding the equations for the jacobians automatically. These extended state and problems are then provided to a classical underlying integrator chosen by user.

                  This behavior imply there will be a top level integrator knowing about state and jacobians and a low level integrator knowing only about compound state (which may be big). If the user wants to deal with the top level only, he will use the specialized step handler and event handler classes registered at top level. He can also register classical step handlers and event handlers, but in this case will see the big compound state. This state is guaranteed to contain the original state in the first elements, followed by the jacobian with respect to initial state (in row order), followed by the jacobian with respect to parameters (in row order). If for example the original state dimension is 6 and there are 3 parameters, the compound state will be a 60 elements array. The first 6 elements will be the original state, the next 36 elements will be the jacobian with respect to initial state, and the remaining 18 will be the jacobian with respect to parameters. Dealing with low level step handlers and event handlers is cumbersome if one really needs the jacobians in these methods, but it also prevents many data being copied back and forth between state and jacobians on one side and compound state on the other side.

                  In order to compute dy(t)/dy0 and dy(t/dp for any t, the algorithm needs not only the ODE function f such that y'=f(t,y) but also its local jacobians df(t, y, p)/dy and df(t, y, p)/dp.

                  If the function f is too complex, the user can simply rely on internal differentiation using finite differences to compute these local jacobians. So rather than the FirstOrderDifferentialEquations interface he will implement the ParameterizedODE interface. Considering again our example where only ω is considered a parameter, we get:

                  public class BasicCircleODE implements ParameterizedODE { private double[] c; private double omega; public BasicCircleODE(double[] c, double omega) { this.c = c; this.omega = omega; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (c[1] - y[1]); yDot[1] = omega * (y[0] - c[0]); } public int getParametersDimension() { // we are only interested in the omega parameter return 1; } public void setParameter(int i, double value) { omega = value; } }

                  This ODE is provided to the specialized integrator with two arrays specifying the step sizes to use for finite differences (one array for derivation with respect to state y, one array for derivation with respect to parameters p):

                  double[] hY = new double[] { 0.001, 0.001 }; double[] hP = new double[] { 1.0e-6 }; FirstOrderIntegratorWithJacobians integrator = new FirstOrderIntegratorWithJacobians(dp853, ode, hY, hP); integrator.integrate(t0, y0, dy0dp, t, y, dydy0, dydp);

                  If the function f is simple, the user can simply provide the local jacobians by himself. So rather than the FirstOrderDifferentialEquations interface he will implement the ODEWithJacobians interface. Considering again our example where only ω is considered a parameter, we get:

                  public class EnhancedCircleODE implements ODEWithJacobians { private double[] c; private double omega; public EnhancedCircleODE(double[] c, double omega) { this.c = c; this.omega = omega; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (c[1] - y[1]); yDot[1] = omega * (y[0] - c[0]); } public int getParametersDimension() { // we are only interested in the omega parameter return 1; } public void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) { dFdY[0][0] = 0; dFdY[0][1] = -omega; dFdY[1][0] = omega; dFdY[1][1] = 0; dFdP[0][0] = 0; dFdP[0][1] = omega; dFdP[0][2] = c[1] - y[1]; dFdP[1][0] = -omega; dFdP[1][1] = 0; dFdP[1][2] = y[0] - c[0]; } }

                  This ODE is provided to the specialized integrator as is:

                  FirstOrderIntegratorWithJacobians integrator = new FirstOrderIntegratorWithJacobians(dp853, ode); integrator.integrate(t0, y0, dy0dp, t, y, dydy0, dydp);
                  commons-math-2.2-src/src/site/xdoc/userguide/utilities.xml100644 1750 1750 17666 11532241247 22557 0ustarlucluc 0 0 The Commons Math User Guide - Utilites

                  The org.apache.commons.math.util package collects a group of array utilities, value transformers, and numerical routines used by implementation classes in commons-math.

                  To maintain statistics based on a "rolling" window of values, a resizable array implementation was developed and is provided for reuse in the util package. The core functionality provided is described in the documentation for the interface, DoubleArray. This interface adds one method, addElementRolling(double) to basic list accessors. The addElementRolling method adds an element (the actual parameter) to the end of the list and removes the first element in the list.

                  The ResizableDoubleArray class provides a configurable, array-backed implementation of the DoubleArray interface. When addElementRolling is invoked, the underlying array is expanded if necessary, the new element is added to the end of the array and the "usable window" of the array is moved forward, so that the first element is effectively discarded, what was the second becomes the first, and so on. To efficiently manage storage, two maintenance operations need to be periodically performed -- orphaned elements at the beginning of the array need to be reclaimed and space for new elements at the end needs to be created. Both of these operations are handled automatically, with frequency / effect driven by the configuration properties expansionMode, expansionFactor and contractionCriteria. See ResizableDoubleArray for details.

                  The OpenIntToDoubleHashMap class provides a specialized hash map implementation for int/double. This implementation has a much smaller memory overhead than standard java.util.HashMap class. It uses open addressing and primitive arrays, which greatly reduces the number of intermediate objects and improve data locality.

                  The ContinuedFraction class provides a generic way to create and evaluate continued fractions. The easiest way to create a continued fraction is to subclass ContinuedFraction and override the getA and getB methods which return the continued fraction terms. The precise definition of these terms is explained in Continued Fraction, equation (1) from MathWorld.

                  As an example, the constant Pi can be computed using a continued fraction. The following anonymous class provides the implementation: ContinuedFraction c = new ContinuedFraction() { public double getA(int n, double x) { switch(n) { case 0: return 3.0; default: return 6.0; } } public double getB(int n, double x) { double y = (2.0 * n) - 1.0; return y * y; } }

                  Then, to evalute Pi, simply call any of the evalute methods (Note, the point of evalution in this example is meaningless since Pi is a constant).

                  For a more practical use of continued fractions, consider the exponential function. The following anonymous class provides its implementation: ContinuedFraction c = new ContinuedFraction() { public double getA(int n, double x) { if (n % 2 == 0) { switch(n) { case 0: return 1.0; default: return 2.0; } } else { return n; } } public double getB(int n, double x) { if (n % 2 == 0) { return -x; } else { return x; } } }

                  Then, to evalute ex for any value x, simply call any of the evalute methods.

                  A collection of reusable math functions is provided in the MathUtils utility class. MathUtils currently includes methods to compute the following:

                  • Binomial coefficients -- "n choose k" available as an (exact) long value, binomialCoefficient(int, int) for small n, k; as a double, binomialCoefficientDouble(int, int) for larger values; and in a "super-sized" version, binomialCoefficientLog(int, int) that returns the natural logarithm of the value.
                  • Factorials -- like binomial coefficients, these are available as exact long values, factorial(int); doubles, factorialDouble(int); or logs, factorialLog(int).
                  • Hyperbolic sine and cosine functions -- cosh(double), sinh(double)
                  • sign (+1 if argument > 0, 0 if x = 0, and -1 if x < 0) and indicator (+1.0 if argument >= 0 and -1.0 if argument < 0) functions for variables of all primitive numeric types.
                  • a hash function, hash(double), returning a long-valued hash code for a double value.
                  • Convience methods to round floating-point number to arbitrary precision.
                  • Least common multiple and greatest common denominator functions.

                  The MultidimensionalCounter is a utility class that converts a set of indices (identifying points in a multidimensional space) to a single index (e.g. identifying a location in a one-dimensional array.
                  commons-math-2.2-src/src/site/xdoc/userguide/stat.xml100644 1750 1750 144022 11532241247 21522 0ustarlucluc 0 0 The Commons Math User Guide - Statistics

                  The statistics package provides frameworks and implementations for basic Descriptive statistics, frequency distributions, bivariate regression, and t-, chi-square and ANOVA test statistics.

                  Descriptive statistics

                  Frequency distributions

                  Simple Regression

                  Multiple Regression

                  Rank transformations

                  Covariance and correlation

                  Statistical Tests

                  The stat package includes a framework and default implementations for the following Descriptive statistics:

                  • arithmetic and geometric means
                  • variance and standard deviation
                  • sum, product, log sum, sum of squared values
                  • minimum, maximum, median, and percentiles
                  • skewness and kurtosis
                  • first, second, third and fourth moments

                  With the exception of percentiles and the median, all of these statistics can be computed without maintaining the full list of input data values in memory. The stat package provides interfaces and implementations that do not require value storage as well as implementations that operate on arrays of stored values.

                  The top level interface is UnivariateStatistic. This interface, implemented by all statistics, consists of evaluate() methods that take double[] arrays as arguments and return the value of the statistic. This interface is extended by StorelessUnivariateStatistic, which adds increment(), getResult() and associated methods to support "storageless" implementations that maintain counters, sums or other state information as values are added using the increment() method.

                  Abstract implementations of the top level interfaces are provided in AbstractUnivariateStatistic and AbstractStorelessUnivariateStatistic respectively.

                  Each statistic is implemented as a separate class, in one of the subpackages (moment, rank, summary) and each extends one of the abstract classes above (depending on whether or not value storage is required to compute the statistic). There are several ways to instantiate and use statistics. Statistics can be instantiated and used directly, but it is generally more convenient (and efficient) to access them using the provided aggregates, DescriptiveStatistics and SummaryStatistics.

                  DescriptiveStatistics maintains the input data in memory and has the capability of producing "rolling" statistics computed from a "window" consisting of the most recently added values.

                  SummaryStatistics does not store the input data values in memory, so the statistics included in this aggregate are limited to those that can be computed in one pass through the data without access to the full array of values.

                  AggregateStatistics IncludedValues stored? "Rolling" capability?
                  DescriptiveStatisticsmin, max, mean, geometric mean, n, sum, sum of squares, standard deviation, variance, percentiles, skewness, kurtosis, medianYesYes
                  SummaryStatisticsmin, max, mean, geometric mean, n, sum, sum of squares, standard deviation, varianceNoNo

                  SummaryStatistics can be aggregated using AggregateSummaryStatistics. This class can be used to concurrently gather statistics for multiple datasets as well as for a combined sample including all of the data.

                  MultivariateSummaryStatistics is similar to SummaryStatistics but handles n-tuple values instead of scalar values. It can also compute the full covariance matrix for the input data.

                  Neither DescriptiveStatistics nor SummaryStatistics is thread-safe. SynchronizedDescriptiveStatistics and SynchronizedSummaryStatistics, respectively, provide thread-safe versions for applications that require concurrent access to statistical aggregates by multiple threads. SynchronizedMultivariateSummaryStatistics provides thread-safe MultivariateSummaryStatistics.

                  There is also a utility class, StatUtils, that provides static methods for computing statistics directly from double[] arrays.

                  Here are some examples showing how to compute Descriptive statistics.

                  Compute summary statistics for a list of double values


                  Using the DescriptiveStatistics aggregate (values are stored in memory): // Get a DescriptiveStatistics instance DescriptiveStatistics stats = new DescriptiveStatistics(); // Add the data from the array for( int i = 0; i < inputArray.length; i++) { stats.addValue(inputArray[i]); } // Compute some statistics double mean = stats.getMean(); double std = stats.getStandardDeviation(); double median = stats.getMedian();
                  Using the SummaryStatistics aggregate (values are not stored in memory): // Get a SummaryStatistics instance SummaryStatistics stats = new SummaryStatistics(); // Read data from an input stream, // adding values and updating sums, counters, etc. while (line != null) { line = in.readLine(); stats.addValue(Double.parseDouble(line.trim())); } in.close(); // Compute the statistics double mean = stats.getMean(); double std = stats.getStandardDeviation(); //double median = stats.getMedian(); <-- NOT AVAILABLE
                  Using the StatUtils utility class: // Compute statistics directly from the array // assume values is a double[] array double mean = StatUtils.mean(values); double std = StatUtils.variance(values); double median = StatUtils.percentile(50); // Compute the mean of the first three values in the array mean = StatUtils.mean(values, 0, 3);
                  Maintain a "rolling mean" of the most recent 100 values from an input stream


                  Use a DescriptiveStatistics instance with window size set to 100 // Create a DescriptiveStats instance and set the window size to 100 DescriptiveStatistics stats = new DescriptiveStatistics(); stats.setWindowSize(100); // Read data from an input stream, // displaying the mean of the most recent 100 observations // after every 100 observations long nLines = 0; while (line != null) { line = in.readLine(); stats.addValue(Double.parseDouble(line.trim())); if (nLines == 100) { nLines = 0; System.out.println(stats.getMean()); } } in.close();
                  Compute statistics in a thread-safe manner

                  Use a SynchronizedDescriptiveStatistics instance // Create a SynchronizedDescriptiveStatistics instance and // use as any other DescriptiveStatistics instance DescriptiveStatistics stats = new SynchronizedDescriptiveStatistics();
                  Compute statistics for multiple samples and overall statistics concurrently

                  There are two ways to do this using AggregateSummaryStatistics. The first is to use an AggregateSummaryStatistics instance to accumulate overall statistics contributed by SummaryStatistics instances created using AggregateSummaryStatistics.createContributingStatistics(): // Create a AggregateSummaryStatistics instance to accumulate the overall statistics // and AggregatingSummaryStatistics for the subsamples AggregateSummaryStatistics aggregate = new AggregateSummaryStatistics(); SummaryStatistics setOneStats = aggregate.createContributingStatistics(); SummaryStatistics setTwoStats = aggregate.createContributingStatistics(); // Add values to the subsample aggregates setOneStats.addValue(2); setOneStats.addValue(3); setTwoStats.addValue(2); setTwoStats.addValue(4); ... // Full sample data is reported by the aggregate double totalSampleSum = aggregate.getSum(); The above approach has the disadvantages that the addValue calls must be synchronized on the SummaryStatistics instance maintained by the aggregate and each value addition updates the aggregate as well as the subsample. For applications that can wait to do the aggregation until all values have been added, a static aggregate method is available, as shown in the following example. This method should be used when aggregation needs to be done across threads. // Create SummaryStatistics instances for the subsample data SummaryStatistics setOneStats = new SummaryStatistics(); SummaryStatistics setTwoStats = new SummaryStatistics(); // Add values to the subsample SummaryStatistics instances setOneStats.addValue(2); setOneStats.addValue(3); setTwoStats.addValue(2); setTwoStats.addValue(4); ... // Aggregate the subsample statistics Collection<SummaryStatistics> aggregate = new ArrayList<SummaryStatistics>(); aggregate.add(setOneStats); aggregate.add(setTwoStats); StatisticalSummary aggregatedStats = AggregateSummaryStatistics.aggregate(aggregate); // Full sample data is reported by aggregatedStats double totalSampleSum = aggregatedStats.getSum();

                  Frequency provides a simple interface for maintaining counts and percentages of discrete values.

                  Strings, integers, longs and chars are all supported as value types, as well as instances of any class that implements Comparable. The ordering of values used in computing cumulative frequencies is by default the natural ordering, but this can be overriden by supplying a Comparator to the constructor. Adding values that are not comparable to those that have already been added results in an IllegalArgumentException.

                  Here are some examples.

                  Compute a frequency distribution based on integer values


                  Mixing integers, longs, Integers and Longs: Frequency f = new Frequency(); f.addValue(1); f.addValue(new Integer(1)); f.addValue(new Long(1)); f.addValue(2); f.addValue(new Integer(-1)); System.out.prinltn(f.getCount(1)); // displays 3 System.out.println(f.getCumPct(0)); // displays 0.2 System.out.println(f.getPct(new Integer(1))); // displays 0.6 System.out.println(f.getCumPct(-2)); // displays 0 System.out.println(f.getCumPct(10)); // displays 1
                  Count string frequencies


                  Using case-sensitive comparison, alpha sort order (natural comparator): Frequency f = new Frequency(); f.addValue("one"); f.addValue("One"); f.addValue("oNe"); f.addValue("Z"); System.out.println(f.getCount("one")); // displays 1 System.out.println(f.getCumPct("Z")); // displays 0.5 System.out.println(f.getCumPct("Ot")); // displays 0.25
                  Using case-insensitive comparator: Frequency f = new Frequency(String.CASE_INSENSITIVE_ORDER); f.addValue("one"); f.addValue("One"); f.addValue("oNe"); f.addValue("Z"); System.out.println(f.getCount("one")); // displays 3 System.out.println(f.getCumPct("z")); // displays 1

                  SimpleRegression provides ordinary least squares regression with one independent variable estimating the linear model:

                  y = intercept + slope * x

                  Standard errors for intercept and slope are available as well as ANOVA, r-square and Pearson's r statistics.

                  Observations (x,y pairs) can be added to the model one at a time or they can be provided in a 2-dimensional array. The observations are not stored in memory, so there is no limit to the number of observations that can be added to the model.

                  Usage Notes:

                  • When there are fewer than two observations in the model, or when there is no variation in the x values (i.e. all x values are the same) all statistics return NaN. At least two observations with different x coordinates are requred to estimate a bivariate regression model.
                  • getters for the statistics always compute values based on the current set of observations -- i.e., you can get statistics, then add more data and get updated statistics without using a new instance. There is no "compute" method that updates all statistics. Each of the getters performs the necessary computations to return the requested statistic.

                  Implementation Notes:

                  • As observations are added to the model, the sum of x values, y values, cross products (x times y), and squared deviations of x and y from their respective means are updated using updating formulas defined in "Algorithms for Computing the Sample Variance: Analysis and Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. 1983, American Statistician, vol. 37, pp. 242-247, referenced in Weisberg, S. "Applied Linear Regression". 2nd Ed. 1985. All regression statistics are computed from these sums.
                  • Inference statistics (confidence intervals, parameter significance levels) are based on on the assumption that the observations included in the model are drawn from a Bivariate Normal Distribution

                  Here are some examples.

                  Estimate a model based on observations added one at a time


                  Instantiate a regression instance and add data points regression = new SimpleRegression(); regression.addData(1d, 2d); // At this point, with only one observation, // all regression statistics will return NaN regression.addData(3d, 3d); // With only two observations, // slope and intercept can be computed // but inference statistics will return NaN regression.addData(3d, 3d); // Now all statistics are defined.
                  Compute some statistics based on observations added so far System.out.println(regression.getIntercept()); // displays intercept of regression line System.out.println(regression.getSlope()); // displays slope of regression line System.out.println(regression.getSlopeStdErr()); // displays slope standard error
                  Use the regression model to predict the y value for a new x value System.out.println(regression.predict(1.5d) // displays predicted y value for x = 1.5 More data points can be added and subsequent getXxx calls will incorporate additional data in statistics.
                  Estimate a model from a double[][] array of data points


                  Instantiate a regression object and load dataset double[][] data = { { 1, 3 }, {2, 5 }, {3, 7 }, {4, 14 }, {5, 11 }}; SimpleRegression regression = new SimpleRegression(); regression.addData(data);
                  Estimate regression model based on data System.out.println(regression.getIntercept()); // displays intercept of regression line System.out.println(regression.getSlope()); // displays slope of regression line System.out.println(regression.getSlopeStdErr()); // displays slope standard error More data points -- even another double[][] array -- can be added and subsequent getXxx calls will incorporate additional data in statistics.

                  OLSMultipleLinearRegression and GLSMultipleLinearRegression provide least squares regression to fit the linear model:

                  Y=X*b+u

                  where Y is an n-vector regressand, X is a [n,k] matrix whose k columns are called regressors, b is k-vector of regression parameters and u is an n-vector of error terms or residuals.

                  OLSMultipleLinearRegression provides Ordinary Least Squares Regression, and GLSMultipleLinearRegression implements Generalized Least Squares. See the javadoc for these classes for details on the algorithms and forumlas used.

                  Data for OLS models can be loaded in a single double[] array, consisting of concatenated rows of data, each containing the regressand (Y) value, followed by regressor values; or using a double[][] array with rows corresponding to observations. GLS models also require a double[][] array representing the covariance matrix of the error terms. See AbstractMultipleLinearRegression#newSampleData(double[],int,int), OLSMultipleLinearRegression#newSampleData(double[], double[][]) and GLSMultipleLinearRegression#newSampleData(double[],double[][],double[][]) for details.

                  Usage Notes:

                  • Data are validated when invoking any of the newSample, newX, newY or newCovariance methods and IllegalArgumentException is thrown when input data arrays do not have matching dimensions or do not contain sufficient data to estimate the model.
                  • By default, regression models are estimated with intercept terms. In the notation above, this implies that the X matrix contains an initial row identically equal to 1. X data supplied to the newX or newSample methods should not include this column - the data loading methods will create it automatically. To estimate a model without an intercept term, set the noIntercept property to true.

                  Here are some examples.

                  OLS regression


                  Instantiate an OLS regression object and load a dataset: OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression(); double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; double[] x = new double[6][]; x[0] = new double[]{0, 0, 0, 0, 0}; x[1] = new double[]{2.0, 0, 0, 0, 0}; x[2] = new double[]{0, 3.0, 0, 0, 0}; x[3] = new double[]{0, 0, 4.0, 0, 0}; x[4] = new double[]{0, 0, 0, 5.0, 0}; x[5] = new double[]{0, 0, 0, 0, 6.0}; regression.newSample(y, x);
                  Get regression parameters and diagnostics: double[] beta = regression.estimateRegressionParameters(); double[] residuals = regression.estimateResiduals(); double[][] parametersVariance = regression.estimateRegressionParametersVariance(); double regressandVariance = regression.estimateRegressandVariance(); double rSquared = regression.caclulateRSquared(); double sigma = regression.estimateRegressionStandardError();
                  GLS regression


                  Instantiate a GLS regression object and load a dataset: GLSMultipleLinearRegression regression = new GLSMultipleLinearRegression(); double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; double[] x = new double[6][]; x[0] = new double[]{0, 0, 0, 0, 0}; x[1] = new double[]{2.0, 0, 0, 0, 0}; x[2] = new double[]{0, 3.0, 0, 0, 0}; x[3] = new double[]{0, 0, 4.0, 0, 0}; x[4] = new double[]{0, 0, 0, 5.0, 0}; x[5] = new double[]{0, 0, 0, 0, 6.0}; double[][] omega = new double[6][]; omega[0] = new double[]{1.1, 0, 0, 0, 0, 0}; omega[1] = new double[]{0, 2.2, 0, 0, 0, 0}; omega[2] = new double[]{0, 0, 3.3, 0, 0, 0}; omega[3] = new double[]{0, 0, 0, 4.4, 0, 0}; omega[4] = new double[]{0, 0, 0, 0, 5.5, 0}; omega[5] = new double[]{0, 0, 0, 0, 0, 6.6}; regression.newSampleData(y, x, omega);

                  Some statistical algorithms require that input data be replaced by ranks. The org.apache.commons.math.stat.ranking package provides rank transformation. RankingAlgorithm defines the interface for ranking. NaturalRanking provides an implementation that has two configuration options.

                  • Ties strategy deterimines how ties in the source data are handled by the ranking
                  • NaN strategy determines how NaN values in the source data are handled.

                  Examples: NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL, TiesStrategy.MAXIMUM); double[] data = { 20, 17, 30, 42.3, 17, 50, Double.NaN, Double.NEGATIVE_INFINITY, 17 }; double[] ranks = ranking.rank(exampleData); results in ranks containing {6, 5, 7, 8, 5, 9, 2, 2, 5}. new NaturalRanking(NaNStrategy.REMOVED,TiesStrategy.SEQUENTIAL).rank(exampleData); returns {5, 2, 6, 7, 3, 8, 1, 4}.

                  The default NaNStrategy is NaNStrategy.MAXIMAL. This makes NaN values larger than any other value (including Double.POSITIVE_INFINITY). The default TiesStrategy is TiesStrategy.AVERAGE, which assigns tied values the average of the ranks applicable to the sequence of ties. See the NaturalRanking for more examples and TiesStrategy and NaNStrategy for details on these configuration options.

                  The org.apache.commons.math.stat.correlation package computes covariances and correlations for pairs of arrays or columns of a matrix. Covariance computes covariances, PearsonsCorrelation provides Pearson's Product-Moment correlation coefficients and SpearmansCorrelation computes Spearman's rank correlation.

                  Implementation Notes

                  • Unbiased covariances are given by the formula

                    cov(X, Y) = sum [(xi - E(X))(yi - E(Y))] / (n - 1) where E(X) is the mean of X and E(Y) is the mean of the Y values. Non-bias-corrected estimates use n in place of n - 1. Whether or not covariances are bias-corrected is determined by the optional parameter, "biasCorrected," which defaults to true.
                  • PearsonsCorrelation computes correlations defined by the formula

                    cor(X, Y) = sum[(xi - E(X))(yi - E(Y))] / [(n - 1)s(X)s(Y)]
                    where E(X) and E(Y) are means of X and Y and s(X), s(Y) are standard deviations.
                  • SpearmansCorrelation applies a rank transformation to the input data and computes Pearson's correlation on the ranked data. The ranking algorithm is configurable. By default, NaturalRanking with default strategies for handling ties and NaN values is used.

                  Examples:

                  Covariance of 2 arrays


                  To compute the unbiased covariance between 2 double arrays, x and y, use: new Covariance().covariance(x, y) For non-bias-corrected covariances, use covariance(x, y, false)


                  Covariance matrix


                  A covariance matrix over the columns of a source matrix data can be computed using new Covariance().computeCovarianceMatrix(data) The i-jth entry of the returned matrix is the unbiased covariance of the ith and jth columns of data. As above, to get non-bias-corrected covariances, use computeCovarianceMatrix(data, false)


                  Pearson's correlation of 2 arrays


                  To compute the Pearson's product-moment correlation between two double arrays x and y, use: new PearsonsCorrelation().correlation(x, y)


                  Pearson's correlation matrix


                  A (Pearson's) correlation matrix over the columns of a source matrix data can be computed using new PearsonsCorrelation().computeCorrelationMatrix(data) The i-jth entry of the returned matrix is the Pearson's product-moment correlation between the ith and jth columns of data.


                  Pearson's correlation significance and standard errors


                  To compute standard errors and/or significances of correlation coefficients associated with Pearson's correlation coefficients, start by creating a PearsonsCorrelation instance PearsonsCorrelation correlation = new PearsonsCorrelation(data); where data is either a rectangular array or a RealMatrix. Then the matrix of standard errors is correlation.getCorrelationStandardErrors(); The formula used to compute the standard error is
                  SEr = ((1 - r2) / (n - 2))1/2
                  where r is the estimated correlation coefficient and n is the number of observations in the source dataset.

                  p-values for the (2-sided) null hypotheses that elements of a correlation matrix are zero populate the RealMatrix returned by correlation.getCorrelationPValues() getCorrelationPValues().getEntry(i,j) is the probability that a random variable distributed as tn-2 takes a value with absolute value greater than or equal to

                  |rij|((n - 2) / (1 - rij2))1/2, where rij is the estimated correlation between the ith and jth columns of the source array or RealMatrix. This is sometimes referred to as the significance of the coefficient.

                  For example, if data is a RealMatrix with 2 columns and 10 rows, then new PearsonsCorrelation(data).getCorrelationPValues().getEntry(0,1) is the significance of the Pearson's correlation coefficient between the two columns of data. If this value is less than .01, we can say that the correlation between the two columns of data is significant at the 99% level.


                  Spearman's rank correlation coefficient


                  To compute the Spearman's rank-moment correlation between two double arrays x and y: new SpearmansCorrelation().correlation(x, y) This is equivalent to RankingAlgorithm ranking = new NaturalRanking(); new PearsonsCorrelation().correlation(ranking.rank(x), ranking.rank(y))


                  The interfaces and implementations in the org.apache.commons.math.stat.inference package provide Student's t, Chi-Square and One-Way ANOVA test statistics as well as p-values associated with t-, Chi-Square and One-Way ANOVA tests. The interfaces are TTest, ChiSquareTest, and OneWayAnova with provided implementations TTestImpl, ChiSquareTestImpl and OneWayAnovaImpl, respectively. The TestUtils class provides static methods to get test instances or to compute test statistics directly. The examples below all use the static methods in TestUtils to execute tests. To get test object instances, either use e.g., TestUtils.getTTest() or use the implementation constructors directly, e.g. new TTestImpl().

                  Implementation Notes

                  • Both one- and two-sample t-tests are supported. Two sample tests can be either paired or unpaired and the unpaired two-sample tests can be conducted under the assumption of equal subpopulation variances or without this assumption. When equal variances is assumed, a pooled variance estimate is used to compute the t-statistic and the degrees of freedom used in the t-test equals the sum of the sample sizes minus 2. When equal variances is not assumed, the t-statistic uses both sample variances and the Welch-Satterwaite approximation is used to compute the degrees of freedom. Methods to return t-statistics and p-values are provided in each case, as well as boolean-valued methods to perform fixed significance level tests. The names of methods or methods that assume equal subpopulation variances always start with "homoscedastic." Test or test-statistic methods that just start with "t" do not assume equal variances. See the examples below and the API documentation for more details.
                  • The validity of the p-values returned by the t-test depends on the assumptions of the parametric t-test procedure, as discussed here
                  • p-values returned by t-, chi-square and Anova tests are exact, based on numerical approximations to the t-, chi-square and F distributions in the distributions package.
                  • p-values returned by t-tests are for two-sided tests and the boolean-valued methods supporting fixed significance level tests assume that the hypotheses are two-sided. One sided tests can be performed by dividing returned p-values (resp. critical values) by 2.
                  • Degrees of freedom for chi-square tests are integral values, based on the number of observed or expected counts (number of observed counts - 1) for the goodness-of-fit tests and (number of columns -1) * (number of rows - 1) for independence tests.

                  Examples:

                  One-sample t tests


                  To compare the mean of a double[] array to a fixed value: double[] observed = {1d, 2d, 3d}; double mu = 2.5d; System.out.println(TestUtils.t(mu, observed)); The code above will display the t-statisitic associated with a one-sample t-test comparing the mean of the observed values against mu.
                  To compare the mean of a dataset described by a StatisticalSummary to a fixed value: double[] observed ={1d, 2d, 3d}; double mu = 2.5d; SummaryStatistics sampleStats = new SummaryStatistics(); for (int i = 0; i < observed.length; i++) { sampleStats.addValue(observed[i]); } System.out.println(TestUtils.t(mu, observed));
                  To compute the p-value associated with the null hypothesis that the mean of a set of values equals a point estimate, against the two-sided alternative that the mean is different from the target value: double[] observed = {1d, 2d, 3d}; double mu = 2.5d; System.out.println(TestUtils.tTest(mu, observed)); The snippet above will display the p-value associated with the null hypothesis that the mean of the population from which the observed values are drawn equals mu.
                  To perform the test using a fixed significance level, use: TestUtils.tTest(mu, observed, alpha); where 0 < alpha < 0.5 is the significance level of the test. The boolean value returned will be true iff the null hypothesis can be rejected with confidence 1 - alpha. To test, for example at the 95% level of confidence, use alpha = 0.05


                  Two-Sample t-tests


                  Example 1: Paired test evaluating the null hypothesis that the mean difference between corresponding (paired) elements of the double[] arrays sample1 and sample2 is zero.

                  To compute the t-statistic: TestUtils.pairedT(sample1, sample2);

                  To compute the p-value: TestUtils.pairedTTest(sample1, sample2);

                  To perform a fixed significance level test with alpha = .05: TestUtils.pairedTTest(sample1, sample2, .05);

                  The last example will return true iff the p-value returned by TestUtils.pairedTTest(sample1, sample2) is less than .05
                  Example 2: unpaired, two-sided, two-sample t-test using StatisticalSummary instances, without assuming that subpopulation variances are equal.

                  First create the StatisticalSummary instances. Both DescriptiveStatistics and SummaryStatistics implement this interface. Assume that summary1 and summary2 are SummaryStatistics instances, each of which has had at least 2 values added to the (virtual) dataset that it describes. The sample sizes do not have to be the same -- all that is required is that both samples have at least 2 elements.

                  Note: The SummaryStatistics class does not store the dataset that it describes in memory, but it does compute all statistics necessary to perform t-tests, so this method can be used to conduct t-tests with very large samples. One-sample tests can also be performed this way. (See Descriptive statistics for details on the SummaryStatistics class.)

                  To compute the t-statistic: TestUtils.t(summary1, summary2);

                  To compute the p-value: TestUtils.tTest(sample1, sample2);

                  To perform a fixed significance level test with alpha = .05: TestUtils.tTest(sample1, sample2, .05);

                  In each case above, the test does not assume that the subpopulation variances are equal. To perform the tests under this assumption, replace "t" at the beginning of the method name with "homoscedasticT"



                  Chi-square tests


                  To compute a chi-square statistic measuring the agreement between a long[] array of observed counts and a double[] array of expected counts, use: long[] observed = {10, 9, 11}; double[] expected = {10.1, 9.8, 10.3}; System.out.println(TestUtils.chiSquare(expected, observed)); the value displayed will be sum((expected[i] - observed[i])^2 / expected[i])
                  To get the p-value associated with the null hypothesis that observed conforms to expected use: TestUtils.chiSquareTest(expected, observed);
                  To test the null hypothesis that observed conforms to expected with alpha siginficance level (equiv. 100 * (1-alpha)% confidence) where 0 < alpha < 1 use: TestUtils.chiSquareTest(expected, observed, alpha); The boolean value returned will be true iff the null hypothesis can be rejected with confidence 1 - alpha.
                  To compute a chi-square statistic statistic associated with a chi-square test of independence based on a two-dimensional (long[][]) counts array viewed as a two-way table, use: TestUtils.chiSquareTest(counts); The rows of the 2-way table are count[0], ... , count[count.length - 1].

                  The chi-square statistic returned is sum((counts[i][j] - expected[i][j])^2/expected[i][j]) where the sum is taken over all table entries and expected[i][j] is the product of the row and column sums at row i, column j divided by the total count.
                  To compute the p-value associated with the null hypothesis that the classifications represented by the counts in the columns of the input 2-way table are independent of the rows, use: TestUtils.chiSquareTest(counts);
                  To perform a chi-square test of independence with alpha siginficance level (equiv. 100 * (1-alpha)% confidence) where 0 < alpha < 1 use: TestUtils.chiSquareTest(counts, alpha); The boolean value returned will be true iff the null hypothesis can be rejected with confidence 1 - alpha.


                  One-Way Anova tests


                  To conduct a One-Way Analysis of Variance (ANOVA) to evaluate the null hypothesis that the means of a collection of univariate datasets are the same, start by loading the datasets into a collection, e.g. double[] classA = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0 }; double[] classB = {99.0, 92.0, 102.0, 100.0, 102.0, 89.0 }; double[] classC = {110.0, 115.0, 111.0, 117.0, 128.0, 117.0 }; List classes = new ArrayList(); classes.add(classA); classes.add(classB); classes.add(classC); Then you can compute ANOVA F- or p-values associated with the null hypothesis that the class means are all the same using a OneWayAnova instance or TestUtils methods: double fStatistic = TestUtils.oneWayAnovaFValue(classes); // F-value double pValue = TestUtils.oneWayAnovaPValue(classes); // P-value To test perform a One-Way Anova test with signficance level set at 0.01 (so the test will, assuming assumptions are met, reject the null hypothesis incorrectly only about one in 100 times), use TestUtils.oneWayAnovaTest(classes, 0.01); // returns a boolean // true means reject null hypothesis

                  commons-math-2.2-src/src/site/xdoc/userguide/transform.xml100644 1750 1750 4000 11532241247 22511 0ustarlucluc 0 0 The Commons Math User Guide - Transform methods

                  This package provides a few transformers for signal analysis. All transformers provide both direct and inverse transforms.

                  commons-math-2.2-src/src/site/xdoc/userguide/linear.xml100644 1750 1750 25067 11532241247 22010 0ustarlucluc 0 0 The Commons Math User Guide - Linear Algebra

                  Linear algebra support in commons-math provides operations on real matrices (both dense and sparse matrices are supported) and vectors. It features basic operations (addition, subtraction ...) and decomposition algorithms that can be used to solve linear systems either in exact sense and in least squares sense.

                  The RealMatrix interface represents a matrix with real numbers as entries. The following basic matrix operations are supported:

                  • Matrix addition, subtraction, multiplication
                  • Scalar addition and multiplication
                  • transpose
                  • Norm and Trace
                  • Operation on a vector

                  Example: // Create a real matrix with two rows and three columns double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}}; RealMatrix m = new Array2DRowRealMatrix(matrixData); // One more with three rows, two columns double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}}; RealMatrix n = new Array2DRowRealMatrix(matrixData2); // Note: The constructor copies the input double[][] array. // Now multiply m by n RealMatrix p = m.multiply(n); System.out.println(p.getRowDimension()); // 2 System.out.println(p.getColumnDimension()); // 2 // Invert p, using LU decomposition RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse();

                  The three main implementations of the interface are Array2DRowRealMatrix and BlockRealMatrix for dense matrices (the second one being more suited to dimensions above 50 or 100) and SparseRealMatrix for sparse matrices.

                  The RealVector interface represents a vector with real numbers as entries. The following basic matrix operations are supported:

                  • Vector addition, subtraction
                  • Element by element multiplication, division
                  • Scalar addition, subtraction, multiplication, division and power
                  • Mapping of mathematical functions (cos, sin ...)
                  • Dot product, outer product
                  • Distance and norm according to norms L1, L2 and Linf

                  The RealVectorFormat class handles input/output of vectors in a customizable textual format.

                  The solve() methods of the DecompositionSolver interface support solving linear systems of equations of the form AX=B, either in linear sense or in least square sense. A RealMatrix instance is used to represent the coefficient matrix of the system. Solving the system is a two phases process: first the coefficient matrix is decomposed in some way and then a solver built from the decomposition solves the system. This allows to compute the decomposition and build the solver only once if several systems have to be solved with the same coefficient matrix.

                  For example, to solve the linear system

                             2x + 3y - 2z = 1
                             -x + 7y + 6x = -2
                             4x - 3y - 5z = 1
                            
                  Start by decomposing the coefficient matrix A (in this case using LU decomposition) and build a solver RealMatrix coefficients = new Array2DRowRealMatrix(new double[][] { { 2, 3, -2 }, { -1, 7, 6 }, { 4, -3, -5 } }, false); DecompositionSolver solver = new LUDecompositionImpl(coefficients).getSolver(); Next create a RealVector array to represent the constant vector B and use solve(RealVector) to solve the system RealVector constants = new RealVectorImpl(new double[] { 1, -2, 1 }, false); RealVector solution = solver.solve(constants); The solution vector will contain values for x (solution.getEntry(0)), y (solution.getEntry(1)), and z (solution.getEntry(2)) that solve the system.

                  Each type of decomposition has its specific semantics and constraints on the coefficient matrix as shown in the following table. For algorithms that solve AX=B in least squares sense the value returned for X is such that the residual AX-B has minimal norm. If an exact solution exist (i.e. if for some X the residual AX-B is exactly 0), then this exact solution is also the solution in least square sense. This implies that algorithms suited for least squares problems can also be used to solve exact problems, but the reverse is not true.

                  Decomposition algorithms
                  Namecoefficients matrixproblem type
                  LUsquareexact solution only
                  Choleskysymmetric positive definiteexact solution only
                  QRanyleast squares solution
                  eigen decompositionsquareexact solution only
                  SVDanyleast squares solution

                  It is possible to use a simple array of double instead of a RealVector. In this case, the solution will be provided also as an array of double.

                  It is possible to solve multiple systems with the same coefficient matrix in one method call. To do this, create a matrix whose column vectors correspond to the constant vectors for the systems to be solved and use solve(RealMatrix), which returns a matrix with column vectors representing the solutions.

                  Decomposition algorithms may be used for themselves and not only for linear system solving. This is of prime interest with eigen decomposition and singular value decomposition.

                  The getEigenvalue(), getEigenvalues(), getEigenVector(), getV(), getD() and getVT() methods of the EigenDecomposition interface support solving eigenproblems of the form AX = lambda X where lambda is a real scalar.

                  The getSingularValues(), getU(), getS() and getV() methods of the SingularValueDecomposition interface allow to solve singular values problems of the form AXi = lambda Yi where lambda is a real scalar, and where the Xi and Yi vectors form orthogonal bases of their respective vector spaces (which may have different dimensions).

                  In addition to the real field, matrices and vectors using non-real field elements can be used. The fields already supported by the library are:

                  commons-math-2.2-src/src/site/xdoc/userguide/xdoc.xsl100644 1750 1750 4715 11532241247 21456 0ustarlucluc 0 0

                                  
                              
                  commons-math-2.2-src/src/site/xdoc/userguide/complex.xml100644 1750 1750 15733 11532241247 22204 0ustarlucluc 0 0 The Commons Math User Guide - Complex Numbers

                  The complex packages provides a complex number type as well as complex versions of common transcendental functions and complex number formatting.

                  Complex provides a complex number type that forms the basis for the complex functionality found in commons-math.

                  Complex functions and arithmetic operations are implemented in commons-math by applying standard computational formulas and following the rules for java.lang.Double arithmetic in handling infinite and NaN values. No attempt is made to comply with ANSII/IEC C99x Annex G or any other standard for Complex arithmetic. See the class and method javadocs for the Complex and ComplexUtils classes for details on computing formulas.

                  To create a complex number, simply call the constructor passing in two floating-point arguments, the first being the real part of the complex number and the second being the imaginary part: Complex c = new Complex(1.0, 3.0); // 1 + 3i

                  Complex numbers may also be created from polar representations using the polar2Complex method in ComplexUtils.

                  The Complex class provides basic unary and binary complex number operations. These operations provide the means to add, subtract, multiply and divide complex numbers along with other complex number functions similar to the real number functions found in java.math.BigDecimal: Complex lhs = new Complex(1.0, 3.0); Complex rhs = new Complex(2.0, 5.0); Complex answer = lhs.add(rhs); // add two complex numbers answer = lhs.subtract(rhs); // subtract two complex numbers answer = lhs.abs(); // absolute value answer = lhs.conjugate(rhs); // complex conjugate

                  Complex also provides implementations of serveral transcendental functions involving complex number arguments. Prior to version 1.2, these functions were provided by ComplexUtils in a way similar to the real number functions found in java.lang.Math, but this has been deprecated. These operations provide the means to compute the log, sine, tangent, and other complex values : Complex first = new Complex(1.0, 3.0); Complex second = new Complex(2.0, 5.0); Complex answer = first.log(); // natural logarithm. answer = first.cos(); // cosine answer = first.pow(second); // first raised to the power of second

                  Complex instances can be converted to and from strings using the ComplexFormat class. ComplexFormat is a java.text.Format extension and, as such, is used like other formatting objects (e.g. java.text.SimpleDateFormat): ComplexFormat format = new ComplexFormat(); // default format Complex c = new Complex(1.1111, 2.2222); String s = format.format(c); // s contains "1.11 + 2.22i"

                  To customize the formatting output, one or two java.text.NumberFormat instances can be used to construct a ComplexFormat. These number formats control the formatting of the real and imaginary values of the complex number: NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumFractionDigits(3); nf.setMaximumFractionDigits(3); // create complex format with custom number format // when one number format is used, both real and // imaginary parts are formatted the same ComplexFormat cf = new ComplexFormat(nf); Complex c = new Complex(1.11, 2.2222); String s = format.format(c); // s contains "1.110 + 2.222i" NumberFormat nf2 = NumberFormat.getInstance(); nf.setMinimumFractionDigits(1); nf.setMaximumFractionDigits(1); // create complex format with custom number formats cf = new ComplexFormat(nf, nf2); s = format.format(c); // s contains "1.110 + 2.2i"

                  Another formatting customization provided by ComplexFormat is the text used for the imaginary designation. By default, the imaginary notation is "i" but, it can be manipulated using the setImaginaryCharacter method.

                  Formatting inverse operation, parsing, can also be performed by ComplexFormat. Parse a complex number from a string, simply call the parse method: ComplexFormat cf = new ComplexFormat(); Complex c = cf.parse("1.110 + 2.222i");

                  commons-math-2.2-src/src/site/xdoc/userguide/optimization.xml100644 1750 1750 36745 11532241247 23271 0ustarlucluc 0 0 The Commons Math User Guide - Optimization

                  The optimization package provides algorithms to optimize (i.e. either minimize or maximize) some objective or cost function. The package is split in several sub-packages dedicated to different kind of functions or algorithms.

                  • the univariate package handles univariate scalar functions,
                  • the linear package handles multivariate vector linear functions with linear constraints,
                  • the direct package handles multivariate scalar functions using direct search methods (i.e. not using derivatives),
                  • the general package handles multivariate scalar or vector functions using derivatives.
                  • the fitting package handles curve fitting by univariate real functions

                  The top level optimization package provides common interfaces for the optimization algorithms provided in sub-packages. The main interfaces defines defines optimizers and convergence checkers. The functions that are optimized by the algorithms provided by this package and its sub-packages are a subset of the one defined in the analysis package, namely the real and vector valued functions. These functions are called objective function here. When the goal is to minimize, the functions are often called cost function, this name is not used in this package.

                  The type of goal, i.e. minimization or maximization, is defined by the enumerated GoalType which has only two values: MAXIMIZE and MINIMIZE.

                  Optimizers are the algorithms that will either minimize or maximize, the objective function by changing its input variables set until an optimal set is found. There are only four interfaces defining the common behavior of optimizers, one for each supported type of objective function:

                  Despite there are only four types of supported optimizers, it is possible to optimize a transform a non-differentiable multivariate vectorial function by converting it to a non-differentiable multivariate real function thanks to the LeastSquaresConverter helper class. The transformed function can be optimized using any implementation of the MultivariateRealOptimizer interface.

                  For each of the four types of supported optimizers, there is a special implementation which wraps a classical optimizer in order to add it a multi-start feature. This feature call the underlying optimizer several times in sequence with different starting points and returns the best optimum found or all optima if desired. This is a classical way to prevent being trapped into a local extremum when looking for a global one.

                  A UnivariateRealOptimizer is used to find the minimal values of a univariate real-valued function f.

                  These algorithms usage is very similar to root-finding algorithms usage explained in the analysis package. The main difference is that the solve methods in root finding algorithms is replaced by optimize methods.

                  This package provides an implementation of George Dantzig's simplex algorithm for solving linear optimization problems with linear equality and inequality constraints.

                  Direct search methods only use cost function values, they don't need derivatives and don't either try to compute approximation of the derivatives. According to a 1996 paper by Margaret H. Wright (Direct Search Methods: Once Scorned, Now Respectable), they are used when either the computation of the derivative is impossible (noisy functions, unpredictable discontinuities) or difficult (complexity, computation cost). In the first cases, rather than an optimum, a not too bad point is desired. In the latter cases, an optimum is desired but cannot be reasonably found. In all cases direct search methods can be useful.

                  Simplex-based direct search methods are based on comparison of the cost function values at the vertices of a simplex (which is a set of n+1 points in dimension n) that is updated by the algorithms steps.

                  The instances can be built either in single-start or in multi-start mode. Multi-start is a traditional way to try to avoid being trapped in a local minimum and miss the global minimum of a function. It can also be used to verify the convergence of an algorithm. In multi-start mode, the minimizesmethod returns the best minimum found after all starts, and the etMinima method can be used to retrieve all minima from all starts (including the one already provided by the minimizes method).

                  The direct package provides two solvers. The first one is the classical Nelder-Mead method. The second one is Virginia Torczon's multi-directional method.

                  The general package deals with non-linear vectorial optimization problems when the partial derivatives of the objective function are available.

                  One important class of estimation problems is weighted least squares problems. They basically consist in finding the values for some parameters pk such that a cost function J = sum(wi(mesi - modi)2) is minimized. The various (targeti - modeli(pk)) terms are called residuals. They represent the deviation between a set of target values targeti and theoretical values computed from models modeli depending on free parameters pk. The wi factors are weights. One classical use case is when the target values are experimental observations or measurements.

                  Solving a least-squares problem is finding the free parameters pk of the theoretical models such that they are close to the target values, i.e. when the residual are small.

                  Two optimizers are available in the general package, both devoted to least-squares problems. The first one is based on the Gauss-Newton method. The second one is the Levenberg-Marquardt method.

                  In order to solve a vectorial optimization problem, the user must provide it as an object implementing the DifferentiableMultivariateVectorialFunction interface. The object will be provided to the estimate method of the optimizer, along with the target and weight arrays, thus allowing the optimizer to compute the residuals at will. The last parameter to the estimate method is the point from which the optimizer will start its search for the optimal point.

                  In addition to least squares solving, the NonLinearConjugateGradientOptimizer class provides a non-linear conjugate gradient algorithm to optimize DifferentiableMultivariateRealFunction. Both the Fletcher-Reeves and the Polak-Ribière search direction update methods are supported. It is also possible to set up a preconditioner or to change the line-search algorithm of the inner loop if desired (the default one is a Brent solver).

                  The PowellOptimizer provides an optimization method for non-differentiable functions.

                  The fitting package deals with curve fitting for univariate real functions. When a univariate real function y = f(x) does depend on some unknown parameters p0, p1 ... pn-1, curve fitting can be used to find these parameters. It does this by fitting the curve so it remains very close to a set of observed points (x0, y0), (x1, y1) ... (xk-1, yk-1). This fitting is done by finding the parameters values that minimizes the objective function sum(yi-f(xi))2. This is really a least squares problem.

                  For all provided curve fitters, the operating principle is the same. Users must first create an instance of the fitter, then add the observed points and once the complete sample of observed points has been added they must call the fit method which will compute the parameters that best fit the sample. A weight is associated with each observed point, this allows to take into account uncertainty on some points when they come from loosy measurements for example. If no such information exist and all points should be treated the same, it is safe to put 1.0 as the weight for all points.

                  The CurveFitter class provides curve fitting for general curves. Users must provide their own implementation of the curve template as a class implementing the ParametricRealFunction interface and they must provide the initial guess of the parameters. The more specialized PolynomialFitter and HarmonicFitter classes require neither an implementation of the parametric real function not an initial guess as they are able to compute them by themselves.

                  An example of fitting a polynomial is given here:

                  PolynomialFitter fitter = new PolynomialFitter(degree, new LevenbergMarquardtOptimizer()); fitter.addObservedPoint(-1.00, 2.021170021833143); fitter.addObservedPoint(-0.99 2.221135431136975); fitter.addObservedPoint(-0.98 2.09985277659314); fitter.addObservedPoint(-0.97 2.0211192647627025); // lots of lines ommitted fitter.addObservedPoint( 0.99, -2.4345814727089854); PolynomialFunction fitted = fitter.fit();
                  commons-math-2.2-src/src/site/xdoc/userguide/overview.xml100644 1750 1750 20533 11532241247 22375 0ustarlucluc 0 0 User Guide - Overview

                  This guide is intended to help programmers quickly find what they need to develop solutions using Commons Math. It also provides a supplement to the javadoc API documentation, providing a little more explanation of the mathematical objects and functions included in the package.

                  Commons Math is made up of a small set of math/stat utilities addressing programming problems like the ones in the list below. This list is not exhaustive, it's just meant to give a feel for the kinds of things that Commons Math provides.

                  • Computing means, variances and other summary statistics for a list of numbers
                  • Fitting a line to a set of data points using linear regression
                  • Finding a smooth curve that passes through a collection of points (interpolation)
                  • Fitting a parametric model to a set of measurements using least-squares methods
                  • Solving equations involving real-valued functions (i.e. root-finding)
                  • Solving systems of linear equations
                  • Solving Ordinary Differential Equations
                  • Minimizing multi-dimensional functions
                  • Generating random numbers with more restrictions (e.g distribution, range) than what is possible using the JDK
                  • Generating random samples and/or datasets that are "like" the data in an input file
                  • Performing statistical significance tests
                  • Miscellaneous mathematical functions such as factorials, binomial coefficients and "special functions" (e.g. gamma, beta functions)

                  We are actively seeking ideas for additional components that fit into the Commons Math vision of a set of lightweight, self-contained math/stat components useful for solving common programming problems. Suggestions for new components or enhancements to existing functionality are always welcome! All feedback/suggestions for improvement should be sent to the commons-dev mailing list with [math] at the beginning of the subject line.

                  Commons Math is divided into fourteen subpackages, based on functionality provided.

                  1. org.apache.commons.math.stat - statistics, statistical tests
                  2. org.apache.commons.math.analysis - rootfinding, integration, interpolation, polynomials
                  3. org.apache.commons.math.random - random numbers, strings and data generation
                  4. org.apache.commons.math.special - special functions (Gamma, Beta)
                  5. org.apache.commons.math.linear - matrices, solving linear systems
                  6. org.apache.commons.math.util - common math/stat functions extending java.lang.Math
                  7. org.apache.commons.math.complex - complex numbers
                  8. org.apache.commons.math.distribution - probability distributions
                  9. org.apache.commons.math.fraction - rational numbers
                  10. org.apache.commons.math.transform - transform methods (Fast Fourier)
                  11. org.apache.commons.math.geometry - 3D geometry (vectors and rotations)
                  12. org.apache.commons.math.optimization - function maximization or minimization
                  13. org.apache.commons.math.ode - Ordinary Differential Equations integration
                  14. org.apache.commons.math.genetics - Genetic Algorithms
                  Package javadocs are here

                  You should always read the javadoc class and method comments carefully when using Commons Math components in your programs. The javadoc provides references to the algorithms that are used, usage notes about limitations, performance, etc. as well as interface contracts. Interface contracts are specified in terms of preconditions (what has to be true in order for the method to return valid results), special values returned (e.g. Double.NaN) or exceptions that may be thrown if the preconditions are not met, and definitions for returned values/objects or state changes.

                  When the actual parameters provided to a method or the internal state of an object make a computation meaningless, an IllegalArgumentException or IllegalStateException may be thrown. Exact conditions under which runtime exceptions (and any other exceptions) are thrown are specified in the javadoc method comments. In some cases, to be consistent with the IEEE 754 standard for floating point arithmetic and with java.lang.Math, Commons Math methods return Double.NaN values. Conditions under which Double.NaN or other special values are returned are fully specified in the javadoc method comments.

                  As of version 2.2, the policy for dealing with null references is as follows: When an argument is unexpectedly null, a NullArgumentException is raised for signalling the illegal argument. Note that this class does not inherit from the standard NullPointerException but is a subclass of IllegalArgumentException. No NullPointerException should be propagated from within Commons-Math.

                  Commons Math requires JDK 1.5+ and has no runtime dependencies.

                  Commons Math is distributed under the terms of the Apache License, Version 2.0: .

                  This product includes software developed by the University of Chicago, as Operator of Argonne National Laboratory. This corresponds to software translated from the lmder, lmpar and qrsolv Fortran routines from the Minpack package and distributed under the following disclaimer: .

                  This product includes software translated from the odex Fortran routine developed by E. Hairer and G. Wanner and distributed under the following license: .

                  This product includes software translated from some LAPACK Fortran routines and distributed under the following license: .

                  commons-math-2.2-src/src/site/xdoc/userguide/distribution.xml100644 1750 1750 12461 11532241247 23247 0ustarlucluc 0 0 The Commons Math User Guide - Distributions

                  The distributions package provide a framework for some commonly used probability distributions.

                  The distribution framework provides the means to compute probability density function (PDF) probabilities and cumulative distribution function (CDF) probabilities for common probability distributions. Along with the direct computation of PDF and CDF probabilities, the framework also allows for the computation of inverse PDF and inverse CDF values.

                  Using a distribution object, PDF and CDF probabilities are easily computed using the cumulativeProbability methods. For a distribution X, and a domain value, x, cumulativeProbability computes P(X <= x) (i.e. the lower tail probability of X).

                  TDistribution t = new TDistributionImpl(29); double lowerTail = t.cumulativeProbability(-2.656); // P(T <= -2.656) double upperTail = 1.0 - t.cumulativeProbability(2.75); // P(T >= 2.75)

                  The inverse PDF and CDF values are just as easily computed using the inverseCumulativeProbability methods. For a distribution X, and a probability, p, inverseCumulativeProbability computes the domain value x, such that:

                  • P(X <= x) = p, for continuous distributions
                  • P(X <= x) <= p, for discrete distributions
                  Notice the different cases for continuous and discrete distributions. This is the result of PDFs not being invertible functions. As such, for discrete distributions, an exact domain value can not be returned. Only the "best" domain value. For Commons-Math, the "best" domain value is determined by the largest domain value whose cumulative probability is less-than or equal to the given probability.

                  Since there are numerous distributions and Commons-Math only directly supports a handful, it may be necessary to extend the distribution framework to satisfy individual needs. It is recommended that the Distribution, ContinuousDistribution, DiscreteDistribution, and IntegerDistribution interfaces serve as base types for any extension. These serve as the basis for all the distributions directly supported by Commons-Math and using those interfaces for implementation purposes will ensure any extension is compatible with the remainder of Commons-Math. To aid in implementing a distribution extension, the AbstractDistribution, AbstractContinuousDistribution, and AbstractIntegerDistribution provide implementation building blocks and offer basic distribution functionality. By extending these abstract classes directly, much of the repetitive distribution implementation is already developed and should save time and effor in developing user-defined distributions.

                  commons-math-2.2-src/src/site/xdoc/userguide/special.xml100644 1750 1750 7046 11532241247 22133 0ustarlucluc 0 0 The Commons Math User Guide - Special Functions

                  The special functions portion of Commons-Math contains several useful functions not provided by java.lang.Math. These functions mostly serve as building blocks for other portions of Commons-Math but, as others may find them useful as stand-alone methods, these special functions were included as part of the Commons-Math public API.

                  Erf contains several useful functions involving the Error Function, Erf.
                  FunctionMethodReference
                  Error FunctionerfSee Erf from MathWorld

                  Gamma contains several useful functions involving the Gamma Function.
                  FunctionMethodReference
                  Log GammalogGammaSee Gamma Function from MathWorld
                  Regularized GammaregularizedGammaPSee Regularized Gamma Function from MathWorld

                  Beta contains several useful functions involving the Beta Function.
                  FunctionMethodReference
                  Log BetalogBetaSee Beta Function from MathWorld
                  Regularized BetaregularizedBetaSee Regularized Beta Function from MathWorld

                  commons-math-2.2-src/src/site/xdoc/index.xml100644 1750 1750 5352 11532241247 17624 0ustarlucluc 0 0 Commons-Math: The Apache Commons Mathematics Library

                  Commons Math is a library of lightweight, self-contained mathematics and statistics components addressing the most common problems not available in the Java programming language or Commons Lang.

                  Guiding principles:

                  1. Real-world application use cases determine development priority.
                  2. This package emphasizes small, easily integrated components rather than large libraries with complex dependencies and configurations.
                  3. All algorithms are fully documented and follow generally accepted best practices.
                  4. In situations where multiple standard algorithms exist, a Strategy pattern is used to support multiple implementations.
                  5. Limited dependencies. No external dependencies beyond Commons components and the core Java platform (at least Java 1.3 up to version 1.2 of the library, at least Java 5 starting with version 2.0 of the library).

                  Download the Latest Release of Commons Math.

                  commons-math-2.2-src/src/site/xdoc/download_math.xml100644 1750 1750 15224 11532241247 21354 0ustarlucluc 0 0 Download Commons Math Commons Documentation Team

                  We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

                  You are currently using [preferred]. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

                  [if-any logo][end]

                  Other mirrors:

                  The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

                  commons-math-2.2.tar.gz md5 pgp
                  commons-math-2.2.zip md5 pgp
                  commons-math-2.2-src.tar.gz md5 pgp
                  commons-math-2.2-src.zip md5 pgp

                  Older releases can be obtained from the archives.

                  commons-math-2.2-src/src/site/xdoc/developers.xml100644 1750 1750 33337 11532241247 20711 0ustarlucluc 0 0 Developers Guide Robert Burrell Donkin

                  Creating and maintaining a mathematical and statistical library that is accurate requires a greater degree of communication than might be the case for other components. It is important that developers follow guidelines laid down by the community to ensure that the code they create can be successfully maintained by others.

                  Developers are asked to comply with the following development guidelines. Code that does not comply with the guidelines including the word must will not be committed. Our aim will be to fix all of the exceptions to the "should" guidelines prior to a release.

                  Getting Started

                  1. Start by reviewing the overall objectives stated in the proposal upon which the project is founded.
                  2. Download the commons math source code. Follow the instructions under the heading "Anonymous Subversion" on the Apache version control page (Also have a look at the Commons wiki svn page ) to check out the commons math code base from Subversion. The svn url for the current development sources of commons-math is https://svn.apache.org/repos/asf/commons/proper/math/trunk
                  3. Like most commons components, commons-math uses Apache Maven as our build tool. We now use Maven 2 as our primary build platform (what we use to cut releases, for continuous integration builds, and for development). The sources can also be built using Ant (a working Ant build.xml is included in the top level project directory). To build commons math using Maven 2, you can follow the instructions for Building a project with Maven 2. Launch Maven from the top-level directory in the checkout of commons-math trunk. No special setup is required, except that currently to build the site (i.e. to execute Maven's "site" goal), you may need to increase the default memory allocation (e.g. export MAVEN_OPTS=-Xmx512m) before launching Maven.
                  4. Have a look at the new features that users and developers have requested on the Math Wish List Wiki Page.
                  5. Be sure to join the commons-dev and commons-user email lists and use them appropriately (make sure the string "[math]" starts the Subject line of all your postings). Make any proposals here where the group can comment on them.
                  6. Setup an account on JIRA and use it to submit patches and identify bugs. Read the directions for submitting bugs and search the database to determine if an issue exists or has already been dealt with.

                    See the Commons Math Issue Tracking Page for more information on how to search for or submit bugs or enhancement requests.

                  7. Generating patches: The requested format for generating patches is the Unified Diff format, which can be easily generated using the svn client or various IDEs. svn diff > patch

                  Contributing ideas and code

                  Follow the steps below when making suggestions for additions or enhancements to commons-math. This will make it easier for the community to comment on your ideas and for the committers to keep track of them. Thanks in advance!

                  1. Start with a post to the commons-dev mailing list, with [math] at the beginning of the subject line, followed by a good, short title describing the new feature or enhancement. For example, "[math] Principal Components Analysis." The body of the post should include each of the following items (but be as brief as possible):
                    • A concise description of the new feature / enhancement
                    • References to definitions and algorithms. Using standard definitions and algorithms makes communication much easier and will greatly increase the chances that we will accept the code / idea
                    • Some indication of why the addition / enhancement is practically useful
                  2. Assuming a generally favorable response to the idea on commons-dev, the next step is to add an entry to the Math Wish List corresponding to the idea. Include a reference to the discussion thread and, for substantial enhancements, a new Wiki page named using the enhancement / addition name, e.g. "PrincipalComponentsAnalysis." We can then us this page to lay out the development plan and track progress and decisions related to the feature.
                  3. Create a JIRA ticket using the the feature title as the short description. Incorporate feedback from the initial posting in the description. Add a reference to the JIRA ticket to the WishList entry.
                  4. Submit code as attachments to the JIRA ticket. Please use one ticket for each feature, adding multiple patches to the ticket as necessary. Use the svn diff command to generate your patches as diffs. Please do not submit modified copies of existing java files. Be patient (but not too patient) with committers reviewing patches. Post a *nudge* message to commons-dev with a reference to the ticket if a patch goes more than a few days with no comment or commit.

                  Commons-math follows Code Conventions for the Java Programming Language. As part of the maven build process, style checking is performed using the Checkstyle plugin, using the properties specified in checkstyle.xml. Committed code should generate no Checkstyle errors. One thing that Checkstyle will complain about is tabs included in the source code. Please make sure to set your IDE or editor to use spaces instead of tabs.

                  Committers should make sure that svn properties are correctly set on files added to the repository. See the section on Committer Subversion Access on the Apache Source Code Repositories page.

                  • Committed code must include full javadoc.
                  • All component contracts must be fully specified in the javadoc class, interface or method comments, including specification of acceptable ranges of values, exceptions or special return values.
                  • External references or full statements of definitions for all mathematical terms used in component documentation must be provided.
                  • Implementations should use standard algorithms and references or full descriptions of all algorithms should be provided.
                  • Additions and enhancements should include updates to the User Guide.
                  • Committed code must include unit tests.
                  • Unit tests should provide full path coverage.
                  • Unit tests should verify all boundary conditions specified in interface contracts, including verification that exceptions are thrown or special values (e.g. Double.NaN, Double.Infinity) are returned as expected.
                  • All new source file submissions must include the Apache Software License in a comment that begins the file
                  • All contributions must comply with the terms of the Apache Contributor License Agreement (CLA)
                  • Patches must be accompanied by a clear reference to a "source" - if code has been "ported" from another language, clearly state the source of the original implementation. If the "expression" of a given algorithm is derivative, please note the original source (textbook, paper, etc.).
                  • References to source materials covered by restrictive proprietary licenses should be avoided. In particular, contributions should not implement or include references to algorithms in Numerical Recipes (NR). Any questions about copyright or patent issues should be raised on the commons-dev mailing list before contributing or committing code.

                  Here is a list of relevant materials. Much of the discussion surrounding the development of this component will refer to the various sources listed below, and frequently the Javadoc for a particular class or interface will link to a definition contained in these documents.

                  Concerning floating point arithmetic.
                  http://www.validlab.com/goldberg/paper.ps
                  http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps
                  http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf
                  Numerical analysis
                  Scientific Computing FAQ @ Mathcom
                  Bibliography of accuracy and stability of numerical algorithms
                  SUNY Stony Brook numerical methods page
                  SIAM Journal of Numerical Analysis Online
                  Probability and statistics
                  Statlib at CMU
                  NIST Engineering Statistics Handbook
                  Online Introductory Statistics (David W. Stockburger)
                  Online Journal of Statistical Software
                  References for mathematical definitions.
                  http://rd11.web.cern.ch/RD11/rkb/titleA.html
                  http://mathworld.wolfram.com/
                  http://www.itl.nist.gov/div898/handbook
                  Chan, T. F. and J. G. Lewis 1979, Communications of the ACM, vol. 22 no. 9, pp. 526-531.
                  XML related resources.
                  http://www.openmath.org
                  commons-math-2.2-src/src/site/xdoc/proposal.xml100644 1750 1750 12443 11532241247 20373 0ustarlucluc 0 0 Proposal for math Package Robert Burrell Donkin

                  The Java programming language and the math extensions in commons-lang provide implementations for only the most basic mathematical algorithms. Routine development tasks such as computing basic statistics or solving a system of linear equations require components not available in java or commons-lang.

                  Most basic mathematical or statistical algorithms are available in open source implementations, but to assemble a simple set of capabilities one has to use multiple libraries, many of which have more restrictive licensing terms than the ASF. In addition, many of the best open source implementations (e.g. the R statistical package) are either not available in Java or require large support libraries and/or external dependencies to work.

                  A commons-math community will provide a productive environment for aggregation, testing and support of efficient Java implementations of commonly used mathematical and statistical algorithms.

                  The Math project shall create and maintain a library of lightweight, self-contained mathematics and statistics components addressing the most common practical problems not immediately available in the Java programming language or commons-lang. The guiding principles for commons-math will be:

                  1. Real-world application use cases determine priority
                  2. Emphasis on small, easily integrated components rather than large libraries with complex dependencies
                  3. All algorithms are fully documented and follow generally accepted best practices
                  4. In situations where multiple standard algorithms exist, use the Strategy pattern to support multiple implementations
                  5. Limited dependencies. No external dependencies beyond Commons components and the JDK

                  math relies only on standard JDK 1.2 (or later) APIs for production deployment. It utilizes the JUnit unit testing framework for developing and executing unit tests, but this is of interest only to developers of the component.

                  No external configuration files are utilized.

                  The initial codebase will consist of implementations of basic statistical algorithms such as the following:

                  • Simple univariate statistics (mean, standard deviation, n, confidence intervals)
                  • Frequency distributions
                  • t-test, chi-square test
                  • Random numbers from Gaussian, Exponential, Poisson distributions
                  • Random sampling/resampling
                  • Bivariate regression, corellation
                  and mathematical algorithms such as the following:
                  • Basic Complex Number representation with algebraic operations
                  • Newton's method for finding roots
                  • Binomial coefficients
                  • Exponential growth and decay (set up for financial applications)
                  • Polynomial Interpolation (curve fitting)
                  • Basic Matrix representation with algebraic operations

                  The proposed package name for the new component is org.apache.commons.math.

                  • CVS Repository - New directory math in the jakarta-commons CVS repository.
                  • Mailing List - Discussions will take place on the general dev@commons.apache.org mailing list. To help list subscribers identify messages of interest, it is suggested that the message subject of messages about this component be prefixed with [math].
                  • Bugzilla - New component "math" under the "Commons" product category, with appropriate version identifiers as needed.
                  • Jyve FAQ - New category "commons-math" (when available).

                  The initial committers on the math component shall be:

                  commons-math-2.2-src/src/site/xdoc/mail-lists.xml100644 1750 1750 22220 11532241247 20604 0ustarlucluc 0 0 Commons Math Mailing Lists Commons Documentation Team

                  Commons Math shares mailing lists with all the other Commons Components. To make it easier for people to only read messages related to components they are interested in, the convention in Commons is to prefix the subject line of messages with the component's name, for example:

                  • [math] Problem with the ...

                  Questions related to the usage of Commons Math should be posted to the User List.
                  The Developer List is for questions and discussion related to the development of Commons Math.
                  Please do not cross-post; developers are also subscribed to the user list.

                  Note: please don't send patches or attachments to any of the mailing lists. Patches are best handled via the Issue Tracking system. Otherwise, please upload the file to a public server and include the URL in the mail.

                  Please prefix the subject line of any messages for Commons Math with [math] - thanks!

                  Name Subscribe Unsubscribe Post Archive Other Archives
                  Commons User List

                  Questions on using Commons Math.

                  Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
                  www.mail-archive.com
                  news.gmane.org
                  Commons Developer List

                  Discussion of development of Commons Math.

                  Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
                  www.mail-archive.com
                  news.gmane.org
                  Commons Issues List

                  Only for e-mails automatically generated by the issue tracking system.

                  Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
                  www.mail-archive.com
                  Commons Commits List

                  Only for e-mails automatically generated by the source control sytem.

                  Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
                  www.mail-archive.com

                  Other mailing lists which you may find useful include:

                  Name Subscribe Unsubscribe Post Archive Other Archives
                  Apache Announce List

                  General announcements of Apache project releases.

                  Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
                  old.nabble.com
                  www.mail-archive.com
                  news.gmane.org
                  commons-math-2.2-src/src/site/xdoc/changes.xml100644 1750 1750 215031 11532241247 20162 0ustarlucluc 0 0 Commons Math Release Notes TestUtils is thread-hostile. Deprecate the getters and setters. FastMath is not an exact replacement for StrictMath (partially fixed) added scalb(double, int), scalb(float, int) FastMath is not an exact replacement for StrictMath (partially fixed) added hypot(double, double), nextAfter(double, double) and nextAfter(float,double) (beware of the strange double second argument) so that they handle special values in the way as StrictMath FastMath is not an exact replacement for StrictMath (partially fixed) added getExponent(double) and getExponent(float) FastMath is not an exact replacement for StrictMath (partially fixed) Add copySign(double), copySign(float) FastMath atan2 does not agree with StrictMath for special cases FastMath acos fails when input abs value is less than about 5.7851920321187236E-300 - returns NaN separate discrete event detection from adaptive step size handling in ODE solvers, thus improving robustness, maintainability and speed FastMath toRadian and toDegree don't handle large double numbers well FastMath does not handle all special cases correctly Fix ulp(Infinity) to return Infinity rather than NaN FastMath.signum(-0.0) does not agree with Math.signum(-0.0) FastMath is not an exact replacement for StrictMath (partially fixed) Add signum(float), ulp(float) MathUtils.equals(double, double) does not work properly for floats - add equivalent (float, float) methods and basic tests FastMath.max(50.0f, -50.0f) => -50.0f; should be +50.0f Fixed FastMath.max(float, float) so it returns correct value. Fixed an awkward statement that triggered a false positive warning. Added complementary error function, erfc. Modified erf (and erfc) to return extreme values for x with abs(x) > 40. For these arguments, the true value is indistinguishable from an extrema as a double. Added characteristic support to distributions, including methods to return numerical estimates of the mean and variance and upper and lower bounds of support. In version 2.2, methods returning distribution characteristics have been added only to the implementation classes. In version 3, supporting methods have been added to the abstract base classes and distribution interfaces. Added a constructor and addValues(double[]) methods allowing DescriptiveStatistics to be initialized with values from a double[] array. Similarly enhanced ResizeableDoubleArray. Added a getUniqueCount() method to Frequency to return the number of unique values included in the frequency table. Modified NormalDistributionImpl.cumulativeProbability to return 0 or 1, respectively for values more than 40 standard deviations from the mean. For these values, the actual probability is indistinguishable from 0 or 1 as a double. Top coding improves performance for extreme values and prevents convergence exceptions. Added toString() override to StatisticalSummaryValues. Deprecated the whole ode.jacobians package. It is clumsy and difficult to use. It will be replaced by a completely rewritten implementation in 3.0, which will be more tightly bound to the top level ode package Added a normalization feature to transform samples so they have zero mean and unit standard deviation Created "MathUserException" class to convey cause of failure between layers of user code separated by a layer of Commons-Math code. Fixed k-means++ to add several strategies to deal with empty clusters that may appear during iterations Improved Percentile performance by using a selection algorithm instead of a complete sort, and by allowing caching data array and pivots when several different percentiles are desired Fixed an error preventing zero length vectors to be built by some constructors Fixed an error preventing ODE solvers to be restarted after they have been stopped by a discrete event Added new random number generators from the Well Equidistributed Long-period Linear (WELL). Made intercept / no intercept configurable in multiple regression classes. By default, regression models are estimated with an intercept term. When the "noIntercept" property is set to true, regression models are estimated without intercepts. Fixed lost cause in MathRuntimeException.createInternalError. Note that the message is still the default message for internal errors asking to report a bug to commons-math JIRA tracker. In order to retrieve the message from the root cause, one has to get the cause itself by getCause(). Modified multiple regression newSample methods to ensure that by default in all cases, regression models are estimated with intercept terms. Prior to the fix for this issue, newXSampleData(double[][]), newSampleData(double[], double[][]) and newSampleData(double[], double[][], double[][]) all required columns of "1's" to be inserted into the x[][] arrays to create a model with an intercept term; while newSampleData(double[], int, int) created a model including an intercept term without requiring the unitary column. All methods have been changed to eliminate the need for users to add unitary columns to specify regression models. Users of OLSMultipleLinearRegression or GLSMultipleLinearRegression versions 2.0 or 2.1 should either verify that their code either does not use the first set of data loading methods above or set the noIntercept property to true on estimated models to get the previous behavior. Added the dfp library providing arbitrary precision floating point computation in the spirit of IEEE 854-1987 (not exactly as it uses base 1000 instead of base 10). In addition to finite numbers, infinities and NaNs are available (but there are no subnormals). All IEEE 854-1987 rounding modes and signaling flags are supported. The available operations are +, -, *, / and the available functions are sqrt, sin, cos, tan, asin, acos, atan, exp, log. Added faster and more accurate version of traditional mathematical functions in a FastMath class intended to be a drop-in replacement for java.util.Math at source-level. Some functions still directly delegates to Math but this will improve with time. Some functions like exp may be twice as fast (even 3 times faster on some processors). Sine, cosine or power functions show typical speedups of 1.5 times faster or more. Added R-squared and adjusted R-squared statistics to OLSMultipleLinearRegression. Corrected the formula used for Y variance returned by calculateYVariance and associated methods in multiple regression classes (AbstractMultipleLinearRegression, OLSMultipleLinearRegression, GLSMultipleLinearRegression). These methods previously returned estimates of the variance in the model error term. New "calulateErrorVariance" methods have been added to compute what was previously returned by calculateYVariance. Bug fixed in Levenberg-Marquardt (handling of weights). Bug fixed in Levenberg-Marquardt (consistency of current). Bug fixed in chi-square computation in AbstractLeastSquaresOptimizer. Added support for Gaussian curve fitting. Fixed several bugs in "BrentOptimizer". Fixed inconsistency in return values in "MultiStartUnivariateRealOptimizer". Added a feature allowing error estimation to be computed only on a subset of Ordinary Differential Equations, considered as the main set, the remaining equations being considered only as an extension set that should not influence the ODE integration algorithm Fixed bug in precondition check (method "setMicrosphereElements"). Created "MultidimensionalCounter" class. Created package "exception" to contain the new exceptions hierarchy. Created package "exception.util": utilities for the exception classes (e.g. managing the localization of error messages). Default policy for dealing with invalid null references: raise a "NullArgumentException" (subclass of "IllegalArgumentException"). Implementation of linear interpolation. Improved localization of error messages. Allow multiple optimizations with a default simplex. Added new "equalsIncludingNaN" methods that have the same semantics as the old "equals" methods. The semantics of the old methods will be modified (in the next major release) such that NaNs are not considered equal (to be more compliant with IEEE754). Added a setQRRankingThreshold method to Levenberg-Marquardt optimizer to improve robustness of rank determination. Added random data generation methods to RandomDataImpl for the remaining distributions in the distributions package. Added a generic nextInversionDeviate method that takes a discrete or continuous distribution as argument and generates a random deviate from the distribution. Also added sampling methods based on the implementations in RandomDataImpl to distributions. Fixed Levenberg-Marquardt optimizer that did not use the vectorial convergence checker. Now this optimizer can use either the general vectorial convergence checker or its own specialized convergence settings. Fixed loss of significance error in PersonsCorrelation p-value computation causing p-values smaller than the machine epsilon (~1E-16) to be reported as 0. Fix NullPointerException in BisectionSolver.solve(f, min, max, initial) Fix spelling of getSparcity [sic] method of OpenMapRealVector Fix problem with the default sparseIterator when a RealVector has exactly one non-zero entry Implementation of tricubic interpolation. Deprecated SmoothingBicubicSplineInterpolator and SmoothingBicubicSplineInterpolatorTest. Added BicubicSplineInterpolator and BicubicSplineInterpolatorTest. Added SmoothingPolynomialBicubicSplineInterpolator and SmoothingPolynomialBicubicSplineInterpolatorTest. Added method to clear the list of observations in PolynomialFitter. Fix use of wrong variable in SmoothingBicubicSplineInterpolatorTest.testPreconditions() Added method to clear the list of observations in CurveFitter. Implementation of bicubic interpolation. Added density functions to remaining continuous distributions (F, T, Weibull, Cauchy). As of Math 2.1, all continuous distributions implement density functions. The HasDensity interface has been deprecated and in version 3.0, density(double) will be added to the ContinuousDistribution interface. Changed equals() methods to use instanceof check rather than catching ClassCastException; this also allows some null checks to be omitted. Removed unnecessary null checks in equals methods. Fraction.hashCode() implementation was not fully consistent with Fraction.equals(). Changed hashCode() to use fields directly to agree with equals(). Resolved multiple problems leading to inaccuracy and/or failure to compute Normal, ChiSquare and Poisson probabilities, Erf and Gamma functions. Made Brent solver absolute accuracy configurable for all continuous distributions. Fixed too stringent interval check in Brent solver: initial guess is now allowed to be at either interval end Added a way to compute both the final state in an Initial Value Problem (IVP) for Ordinary Differential Equations (ODE) and its derivatives with respect to initial state and with respect to some problem parameters. This allows wrapping ODE solvers into optimization or root finding algorithms, which in turn can be used to solve Boundary Value Problems (BVP). There are no implementations (yet) of BVP solvers in the library. Fixed an error in events handling in ODE solvers. In some rare cases, events occurring close to a step start were handled without truncating the step, making them appear as is they occurred close to the step end Fixed a problem with getInterpolatedDerivatives returning zero derivatives when an ODE step handler is configured to not use interpolation. It now returns a constant but non-zero value consistent with at least one point inside the step Fixed wrong return values when enpoints are roots in Brent solver with a user provided initial guess Fixed a missing bracketing check of initial interval in Brent solver. In SVD, the matrices passed to EigenDecomposition are now symmetric by construction (rather than simply by definition). In EigenDecomposition, once the tridiagonal form is obtained, the non-significant elements are set to 0. A EigenDecompositionImpl simplified makes it possible to compute the SVD of a singular matrix (with the right number of elements in the diagonal matrix) or a matrix with singular value(s) of multiplicity greater than 1. Added SemiVariance statistic. Added a warning in the getCoefficients method documentation for PolynomialFunctionLagrangeForm. Computation may be ill-conditioned so this method should be used with care. Fixed an error in BigFraction multiplication for large numerators that don't fit in a primitive int. Fixed a spurious exception in EigenDecompositionImpl when a 3x3 block had two identical eigenvalues. Added min/max getters for real vectors (not yet in the RealVector interface for compatibility purposes, but in the AbstractRealVector abstract class). Fixed automatic step initialization in embedded Runge-Kutta integrators. The relative tolerance setting was never used, only the absolute tolerance was used. Fixed regression in Frequency.getPct(Object) introduced in 2.0. Cumulative percent was being returned for Object arguments in place of percent. Singular Value Decomposition now computes either the compact SVD (using only positive singular values) or truncated SVD (using a user-specified maximal number of singular values). Fixed Singular Value Decomposition solving of singular systems. Added MathUtils methods to compute gcd and lcm for long arguments. Added support for weighted univariate statistics. Fixed a wrong implementation of the Linf norm in vectors. Fixed a convergence discrepancy with respect to theory in Gragg-Bulirsch-Stoer integrator. Fixed a wrong dimension check in SVD solver. Added composition features for real functions. Added mapping and iteration methods to vectors. Provided a default implementation for the numerous simple methods in the RealVectorInterface. Fixed an error in handling very close events in ODE integration. Fixed an overflow error in MathUtils.distance that was causing KMeansPlusPlusClusterer to fail with a NullPointerException when component distances between points exceeded Integer.MAXVALUE. Added generationsEvolved property to GeneticAlgorithm to track the number of generations evolved by the evolve() method before reaching the StoppingCondition. Fixed an index computation error in eigen decomposition. Once again, kudos to Dimitri for debugging this. Fixed an ArrayIndexOutOfBoundsException in eigen decomposition. Kudos to Dimitri for debugging this, it was really difficult. Fixed parameter test in RandomDataImpl#nextExponential. The method now throws IllegalArgumentException for mean = 0. Changed probability calculations for Binomial, Poisson, and Hypergeometric distributions to use Catherine Loader's saddle point approximations. Removed dead code from Complex#divide. Fixed implementation of RandomDataImpl#nextPoisson by implementing an alternative algorithm for large means. Added support for multidimensional interpolation using the robust microsphere algorithm. Fixed implementation of EmpiricalDistributionImpl#getUpperBounds to match interface contract. Added getGeneratorUpperBounds method to EmpiricalDistributionImpl providing previous behavior. Fixed wrong results on Loess interpolation, also added a way to set weights for smoothing and to ignore zero weights for coefficients computation Fixed a OutOfBoundException in simplex solver when some constraints are tight. Fixed misleading number formats in error messages for adaptive stepsize integrators. Added support for weighted descriptive statistics. Added normalizeArray method to MathUtils. Fixed a NullPointerException in simplex solver when no solution is possible and some constraints are negative. Removed an unused argument in a private method in simplex solver. Fixed an error induced by entries set to 0 in simplex solver. Fixed an error leading the simplex solver to compute the right solution but return another one. Prevent infinite loops in multi-directional direct optimization method when the start point is exactly at the optimal point. Prevent possible zero divides on eigenvectors of indefinite matrices Fixed an error in RealMatrix javadoc Added an implementation of the Mersenne twister pseudo random number generator from Makoto Matsumoto and Takuji Nishimura Changed the return type of the various interpolation algorithms to the specific implementation of UnivariateRealFunction each one uses The behavior of the bracket method in UnivariateRealSolverUtils has been changed to return successfully when a tentative bracketing interval has a root exactly at one of its end points. Previously, such intervals triggered an exception. Added a check for too few rows with respect to the number of predictors in linear regression Added a getCovariance method to singular value decomposition Added robust locally weighted regression (Loess). Added a scalar multiply to the Complex class Added curve fitting with a general case and two specific cases (polynomial and harmonic). Optimized Complex isNaN(), isInfinite() by moving computation to constructor. Added Genetic Algorithm implementation. Fixed detection of not positive definite matrices in Cholesky decomposition Fixed a wrong check for basic variables Fixed a problem when setting some variables (several variables were set instead of only one) Added a way to limit the number of functions evaluations in optimizers (the number of iterations could already be limited) Added digamma function. Added Spearman's rank correlation (SpearmansCorrelation). Added support for rank transformations. Completed internationalization of all error messages Added a clustering package with an implementation of the k-means++ algorithm Added distance1, distance and distanceInf utility methods for double and int arrays in MathUtils Added an utility equality method between double numbers using tolerance in ulps (Units in Last Position) Added getNorm1, getNormInf, distance1 and distanceInf to the Vector3D class Added support for any type of field in linear algebra (FielxMatrix, FieldVector, FieldLUDecomposition) The RealMatrixImpl implementation classes has been renamed Array2DRowRealMatrix to reflect its specificities and for consistency with the new implementations. The previous name is still available but is deprecated Added a block-based storage type for dense matrices improving speed for large dimensions Added AggregateSummaryStatistics class to support aggregation of SummaryStatistics. Added general Field and FieldElement interfaces to allow generic algorithms to operate on fields. The library already provides several implementations: Complex, Fraction, BigFraction and BigReal Fixed inconsistent access to multidimensional array in FastFourierTransformer Greatly improved multiplication speed for sparse matrices Fixed threading issues with MathException and MathRuntimeException Fixed threading issues with UnivariateRealSolverUtils factory Reduced visibility of MessagesResources_fr.contents field to private Added Fraction.toString() Added add/subtract/multiply/divide functions with integer parameters to Fraction Added some utility functions to compute powers with integral types (int, long, BigInteger). Fixed a comparison error when two different fractions evaluate to the same double due to limited precision. Added a BigFraction class that does not overflow when big numerators or denominators are used. Added an optimizer for constrained linear problems based on 2-phases standard simplex. Redesigned the optimization framework for a simpler yet more powerful API. Added non-linear conjugate gradient optimizer. Fixed an error in computing gcd and lcm for some extreme values at integer range boundaries. Added a MathUtils method to check equality given some error bounds. Added PearsonsCorrelation class to compute correlation matrices, standard errors and p-values for correlation coefficients. Added Covariance class to compute variance-covariance matrices in new correlation package. Improved fast Fourier transform efficiency. Added a SparseRealVector class that implements a sparse vector for the RealVector interface. Added factory methods to create Chebyshev, Hermite, Laguerre and Legendre polynomials. Added add, subtract, negate, multiply and toString methods to PolynomialFunction. Changed FractionFormat to extend NumberFormat. Forced symmetry in binomialCoefficientLog and added test cases for MathUtils. Fixed error in binomial coefficient computation. Added a Legendre-Gauss integrator. Fixed error in factorial computation for 17 <= n <= 20. Integration algorithms now can have both relative and absolute accuracy settings. Added a new univariate sub-package below the optimization package. The analysis package has been reorganized with several sub-packages. Fixed an error in gcd computation for large values. Added method to walk matrix entries with or without changing them in the visitor design pattern sense. Three different orders can be used, row by row, column by column or optimized order according to internal storage. Optimized order should be preferred when no specific order is needed, because it will be more cache efficient. Added Fast Hadamard Transform. Added nth root computation for complex numbers. Added support for sparse matrix. Added an int/double hash map (OpenIntToDoubleHashMap) with much smaller memory overhead than standard java.util.Map (open addressing and no boxing). Added support for multi-dimensional Fourier transform. The root solvers and the integrators now take the function to solve as a parameter to the solve/integrate methods, thus allowing to reuse the same solver/integrator for different functions. Added setter methods for rows and columns in matrices. Added Frobenius matrix norm. Added an abstract matrix implementation simplifying extension by users. Added support for the Zipf distribution. Added support for copying statistics. Changes to stats classes include copy constructor, static copy(-,-) and instance copy() methods. Added copy() to UnivariateStatistic and StorelessUnivariateStatistic interfaces. Added a removal feature for observations in descriptive statistics. Added a scalb method in MathUtils. This method is similar to the method with same name added in java.lang.Math as of Java 6. Fixed F distribution inverse CDF computation for small denominator degrees of freedom. Fixed an error in CorrelatedRandomVectorGenerator leading to a component of the generated vector being constant. Greatly improved QR-decomposition speed using transposed matrices internally. Fixed an infinite loop encountered in some backward integration cases for ODE solvers. Added beta distribution. Added probability density functions computation for distributions for which it is feasible. Changed the Complex.equals() method so that it considers +0 and -0 are equal, as required by IEEE-754 standard. Added JAMA-like interfaces for eigen/singular problems. The implementation are based on the very quick dqd/dqds algorithms and some parts of the MRRR algorithm. This leads to very fast and accurate solutions. Added JAMA-like interfaces for decomposition algorithms. These interfaces decompose a matrix as a product of several other matrices with predefined properties and shapes depending on the algorithm. These algorithms allow to solve the equation A * X = B, either for an exact linear solution (LU-decomposition, Cholesky decomposition) or an exact or least-squares solution (QR-decomposition). Added removeData methods for the SimpleRegression class. This allows to support regression calculations across a sliding window of (time-based) observations without having to recalculate for the entire window every time. Support for one dimensional vectors has been added to the linear algebra package with a RealVector interface, a RealVectorImpl default implementation using a single double array to store elements and a RealVectorFormat for input/output. Changed OLS regression implementation added in MATH-203 to use QR decomposition to solve the normal equations. New ODE integrators have been added: the explicit Adams-Bashforth and implicit Adams-Moulton multistep methods. As the implementations of these methods are based on Nordsieck vector rather than a traditional array of previous steps, they both have been improved to handle adaptive stepsize. These methods provide the same rich features has the existing ones: continuous output, step handlers, discrete events, G-stop ... Replaced size adjustment of all steps of fixed steps Runge-Kutta integrators by a truncation of the last step only. The ODE integrators now support several step handlers at once, instead of just one. This is more consistent with event handlers management. The setStepHandler method has therefore been replaced by addStephandler, the getStepHandler method has been replaced by getStepHandlers which returns a Collection and a clearStepHandlers method has been added. All ODE integrators now support setting a maximal number of evaluations of differential equations function. If this number is exceeded, an exception will be thrown during integration. This can be used to prevent infinite loops if for example error control or discrete events create a really large number of extremely small steps. All step interpolators for ODE integrators now provide interpolation for both the state and its time derivatives. The interpolated derivatives are the exact derivatives of the interpolated state, thus preserving consistency. The general step handlers hence do not need to call the derivation function anymore. The fixed step handlers also get the time derivative of the state as an additional argument along with the state when they are called. Changed return type for FirstOrderIntegrator.integrate() to double in order to retrieve exact stop time. This allows to handle properly integration interruption due to an EventHandler instance asking to stop the integration when its associated event is triggered. The state was already set to the current state at interruption time, but it was difficult to get the corresponding time (it involved setting a step handler monitoring the last step specially). Events handlers in the ODE package now also provide the switching function variation (increasing/decreasing) when an event occurs Clarified the ODE package by breaking in into several sub-packages and renaming classes (SwitchingFunctions/EventHandler, SwitchingFunctionsHandler/CombinedEventsManager) Changed return type for FirstOrderIntegrator.getSwitchingFunctions() to a collection of SwitchingFunction instances. This better suits the intended use of the method and fixes a visibility error since the previous return type referenced the package private SwitchState class. Fixed dimension error on output vector for the operate method in RealMatrixImpl and BigMatrixImpl classes. The FirstOrderDifferentialEquations, FirstOrderIntegrator and FixedStepHandler interfaces now extends Serializable, allowing integrators, problems and handlers to be embedded into users Serializable classes. Added several convenience methods and constants for Vector3D and Rotation. Replaced public no argument constructors with IDENTITY or ZERO static instances for immutable classes Vector3D and Rotation. Fixed inconsistencies in the naming scheme for static fields in Vector3D and Rotation with respect to the overall library. Greatly improved RealMatrixImpl and BigMatrixImpl performances, both in terms of speed and in terms of temporary memory footprint. Added Mauro's patch to support multiple regression. Starting with version 2.0 of the library, the minimal version of the Java platform required to compile and use commons-math is Java 5. This version is widely deployed now on many systems. It brings new important features for specific mathematical developments, for example new functions (log10, cbrt, ulp, signum, cosh, sinh, tanh, hypot, expm1, log1p), autoboxing, MathContext or RoundingMode. It also brings important features for general development, for example enums, generics or annotations. Switching functions can now throw dedicated SwitchException from all their method. At upper call level, the various ODE integrators handle these new exceptions and wrap them into IntegratorException instances, hence the integrators methods signature did not change. Added the getSwitchingFunctions and clearSwitchingFunctions to the FirstOrderIntegrator interface and all its implementations Removed deprecated features. This includes the following changes. Factory-based instantiation replaced by setter injection in 1.2 in several classes have been removed. Protected fields in matrices implementations have been declared final and private. Identity factory methods moved to MatrixUtils class have been removed. Complex utilities methods that have been superseded by Complex instance methods have been removed. Fixed formula in fast cosine transformer javadoc comments. Javadoc and style fixes. Added an error detection for missing imaginary character while parsing complex string Detect numerical problems in Q.R decomposition for Levenberg-Marquardt estimator and report them appropriately Fixed several crashes in getCovariances() and guessParametersErrors() in AbstractEstimator when some parameters are bound. The methods now explicitly give result only about unbound parameters. Fixed truncation error in t-test classes for large t values. Added root checks for the endpoints. Fixed numerous warnings in test code. Use the initial guess provided by the user in BrentSolver.solve(), thus improving speed. Added the estimation, optimization, geometry and ode packages from the Mantissa library. Made ComplexFormat format double values with a provided NumberFormat instance instead of using the real part format for all values. Added Pascal distribution implementation. Added QR Decomposition. Modified ProperFractionFormat to reject embedded minus signs. Added a nextAfter method in MathUtils to return the next machine-representable number in a specified direction from a given floating point number. Used this to ensure that MathUtils.round does not return incorrect results for numbers with bad IEEE754 representations. Added Fast Fourier Transform implementation. Modified getSumSquaredErrors method in SimpleRegression to always return a non-negative result. Corrected nextInt and nextLong to handle wide value ranges. Increased default precision of Gamma and Beta functions. Added log function to MathUtils. Added two sample (binned comparison) ChiSquare test. Modified NormalDistributionImpl.cumulativeProbablity to catch MaxIterationsExceededException and return 0 or 1, resp. if the argument is more than 20 standard deviations from the mean. Added SynchronizedDescriptiveStatistics class. Added addAndCheck, mulAndCheck, and subAndCheck MathUtils methods for long integer arguments. Merged most functions from ComplexUtils into Complex class, added static factory method to Complex. Deprecated abstract factory methods and made DescriptiveStatistics and and SummaryStatistics concrete classes. Pushed implementations up from DescriptiveStatisticsImpl, SummaryStatisticsImpl. Made implementations of statistics configurable via setters. Changed Mean.evaluate() to use a two-pass algorithm, improving accuracy by exploiting the the fact that this method has access to the full array of data values. Added check and rescaling of expected counts to sum to sum of expected counts if necessary in ChiSquare test. Handle multiplication of Complex numbers with infinite parts specially. Add errors guessing to least-squares estimators. Add tests for Fraction constructor using double parameter. Added one-way ANOVA implementation. Add Fraction constructor using max denominator value. Add integer overflow checks in Fraction constructor using double parameter. Throw EOFException when using empty files with ValueServer in replay and digest modes. Added a equals and hash methods in MathUtils to check for double arrays Added an angle normalization method in MathUtils to force angles in some user-defined interval Added vectorial covariance computation (either sample or population covariance) Added multivariate summary statistics. Added getSumOfLogs method to SummaryStatistics and made SumOfLogs instance used by GeometricMean configurable. Fixed AbstractIntegerDistribution cumulativeProbablility(-,-) to correctly handle double arguments. Made numerator and denominator final in Fraction and deprecated protected real and imaginary parts fields in Complex, making Fraction immutable and preparing Complex to become fully immutable in 2.0. Made NewtonSolver derivative field transient and implemented readObject to initialize. Made sampleStats field private and changed getUpperBounds to return a fresh copy in EmpiricalDistributionImpl. Added polar2Complex method to ComplexUtils to create Complex numbers from polar representations. Made all serialVersionUIDs private. Improved documentation and test cases related to handling of infinite and NaN values in Complex, ComplexUtils classes. Fixed incorrect NaN handling in o.a.m.s.d.rank.Min, Max Changed RealMatrixImpl.equals to use Double.doubleToLongBits to compare corresponding matrix entries. Eliminated floating point equals comparison in Percentile.evaluate. Eliminated unnecessary assignment statements in Skewness.getResult method. Synchronized getters in ResizeableDoubleArray. Eliminated unnecessary assignment statement in BisectionSolver.solve method. Implemented hashCode in the Complex class and changed the semantics of equals to make all instances with real or imaginary part NaN equal. Fixed bin index overflow problem in EmpiricalDistributionImpl. Added protection against numerical overflow and underflow in the isBracketing method. Fixed division by zero error in rounding methods. Added upper tail cumulative probability method to HypergeometricDistributionImpl. Added better handling of numerical overflow and division by zero in Complex calculations. Changed ContinuedFraction to better handle infinite convergents that resulted in divergent continued fraction evaluations. Changed rounding methods to not rely on BigDecimal conversions which was causing numerical error. Changed Fraction(double) to correctly handle near-integral arguments. Changed lcm to throw ArithmeticException (instead of returning bogus value) if the result is too large to store as an integer. Added factories for TTest, ChiSquareTest and TestUtils class with static methods to create instances and execute tests. Eliminated repeated endpoint function evalutations in BrentSolver, SecantSolver. Added setSubMatrix methods to RealMatrixImpl, BigMatrixImpl. To Preserve backward compatibility with version 1.0, these methods were not added to the RealMatrix, BigMatrix interfaces. Added createXIdentityMatrix methods to MatrixUtils and deprecated getIdentity methods in RealMatrixImpl, BigMatrixImpl. Modified RealMatrixImpl, BigMatrixImpl constructors to throw IllegalArgumentExceptions instead of ArrayIndexOutOfBounds when dimension arguments are not positive. Made PRNG pluggable for classes in the random package. Added RandomGenerator interface extracted from java.util.random and abstract implementation, AbstractRandomGenerator providing default implementations of methods based on nextDouble(). Added a constructor taking a RandomGenerator as an argument to RandomDataImpl. Changed ValueServer to use a RandomData in its constructor. Changes to 1.0 classes should be backward compatible (including serialization). Added utility methods for overflow-checked integer arithmetic and improved gcd method in MathUtils. Fixed error in TTestImpl.homoscedasticTtest. Implementation was incorrectly using heteroscedastic t statistic. Also improved sensitivity of test cases. Fixed javadoc errors. One-sided t-test significance adjustment was reversed in javadoc for boolean-valued test methods. Fixed bug in PolynomialSplineFunction to allow evaluation of the function at the last knot point. Added Weibull distribution implementation. Added Cauchy distribution implementation. Added convenience methods for rounding. Added Fraction class based on commons-lang implementation. With the fraction class, FractionFormat and ProperFractionFormat classes were added to provide fraction formatting and parsing. commons-math-2.2-src/src/site/xdoc/issue-tracking.xml100644 1750 1750 13221 11532241247 21457 0ustarlucluc 0 0 Commons Math Issue tracking Commons Documentation Team

                  Commons Math uses ASF JIRA for tracking issues. See the Commons Math JIRA project page.

                  To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

                  If you would like to report a bug, or raise an enhancement request with Commons Math please do the following:

                  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
                  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
                  3. Decide if your issue is a bug or an enhancement.
                  4. Submit either a bug report or enhancement request.

                  Please also remember these points:

                  • the more information you provide, the better we can help you
                  • test cases are vital, particularly for any proposed enhancements
                  • the developers of Commons Math are all unpaid volunteers

                  For more information on subversion and creating patches see the Apache Contributors Guide.

                  You may also find these links useful:

                  commons-math-2.2-src/src/site/site.xml100644 1750 1750 6750 11532241404 16522 0ustarlucluc 0 0 Commons Math /images/math.gif /index.html commons-math-2.2-src/src/site/resources/userguide/estimation-class-diagram.png100644 1750 1750 47374 11532241247 26465 0ustarlucluc 0 0 PNG  IHDRdNIDATxU{9QPPA ٌ(ǀ& J^..9HF@ xo{3b7Zo:UUZ{ݪN_OrAAAAX AAC|~QX~p;eMmYovAݼy@c7nWoq~]m{]&lk][cWW_ؗ_Pe]$lՖ.\PVvΝcgfh/6+v挰tnO )a}6'vz?Ncǎ)v(ZnG[Vs!lO?9/"`C9%(F`m+P6sP6/0s-`Cz(CfygÝ5#"E Gs(7hpKU3W,_=.o{MGG.\8FxOȹ)J:vQ w'];o(C0-&S`-(Z6>Z!ls_0ϙ1w/ԗR2}:v|ض4vzg`nҤ>+^"`Q\.`[&ѭ[[CB 8ԩo8ils`6փY-o +ݨџYbEَfXY__^r2w>ۃ-X0Z VyʧN[zVժULwY\;4Y`묀>RLl;+i3Wp蒎exRӧ3#<+j}zʔJƞ<ٻN)lޢESϠ'0O4SyzϞhJ`  ˢ76xVȣ8J;:EO8L/fb;{{;\25_2- R4L`~|Rfi}H}̘70]|ݧ,wԨwn+ox~&o F|Mճ}!eYYD>x`8fN`;vLuuisvuJwc-See (b`}~}G/un^`^%xRjTF6z`|=UlG5bX'HRT8V'zOSnZ<*G`&XS~~YzG 0ԶbDVR9mzJާZWrr=??[LiYV;؞:< b=?5O]S/S6b=//Ѻ46 Aa0Th`cRAui+ *XxPD1)ѾԗJ!s(p< =KxHFQ_җ/a8=pza8ԗf0a8Ns`eN2 A&a0Wf8qNZ!LF՗ML}z\}ٞ4vvn}L,Lѳ3A̘<7ͣh@tNf`F}_.Rp%=;yKd4UZoU0fLiԗSf(!^0k}ܹ#YժY h(b˖Yj <[z*]:_6ۼy6b[ڦ],=}w_}A^ƍ*С5hKW| |w۶?}~֬@i^{]cX͚UYݺ5YJd\ڴiηY [jۿ)kݺ+\Xn vSͪTR}"]13y43`6蒿4?0iNci|2xFu^(KJofسg;((*ܹ5۷o ^re4`7n/M-?|ų+rȑquҚlڴrȄܹ_߲eۤI}mG|5acfLië/P|9:HQ$ިQϽ2_'u`D׍*i]CJyK=f/LM636j0ʕ<ޥVfźbq,|Eh]pF;$u0cGL42 f-Z4#?5jTGi`NcL>I,?4 ե^̔Xn W}?0@3`68̘<-Pr9jDbOe 4A?(Eg/^L};_>؄n 6dȳ?0K޽KmN`f]3#5\J/^T}"uO?#02+jTqaD!fsIeT6OeSG#ԩ^Į |OlqbrάCfn0;wTsFlA^lQ:0o s?f*e}tϨ.>:vѶ{lk99XhLRJ(Q3ժukIi92H\Q|\ʱRӛ AP$l1)+%jnF2~:\_p:5ڗa8ª/'=Eg0/f"fewBG5CIa6)sCS>Z gI%lRshQ3AǤ/;a6prH٤c7$%Eˈ!?qR9PhI1)\+XHI1)hQ3Asr8ؕƎT}9ؔᥱ363T҃م!r7 ce'B`cR򘔘E` A uI%.+O2=ŭ+G  A d0 T` B4cR3APtǤ A @1)<&e 0k) (BcRxL*cRejJwaSIv3401d{LJ<.IČǤ 0C] +%cR"f" d  r Ǥ1m0C_xL IOc[30C ql<&Ǥ=&0EcRxLL`! 0CY01)<&_ 4y_`V ` (JT \7{؊zxKJ08 `ԥ5߻ F] f\$V `/f\7` (Q }u} !KE_<<0CQ5z{y]7(Dfbuݿm*zn>0?b['渻n`}b?D段wByS8C?;f3?= Xm&>7030:=^c}Z`ċtxf稵s~Z@@>r^7p `v6r 0ǞYxȴN$l>U^Sff1o l;0G:u\ֺui쌌٬Uf\X;XB9(HcܲeS:-Z4a))LOgg`pq-4ǂ8ZFil Y۶-[9#cr69LWOekWcw]m4KSSy߾nݚdlqJ#`6n\Wbxblǎ Vo (P޾}>Sy>VLCz+(Z&(?PSU&E5 0̸nH9P}j ӲQ{9յef-z>"1@.;}/Cf `v7ڗAE0W˫f8Z\79^ѾDeulP,Aya۾ѾLOc3ڋY@ fLZNztVl„& }}YDhMZ0Ah q<`6.[+VhD*SU4-dL#|Y}LJ|4/>t(`uLɍ0/9#YժYҠbdFX^ͪUgYj4sTYz,ePFHbӦ|(b.h 7m߫chbP VR9>8Hf<%3 IuR^9}~cLgXѢ(KՀyax|Tk)il5_GF+\0Y [b";T4??4|(ltӣ}pnVq f}/4s[5il=yܸ!<2e=˗/կPփFŋ9iLHyLFԩ۽{رo*?_;c>4'-)}-_` [͗5kdΝ[e6iR_fcE|F{ٮ] zٲ-f `vY1k4AިQh-YźHcusZ'iU%vYf\7p ġ`Ƥ3i31WbOZ0Ah qfLZ Vpn#uʍi䚴B-#bu톈#0;;*LZa6l eVs'f\79C/5iE(rXͽLPւ9`q^f'_ǤmNcHcOcf\7`F;4v4v`t;/`q^ɍM0o;L=&?4vI^f\7p $lh_m+ilvf Bq(?&cR$*- 0Ah stBY}pnHV46  $z`h_5i:Zqd!0VvZf0V6,l5C08`CY f=# f=`6r,A93b`.7cf] |0KP޷okٲ)+R0kl EZ([\/eghY fv_,#\0Pfͪlܸ!`B93Y*%(@y_(k 0̎ 4Ѳ5kV&^$m f=4v2XbE|es46}GѢEL3}l̴y,L?9h`kƩGl>]tIV`'UY90~{ KKuWu֠],3svXXZUΝxZϪ]:۲eNP0J|=f ui1EƲU+29bDWcbPyYF3W޴㏷" F*V,J,22f+k5ɗ֭'c'0ӣ#Viveŋk͚iJZO޷o kժ+\0|c͌|gؠA؜95:ujKd7,87|6('N@8y;< jvtO7/h={>KySfG?08J>,/_F6P6sϞ=6/@`WYnn _&(LFaD=z`G4vkTj(`il.b}/E [ fqLI)kq\j0:BVYKNcij=Fl\63Ek@j04Xez2 AL&C*0փjȴL)m`&063|%Sw ̔,jF`7`_j08!RځLTח͂9h`uh P$l^{>I[~mJIw}E`4\4`u@``ޡS22q;(nf:NʦZ8vk`̽z=)e-Jj0Sm|ʔwr׮m ,R⯿×i`^Ej\]7N, )R^xq 0ǃ3/lf`ԗc;qsBM^ԗd e~ BIz0l4˱Ie~ р#fԗw⊍Qew}`_@fL\e{2 df_|IegO\a20NxExa!Xfpkxǁ EO:N/%f3KM8t`ѢEؒ%Y+zB3N,0Eue9rF 0cПрs={p0_D3/%Z~ C!j_AhhCeD 9(ZF %h?ș2fJx`C -#jOfhQ3q8PtE" р!ܗXrc  ύ G @hh0 ` 4`4`B;@;Ѐ!_$р vGƅqϷ\z)puV-(B(miԶIMImRir{UjMۺ@t8@4ȁY`c f=?0로!CYrH`>h߭nXms `k _Y 0_ԃYn[``N08@4`yy`^yK`Vlq*TխݐMxgN`>"h`|,1hu`u0ajuؔwY `VQ 0롬93`C`?Yng>r?0kl1b6Hc)U-R:@ >_:' \_0-]+Z<8P"fhb #f=|5|\9_.Rh`ΰi6y nAhNs1k_êVxrfډYܨ-6̷U[7%;nzJ(,u4FNĺYX1e'7|@@l;gZVRMf[׶-:a2}k02 aurX].ۼ0gOlml<M)X*59Xk+>)R cvNvWͺA֕y>Ie+Ve%Kfp(Gƒ\o5Oo2ÛYv:~^va{x)k)C0/n#ײkr0X~{_^Ί-jT8SYӎl6">dK>Ʒ[1[3.?IBhs4`^Wԗ+]QsO}/5hDHŚY eȑhķ+f^;G{OuySC0_=%`=I2<@Ymӿ7iԑ W6ᯟ d>N˗Dz03vfw|:iاvMS'ݧt^M`K'K3Ҿ}a*ۥMv`%5J/#}Ovjqٚ[YՎΓѽ[hZb߯f®?N55E[Ys%^W\ʼM|>Me Ӟlt`lM[]{7d Ah_U_ZxϬW )Je#0@:-Ee[Tzd+`k{W뭚t r1[/jT͗e^$`>t`!Rځ|z5em0 0c̀YB39WzmϜ 'RnwgFiܯ@ұ0/V~8s/(Lܯ AxBނq^j0;t7]ih\XI0&mc4f)-_,D-C0*e3i2f ̺Ǥ\1lx̙OKˏ?!E;zQ:P-AUe+`zVLe֧y];Q̴NhwhR׺/+瑓eafEΝ|r`=ƾ Oe}0m`+f*=O_K`y<%ΣR_V`^:-U,_=ֱM~<"jVOoXWZwGP板J:PW |t=mG9x0;Ʉ2WoC^TX#~mmįpP򨔙{~9߆NZR>׵`/ ."η=/ `?Gmsy0c5U>[2*pi Tc}L7gCq~iPm3`qhN3H`i`p̱a(=6 ŹՆ8{|Cq 0c\R­p$"CqͥGV!mr(NÈ_}Y1cf2yߡ8#x(Nr8M՗DV"frCq AhM4PZǯ_C_s:~:~W ք ` 4s0Gn9;~! v0Wt`>o3 f!Wu69s0Lc;hfe s01ٻm葽ņ` 8`fǯ9-9083 D=Sm{dktW[ W N8ut4'2lW:~}_fPw210W8wPׅvO` ,u- 8*`ytBǯ$0Cpl__㗹8+"fB-5t:iCǯ|:~ ?Ѐc ;a4̿>_;~]rP/Sn&Rǯc6tJ903 npvHawZoCǯ6tcCǯ;~EG6:~E Dn_B-s0[0ßрc渜`f;I̷a6N_g8@49܎_B :~afG 0ßFBng̘s0[ :~둽 `v% ^hv9_\c3U 0'I ;QDǯ`- ` 49;~Rǯm"85 i` 4s0[`N_3d3/808Ga(N/4H  Oqh1W!--XxylǮ{lJ!Aؿȋb9^z}!~ `EP]H\-'G.=~ 43/ Q$2>B_Ch㥚?T!?5`E.sUݸ!?5`!b1#b_@ A6 0ceWlor@3Dv#/ riG^_)ȑ?`P~ `x$rcp#ύ& Gp!4`\00Bq>Ѐq= ~ Fx!?G ǁp?<njyBh8Ak?ǁpslFx!?GMYIѻl p`8^`q$߅;.i7 ?ᱻ+L?o1 8iu}~a]ҜByKu9kU+7D"/,-[%}y:>G @O{ ]IĹdݟ<汿"b׉Q<ݸ;p0忩30Lv޿NbwhV-q\n0~d z9fKP^Cb|L~ y:>r(vIG.mx:O2y )~`vXށ=@ޮVg_X?Ю q).FrAA&/ 8n4q4`8 /}z@Ѐрq9Ahk$7p`2(> k0Y3;cf_JήXlwعղί-c d=ca6y,]K=!-J++rl=WNn]Jc%ʖM;;+[gߐa ;qL=vB[v|>d3vDws˓Z|?@2~l$cǾG:C:_'?s|i|7KƯ&<†_^~t\sk̯`dm܆< `_0* |Bϼ]4?>a'lRPN_|C7(!Ϗ8GUA#n| Pot~Wk_|UWnة۽ /PtgW o 03 Ez `ޢ VBḣ#0T>GT`>dOd0{}obWY/2TB UB4?>cgQ:=Q`aVzC6z, Nؿe7dsf9,_G}:CoqPHqyhz00oW~AܷW"9NωQ^GfG9O'ryW WX:0׃yMo` qlWY˔*oXPl3Mҿ 2%0̦ت ڇ?9Ѳ'\c⾽Y*ߠxa76@ Q>yIcٟo!m+~5Lc ?`ꇼ4v`&0__yF-P _HᢚțX} 037,sXUYخ%FynJ,lK ֿvuWz]yQ7}5i؜$߱Z{HQvWͺ,3%x|Ueyr}6n%Z:+(Nby4VRM~O=BjuY9 Ʀkm<[1a;UW1[?-I3^_7%[ѯbyiRl''| ` VNc7ݔ-xwiƼ*7=mIeWYzHoY% JxMss0+8=V7ݧyHcsQmYǡ|?<ۭ?x?[Jc+?T>biika(`/mրlQկݘm4M}Q,>c`ups|v?Fo}~m󑵷TԀycm言/צD1?Izo{ZjDU0,/M[j"f7rO6I#+{{zIF-}$?<U0(-hR?hf<JVM44n1C<~qM:]H~23ḳ^hi& 0tahz0?ܴM.̫cܔ^U`lF,n+~рY`>r1۷slu>`/c6-9oS`7^zúnX:Eez0?Gfz0_5ԗ2 ކfOm`@}Nĺ:{v1gRմf?H5/`Vח}8Cty-'>"0-e?PvrM04w,2 F({),ԗS昃9:ZփZ{6kKn!Y_c_?55svŊgٛ.#ԐjTo||vOZxz,L0_>5f`>>5f I\>LZ`?E}9T0W"ݗ_SY*0hp?0֟W/ ?pb,hڨ1̗O}*n/ej7_T[҃>a'T;RYԒ |c ߷ 'WNݦs.RGw^c+TnHM#n=a#р穭_zvg}g&%9J*`nۢO=Š`I/̽{(K`%{u9B}y+oizRCMIԃ~M+YQ?.w0IWY^?kc48;3\(^R&0G`1̉ `seC?cRӦeIe}LJHcR u}z~s?7}~9˻2 03I0sa8 |EfQM}YΊ+3 0ai}:a85>"06ԗf`!a8+ 0s Up^4sǤ 0 ?pLgD̈1C"b0 93i` |=Y!iG/ 0Pi1ca8f`!;i1c< ?! 0P/L*rbmef  X_ވrv i_lQ-3 0C64ƾ`N3il@}9.f`" é/k(k1)N/oP_0j03d+1 X/_|%%yf`"hח[/P_εP_>f}Oe 3 0CahNa81cl3 0̐`2y4z03.1#y cG`f(`0 H /'0_f`l3y4!N03 E̘ ELYb]20XLtY]-tF40ZLtYqźz1eEv߽?d0u&KuuM:m2d2u߯I_4{f]nOԵߺ3dZM]uNXnqs^g:ڜ椶lal,~ν]vl{Ssw<gl{s-?v'Ny,$i;O׹u-dC~p,]wS.ƧOEOu"@o깓&]jllG^l &L;/3q@: MLL||dm-AYY%--|}=)2,Eș|}[k~K+{]Y y%9(vւe#ĆP?WaoY ?m'-f]쁣CׅێDvZZZ;Atx|`I:XOmLw򥨬S'l'/ mL Me>fSssp;v`8y+.$Q}&ZvD 5T^Go?tg2OƦvCEeeDEcL czzFK?el]N;M~6&eNכ,MuDZXPRYpɞ1Æ'!!b``׮AA~uy'O㉳IѣY$&FOaa)6짉d"?r"#CrP;PSSws]qE2#G^@SS3{5 Hvv>AA~88_;)~̥[[BB &H rrNMPE9ONgag,ollb߾4ﰰ@#8d]i|4ᯒrN, 0З@_O;\\\8xwdd0]Kdd6KH"==jl [Wmm=ǏHllUWW>ߓYaǎy3}+)))MYlWc/7} K}e+Wndժ̞)W3}"/\ˆ ;Yj_e_t;vOCCySgx9L曟vvV[o}fYr{՚֚ZVĆ ;>[y_sVm~6566nue{Ǻu;T}~QA}[UYYذa'˖w5W?0=6lMQQY{-^|q2[l_]cj֮?oeg=mBa o>:77LQ{zsH&_|#̙ E̙5ļy!""*IfϞ=77fΜƊ% v8[租˴iqww琘Mff.=w&ǻ _/0lGN|8}vO;1ޙ7lmyng_6|%"bc:M{Ws8sɕ!}mKXzŦ2ijnfׯDAI>MM}}̽7>~<4Ifؿ+zӏ̸Q$ 巟fUytKVkx'ߛg_}z `U.N.㉇^֎fay+!c'p䇉H[B}}<33_ޞe#==@_OȑҷoOdv<+3YnGWq}7qn'ƍnJ^cw@@+:?^^n`C;& TlS^^ {{{>|1])) {}Cyy5NNOL6 [[]Yj3篠gooO,yÇ3ILb]:U9 ¾}iyc !33Yʼn.Myu^ Vq㍣;JJJ*x\qvvƮ]=3}xaϞ#_Zh4c݅[ 訬g̝-2uD_+̥[g=z0'_[o}NXX kl/x~B7oW]5G3v}'<=ݩᇧqnK;k+J\\Vw߭^O͡C$%Ųfv KaР{Q0z`22r_ՙ~io%MML2ի`*&O5 W^U܂=?;v7?'(ȗA@wf=TVVh"::3^x1LTU33Ԋ̝Caee^>| c ᦛ曟Ě5ۨa޼W륌9@_}+ Hd2SXj3G?-7IIL6 ;;[\X~qx׉}i ڇ cDz4(;0apρɟ |?=&]Yd SNbذ~+s P[IwxMM-/~.ΝOdd0?~7^lܸC2+ 'F=͞)S[[>:m3obFȭ壏曟Q[[ϴiXfG1~pIJaʹxꫥ B@sΆ?NN.f-L6mQRR΂HL>?[[[fΜ6iVsyF %%ٳadfμALL5WDaa)S^ǢEk?~Yo*}/⮻&ĉ#innaMOOAIR;hv .~=q!Ws9zb?}-zE}a>/ϡGd*nyE Má/J޺kpsXvn"b|k:FOOOmgp*59vƏnJvH}CG3p)<2/N*Y;$ `uruwjTVs,a珹zȵ457rHi%'_OLie [GL ,М)8t|/1 LFʫJ|ٻEsSŹTՔ{oz rUg̚6s|M{7ӱb(/;>F,Y @`/f=ĉxO:uw|RRe?_5 塇nٹrf6lуILׯlp&>?~gATT(~0_ڵ;4('5s|CϞV4*y챻瓔d" Kx'prrFe̟LEE z;;[**inn>o~ڽfG)[箻n࣏^"%%o*B)))1cu>:Vd~>Cqs|BrrZHJJ_|V|nmsEe6inƏFJJ>;HjVǑ#̘q}O>9,Y`$74:72r8 =cYx ---vxyԼ|ruWV=_@TT =vvDDu:ULϞ1466QSS-&zuY0O?V|w̢wTU0f`mϔ)Xr~a{ϔ)b0䓅;oѱwKgӦ=L0Dyf11 յ9̇*tb 74>e60rOo;ᇟii12eʵ$'v껼ky눈V{МVM]]vv9~ڴif͗_03f'BJJ'4 Ӵ(**{w&OkwУG4=w?{''?0s]$'s oڃy&{k2SLήLh6ou׍`Рz09̙cw۰zV+o`Ÿ7n;v^?&{M$'3mRӻw_~99hi10{3ʑ_~ʁixyHff.$::=O耣#N׋ٳ7FðcUw*,, ?܉ h>y~Z`&릦}ozEcXXm)(5h14SRQh\~ ?`0`j*qs457agg!TV+ K !8}G33PYU-446ϭ}yhii!/M݋!F`kkq=ptp")!r`};=}z%n(/y߿GIYe%]6U:R@9`>ggGx''32z`yy1c2{᧟a4 Mў(<=0{,## Wb"Hh/Zs7xBBpp8⧽{l{`Ȑ>ye^~e&Z,HxxnGXt*--' i&vzmy `ء{,99,>NBB:Cˬzyd"'GԤ&"|cDzqpW 3' WD^^666qn6nm0:v-t:h1P\6upU8A1.9]FckcKQi\]ܱ۰evBLXyƒ=Jth<.NJfjhp^6Y]5Wg7&"( Plll0/?I_ﰐ qRQUFXp$dÇ㹖cFz$m6\3NJa3sE+9`<>A_MKK[p"b>Ξ-IJ|x h}^JN䚅@~Q6L0w/o3IDz ݪOoSW;ndyWY.#7Owo :G;rXlll 0/svtf@PC T/7sih'40[[[݉2uh ?qz<=8q"Ccc%%eNF ߛ幜ȢEw+)((1SnwwWpqqNjZ*+-+^jjۃ jkΚFGGx{{11tS IDAT JpDEPYY֭x)[Jquufǎu^v+>}zm~766aggrwuy>|׃ f^;aB]]mPwx{{PZZaUިQmۃĨQ4?:]km3lllر 55DGW?TRRAcc}` 5'=V_߈#~~Q^^#'O`ooС} #,,PPIWWK- 7\͕Wʼnz<={sUU-~~^xyyPXXzX5j p5`Ԩy=@XX H\\۶'55,{N`Ӧ=}:KS+~bN#ܿS;;;CqppdMאhg| `4) bZi@@ϸsĘ^v SSZV!r,(Iq"{EEe)sҸ h4F\ 끳+.NnMFRL' 3TIk$z-!E'm 0@TP6z䉻'!g`VM6k$vpS2 ֎tPP18;IIE!q-$FNh 1*v݂dWHr|?@xH4$h4݋ 0N$"$Z9^L/\=xzx7y ΜtfMؗpIW`4Xu%>A b ^>s>F G_(!N1v;fkHŠ\` 12HxP ND&p0s7V㊗MF}B H-kb;s7 i™OFF.8::Ù BϞGRB#zHDD0&=͔W=pda}f8t(gg'zOFbbpttP[)/h4d.8kN./|quu&))7ң-66p1뉝-jH"#Cؾe0dH*&X~'11a:Ҳ0adfү_ee>Wje{qVش8ؕ֝NDMM..Nʼn~ٲy>RS{гgYxLJ+݂VuXפcޒt^& ߹woYqrXw11a䇧~6ŅDUU-MDGB (ׂ:.]E||w QfyxRPP=~~!!x{{'..NҥBپ}?cTt:;\NN>11ᄇ+KOj3|gggKuu#FUi!ݾ}?:#_ʪ+h3thZ엙k'[ĉ<ƌBTTgo^'44WW=^3%%t:BC >>:"#b۶>]Ljj"qqs)$$pRRгgY{y{ڜ/BCqqqǃ_!([[[Cqss%&&S?V{PPPBdd0!!l~'^FL$%%''G3f_itgԨWss oQ`erJS'_O0-"g=3 B^03fE.[ڱbNBv ÛyKfD :=Uk0&\:՝3Y_vׄ8l8axz }cs^9Btt/_$#06^ 4 9^e^:忮 V1h< ︧?Ϙ׮fH' yU,X̙]5j2צM{'Ů̞)S"iKIWi<~$#FѮSOݳǧwvgdo_'4W"-}uuOr[#* r`pnw7] GBl/0)]􉿬_":wO2_]au{%DAĆF^<}//K  E_瞜MDKDA#$/YKs2_"/D tq^YgKU%i_"@Aѥ-YH4Ye^ADlHU%W뢥[ _"_/K B|;_ri_ruAabä4DlHUe" C^YH%X;z "6*bC%8hi"MS(_"_"@AOhBK%XK  +x^ܗKġv &W7,Hii2M&5&]o}Wm۞^2C?G)Ё?:eNߺBn][w8ymtؿuau3of0YgM`R谏yiޖg9κM29ӗu9Vay>Gs[g-Eط:Y~{|dqc06mY,i⸝|S'>4븼=ce,2(s묬|]k>>:q"[p]+((]&>otwOੋ2p+EF`E>@Έ|b.Y ź8`z7ƫ@q7‹|vtv>uC oS eZ>^np@U7-.օvk\?Kcbu%/X7+b.j\!  AAAD   hV Jഘ VO@S;\[ !3\V3J6 N ?2I,AAAB'VO 0N`LB VbM$R%| FD\$Y=@@'X7bM!pm 84C*DAAA   "@AAA.3wkt:;{0Wlw %U_2 WnE'w.>1/&i@A3dUb x NH|z.72oV %UxP x>aWenw/<wu{k/QltVѺξݹ]mcujzlP]ECn]ة=s88`#N_i-njQKOu5cdUӠEi)KzjUS_ JKo(1hP,` 7tkU,P;tIjQ-?Sҕh-JkEJףm(?AJw.Ќ2>#.YO4SmTEMe FA{e JN{Pj5rT0M=G@p 0k؊NZ=#xAAA((5M5Ԭ j'@Dg*S(Qy\bฺ q~QEm_ԨB .LϪbgz>*jԴW-(2ʱH=b95->4D8Ai(TnLuRN  ˖ 3ʘoP'Iĥˋ(Mu:K`h->.f PwK.u Ȏp:`˖bDPOVbMCL);AJ _WWAA{p(axO/;A%\H+y/^&\ (c[rr#GʚZ{†NmPfnBPk5)Xy'h16G)h@1MbKB#`ҤQ={3}6 gkp=X{%BV߭7ĄVs(c1Q/Lf,h?Lt-c@z j=S7DovvvK^SL4oA:q"UGGwͭq3]jĀօD G"HL)vSkËnf@S@"`i@A3Dg"dY &m1\L)~wz Wznbg@svH !r^2fN>5r2O 4-dm!"Q5/L肂#^1ph '.QųpKy@D  UqLD(:w  "@.J1 V*@Dw  D *"@_b1@SGˀ*1f9=z/ ocjVOAE&>hybMHL)t狻$wÆ]7l0^H~2"- B*T)z1f2h+@B$@IwKQJXAa pZ`hXZb>P.f  FHLj+yI c}lbM!pm@Sl\tx1U x[Lcu  V1W1f?z`E8pJ.E"r*.3`sT2]&(ݽT1>؉8T*Pq`*~i>Yć  p! $sPj2g`=]G8rPR _] (@i"C[9H[6?UQZ2sFi1QQFGuAMvyMMG@"  R7.y\'z HP };JkL*Zm[9Rk%OvĄ^-ۢlD@JkI*&6#Qwuשɥ8J j wH 2TFn^h7y@(6X[bsϟuΡCwGiABiB FѬQjZ@QC-p 7GiՇs*Zn5j{U,(RyPns &KMS*v Դl]G @zbVCnNt/,1K`A"/02KӷxG- h14us*v1 %&6T?kF@;y@-dAtttJc  B2oߤՉQ߻8]%fAAl… >>B:nܸwزe`O*YO[(]|O+9M)  ]899|`Hmm:qKɑ1c0`@ׄ '륣mllUVPAA/^XwxMu"@su#дE@S4!ahiҤQ~%kyy##_t:n [ׯ_;ߍKOZDszX D 4R!hE(xE/t:zeB.)@o߉%+X#YL) 4^18ڝ/2 zPf^$yN̥d2VTT{7?-((ihhzez{\p=eBBzy+f  ZV`5P.cQ&rڻQWPr\Wwѽ--o6u"aV0FD IDAT 8Pf lU"@..X݋]?KG_]W0Tv^. `M\6][xTwNvq(z  "@.nEȯPo'AAD\pBW"{7t kjr4VG-"fz*JL)jA3u B.%\馃_W@y@-dm(re `;`¯&]L n18,&.I'#c@`3X=O 4œȨ=-13h8 YzZb/)fzhQ"@4@E̠zqKAA/@d   hDZ@AAA%  VCK^rI` 4E@S!-i^$dCGʐf~_b51y@-~*]~ON@OnllSlP5){9ªN_}6h v(3{<3X=}bn \` &s ?ЍúvCn eb'p3X=CBڢ,f AAA   AAAHEM.X7EH4rB4qRKb >܁1[n.(xmv׋7 ֎ FFfgn (3JsN _260vI_VO20N`Id,%n2^G__V/)fz71OL)-G1fO}ج04 A-k&h{ICjd* hE' Hu fcF]B*^o߳1Ya]TI WT/PI^ڿ"%1D޸J_e@3\U~Ԯ8 K.xm7/{_Љҙ #0g>ߑTwIy̞w8px g\}wZm6iL{/R6WSm-Jr/p)0Z(0( Jk p-#}QL{OTP H:x8ג$G% 7smpm[7x `W% \<$\KQc챻_õiSH*d6A0GIÍ} V% N,^hA8/i[yoZG,n_ee7.Q`Wܮ+fCdSWflC[KT}Y1Xi7YR(IxN}@{j,̷I²n\HϠY*^=K#@QJkJx ǵT4ōHT0k`F9޲#7V^vmxK\6{ITP@|p_B]0 C a sU#*^y% PKϥ:V1uQrtUKxE~Z}ҞRSHjDNE m߾͛7rp0ѬYS{m9i'=بC_}Wb5υ<=? V#70Saj{7N*iC'\<% ]V\pI5Zѣ'5J썫B:{TTTTl\VY!%_{R\ZFÁxn`B4% kHjk^ԶUWJKˊ.\㖌ʢ7gg UB*-*VTYP""c|E>;>jկq*Q"" UPPv'ĵt׸S UQҰMkPxq{V+"""$Ne R;@hM#LR6)3J@DƗvU! WQ2*\\WR=n^X"QB=J?^@k% " cptrCrx2yw" W v 7NTRo,K9qRm7xQS 5wZ)^ix)j!}@}/1a57f\n/ Ze!P\!v`$3pd&~"""r%R[g `t²׀f0״}*w8 8XUIxq$`opblTf-ib`,0loM-"""J@DRDKN~iԮܽ-7a)mVΖpL"j6SOkŶUc%66Y<۞bRj W$-QHIBI9v`'[Gj |kIف|ifnDݷ??{^p=' D`oS%_bF^=kX#>y"dBWQLTWD{x[o[cg_˚bIR5]a%# kp:n.[0 b(uZA杁lٵysvq SQ]C%>f\K̞Y%GJy@!ʃ W^Pf% 89 wXe#8U뗥[p$K'Re]TV{ @u@: ~QHx7\zw;k)H:Qf4Q+Ya>N tI]Ppݱis>nӢI5mn;xxQQ"#o?Γ>~謬K+*wb7?줸(G$>-Zh{ˁ;sۡmEIi VQ% q)Dw222 ?f% 9nv_s@<xI4OFoD flWrҦC?)W+7klF nm_%ܞDu kƮ/gzV>^y^! W? H~$v݊{!?sG:琽6mx ^(2m poLP"+ӂsxUwߓM%?f,iWkoSl)\|dQ=-\&$ܙ˞ W5 +y9Iv@%_Z;SŒ+~7@1@Ku*ЂS+qݼvN$uqݶ ,Y: 7i[^DWDDBh(gi ,rnH<ץ*ג\K{<v`IA=n%:e8Ml#l|Qu\@v@D"]S>"^؄L6,k f߭q ZV&o  '$y`Oܧj)_%Qwռr/f“jc q7Y% C&A6O:~x=+DDH4i۲e͚ey}k{p{J~2/dCh?۴jEff]:t7k.Rȼr>^97H(hS_$2kfgvݺ+ɋ}sg"!׫[72$̡Cx孷3W6mzU-rssVt9e<_PXX7, UQQ"ҰI&3.;rgf=xpW&MS,(*Ӥ;t_= r=% "k= hT *vmxSB=9x=^s]gwu $-^3,{qik$WK96'a^)H@b?p?sӟ(-7/ j·qХ=mp35kM裼?yK,cg2Fyj gYS4Ӂ='ٶ~j},61>L]^yX0xc< 8'!"z[ 72q^zٳW\R:P+- r$q~ $Z3t#:q`K_x\=pyq3퇫`%+p ~LhBPTW/(^.+)M>4H۸cg{Y.w|%%bgcYYK& ;#q'Vw8˒@+K([0xu'n;y+W9[w.Xڟ`Y:^k)YfIG%+kAyxZo.Sq'?TWK:I`{ΛQ_Q"RQ7hK^e ȕED H1zKUM/y3g~=FāVMmPjF&߮@K\+b;/uz8~%\6.p{>G~}KsLO."J@~HB  Da\+DJ 9#o۱vE+.ͳ.uR=SK1!.X"Cŭi6%2nvMaq%c : ~y (\g(i^Ig,pH^f2v1C8?YYon_|PT% ^^`Ss44Y̏W\RM"Q"^Ea^xfcAiˆOik 22?dҲ¹ gl|n+M~yQQI3OW7("DXM @]$M-X2gcSo[v ;@X?ųk~r$ё/(MK+g~=}ճ?i؂yWTOHˈL@b:Hwq]IURoߖsj]Q!5ݦކu]w̄-E/kk}l3 #;L4: ~eI?HTR-E뀕q<xVͱ[ .}*dIWhUfZF(i `[ˈфX@;'4DJR| '8ijb5/jIw{o s˜c@$@De W̫loID$:'~ X#ͿH0jw @eºQ"D H>0>dp(p W` LTDjJp:!"?ƀH ;#=Mܬ?Z2tΰd=?3pnv ++2"% {FJ]!z>//pg?Zsiq.QNWEu@|2 !@t#3Z@Wܧ’\u*K8K,+Kxe%!Bk% x)Q@z 1{Tϵ-p``\<`w6k7 /+pԕ'i$$Z&.َB,3󁗀-"c[2EpQ> WV2wJhN`I;c?֜.6`y_'DDDD O=${6vx:s @]$ɇބY&7h^DDD?mD, 7\BE WY|͂%PhEGa{ rrr&JJV+*>y7auX9 B4H)f<?TAjۤh{I٬+rZ@$uƀD)Y G2\-*%u@R4$V@T"ԹGS{CQ u}qHR+B4Q<` wR{й>D{@DD$:Ң &Q"i\! WI^|7}(i ڗl!K_T/v!4T Z60nVV%P0xk`%$p_lx@u@: ~yוQ@iXtqjUDx~ ͂h,: "Rj+Õx|^J@DF3 "@g+t@ 4HjHDDDDDDMbs[DDDDDԿU@ "{ WW)P0xc6N H0D@Eu@򈶗WFy{5cDV[`4{Oms뀣[`e{휐,E!"")iҷ]GVĵLLõ$&_Pؑ+L#,cNˁ|o--խ ٿ󀼄)Z],itWRmg\kB.׺-s'q/v6q Գ*-MI p/nj`%_'$=p]6O K>8o4z)^Ou˭?ަq0.餈ڵI&_% |a̴Dy B~a˷(Ϯi7KF&jjVrB W^?Y$նD\Pd,eUW*HLB4'2^_\]2% :ڐB: :q~&J#_T/RGALRKny!g?}b1{DD'W!J3+9O+5DsooԤ|~~Zh$ʝvgߵ dztfMs/t֔=qMn%Ŋ\$["""J@Dۥ}VcMO]μ39x!M8:qU}% .8CC@JޖM|lޛ|2~`ν:6k<+7'7趺xP ݁ ϫp%WT ΐ|G9H!ʁ[@+\,@?m@KKB[ROu?-fϱPu࿳#],X zYRR;4^{|PR 8IZ~%nIS_` /.;W8㺉nX LfRGr*P ep'>:Z9\Cgq-$Urc>D$7. {x{+~[] 'qqJ@D3x;ɡh%PZ^Q>/x'JMϭQ0Ӂq[`;JA-Ih3Rpx8eF[$!RnqS._MpMq=I6F4üK|R;;B!"GR=Týb58ܒ-vvÞWׁsp^~%с&\?-7LKKߢ) HU$ԁ$7x_aQ"sR%IBh1٫%.033s Ԯ"s"=6J!h{uTձ^Guk] _#`H@⁋Ds?^$*^Olz83[_wuÓ۶ܜ}m]bOq{t*cXtibDw W~o49iߦ#G>>߿8kNov:4*Z8!\ƀJ+,+_「֎PPe4 iGݰRmMs8tcg1D$kK(Y]5%o,Q=ϓ끓q~ Q"XDo|8+^9Mش5xv%7j\ק ;Ts[.vp="x9p%ZIVl{dǸ`)(cW*Fܮ]qs<\WA ƌT z&: u~cy8Io\B호XO`9n\K .%fFl]úOj> tzounWZqռf+Dwu*c,(jI:? /6X/{h\.p#lF\\KUyK[5B#& ";i`3m5_<>_b]fإJu*$`϶KkTy%޳Ӷڟ"࣭+ % ::DD>NkOwpU`8CN7|&I}S{PxX!B nzθ*$)uT^8ܒd3'Zl g+%E>KRĒdJAD"6+ix}ɋI#q-m6m^I1kg om_8h8% yܹ$DDęx+)!#;͎6kʑ~SFש}V]5xNcIa$p9 P$533ҸJz8#m{ZA|17 |BRT]ic~q]#oaXXg<@DLJd_T/n,//bjwR HzJ;cq"OLS2K!vpH>tXՙċDVČP2\`\S|8<\Bo&HtsB+F H}dǿ6 8 lNǍh;kpM౟xn/Dc+ r^hQ*:D$4Y$-qOe%ѓInGi~NS" c_+ 7vQ% "rix G\,TRhp |lEDD$ H, \!( J`7\ """.XDj-nZp⺙jRmBe WV]74ݭHj?f: Lq.6U0xQT'pt͎IoqU\[*U mty.8&s/u[֗b[,Xll}n`}!-q5?oXol}Ͷ Unϵ -l}Z\E䖶>VǶ MS|]J~Q%tC}XzN{K 'нv'$ywIqEK< ԒyS٨MeRҏ֯Ý1~/v_`qݘϵS3m  nJ@M n   l/ǶcGz`I 7ZA|qV*ÉJ6p0>)3Њ>% "i]RHI """J@ckED)Im+ ?D Wf)^\%s%60( nU: ~yؤ0xc!<%- U/`f*陰l nz@zn@:ֵ$DxEH~_?4_dJ~g',kl섛wzG$H8׮|V?|jIKW+^Q_T~%pM߷K^,Nߕ@6 \\wL&{ָ]pf_K#%Cs,^w8p'p%pU] W>p'nO58 8x2-Yd^O$z+^x;DЉ0ՙ $Y>,`ZDK@:O1]`}^h KǶcZ{|5obf$:`2}>etѮ#"""DGp&nF- )`5g]*x!*\dXBnz[KJyv±̒d>e\ {ݖH BoT|g\4=f:qݧVreZǵJNl p)VU˸Y[Jqoid{δmB`UؘJ6""""!J@Qud|f;;O6hK\w-x Xi pc<&}b Okp]>j`%QuZ^v眄SRWUWp)}{p@ewD脄4+"Ӻ; oc`5/]Ax׷_;TwQjٸB;Ο?4y.d})o`'rZ:^P0vzoKQ H,e:5ب D?Q-mtK@ du@D$TĿPHN8,ؾ kkqi \,V""hrtΖ$G HhlFt'HHS7"n|j<,Q Rm؜g`qϪc}l[-"ۿ)$I'B\.N XHu@".O(M*a5B!p}\r ItoQ( }Bah2*j *-IVŪw+V3b5h7Q"""" Z&#yj6qk3(ihugB\0WV07!S(ODRi삏5'xvn0X TN&@AD=NdnIC/I@k<*W+^Q_N u@R]P$ Q"L/RB90x!ۢ4"R^s&X,dKI('k-H`-lX@`p{>nd)""⿸B ")T @]/z`e 8ɮ`Nf l_,""R]Um[4u緁@emq3 e7{p R`_D_`#u3A\J+dv@ d=p.xϒ}U _izMQʫO&oLn&n <l C.؇/q-)U3ΰjWy|2оk;ZԕԇM|ѷo5}\N;۷^nӾO3..X>/nr[lV)R'$}am1Sqݴ q?7-ii?r@7{w/n䘪_T/Pi1 ]nxƭŪUk9-ERD[MqnƩmpvtm:q5u$ 79{v*p%["k׋~+,Vl K-hcϳj%)s1& W0w1 H,5 "޹#ɲ{,{<ɲK2`lk8p:a[wi²qyHLfEDDbdd,-"""""M;Z [j~}nnN'BDDH.XJ@"k\wq.v٥u6䝝7lؼ,2Bb% .mo)4dY{ٯ׸q8} >d[h6n spOxHUUTEB7.%- J@$AgrDtv.6[oMW:b/^nU[3u˖B% PYZan- f@\b123po`J@K- qU%Z⊭iG[;` Guo${cFFFNiiYefffS*W "^)i 6gd5 ޥM9GGkG[`$=6ggTTTo)y뭏z7*-ZnaaH֬à HLglڵּ-/漹s+{QVVQR HNuر.~s,]RR0(C.X""J@R.X:a C佤 VWVVލn;iP

                  Rx}JèJu][pjh[ ,Ho4նJ /BDDDDDS1`ytT"\+\pZaơxTj; Fa+C 7S""""""DDDDDDYŤ M*Pj [pjK0b> Cm.h0D~^@>@ADDDDDc1r!+ w Ya+\Z@|r6VaƱ@ϰsr0D 0 h% ^9h0xcw% """""DDDDDD$W + * N!~ ՕI~F Uav@W!z CxeW4';MolRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDɇ\ IENDB`commons-math-2.2-src/src/site/resources/style/project.css100644 1750 1750 102 11532241247 22334 0ustarlucluc 0 0 @import url("http://commons.apache.org/style/commons-maven.css"); commons-math-2.2-src/src/site/resources/images/math.gif100644 1750 1750 35501 11532241247 21754 0ustarlucluc 0 0 GIF89a,d.../13 7 :.-*(4 9>>A;D3HDG;DL$QD]y3"M,Z?&I.Vkv'uI4b3I֕2(m{ KB <^ C̫Ng/b#y<doa=aCL0f=EE;=>´ۼVZHSDS4cOrI{b@2.ᏯcˆyMG9 ]H0c@ݸ?&W@X2%|Ll]˓41Baۇ;~#r?t|j#Ơa#\!ui# [?֏C/ILb恏{xÈ=Q(!_Ƥtk/h#G>aG!=Ad\ Ff7;B3P=i8 0{ê MہhXkᎰ4L+-yh4f`q}PQ - жGQ#g1l$WWEqZh6X' i(00ф HF`983PEp7)@;xOjt% m70 ȀAs xg~Ұ} mX@Q( ̀58]<0 hQT;Xe@`T` 7A2^u@ Ҁ):| \񑪈g9%@Z0.@+ӗ` (%:hi @j3pgޖT2s ð h"  pP aj|4u[ϑ7 pq$ц# 5$XluRp0$Z&:@iyW1{]xS'Nzh!Yd P3LPx 3 )dWХoRp B4XmP_ {m࠙)xjx֑+~$P`%j5_Ѱ 4?yuV  NUpefp:'0J7+-q 4Hfay"p $@#p$p((p7'` {` )3Ȁ :+#q']79 p gzY ,I)Y>"P r@ T0--fP]`ZᙟHL?dY*0(`5d \PUʫ 8 $3E6 fz1z@ W'9gp |3r Ű3=DS27P Ԁ (|Q'}ف QeP`a7 P b[Z6aUP`Ԡo ~0?DKIz:@B{ 5 9^)@ /0#p' @"5 iF)< `AOx(A8pu x•zJK}0H?CP ^ nuK ݰ Al@`\ؐdNXFjI#it(T v zhl$9L ` i( aFb8rw G;Ř`z00P&Vm{/%'cw =@o0 j#{ t5dk\9 KkTl']v\0:0XK6Pp7Q@[ GKy ưBO Ƞ!q6&?  %Onx P2phtڴ qɖr ɐ %hpq#;p#@%'P DQ D*9  u+3PP Ű HH9jd@KT K~@W6XB 3DP ̠0^] % A`|(6ugv*eU=(j DF,nA  Ґ p KE@аXFAtY%D``1Ր6@ ϐS ֠ L$^Sg@h-}yC8z_A: [yY sbW * @fyQl5 ^Tz6 ԠAB4NB;F5 ^<#DK* `rb9VW5:1 Ȑfؠ Pz%] xa 5`X-~U 09rZK ` 5faPL `   { ` 0 Z 0`e $/NxE#>ٲcoXcʦq'/gĊ 2bWܹ+ƮytC6'xhLaz䓇艇e)oq, : B|"/die!uޓK?܉1#H 4bd8eRƛvRsjZpl[:@p9-dy&N>$2`(ٌ6i!8f)fj)Fh9bSFe1`ifit^!&XƚDÎqsjHf-,$hjeerYjIf@:K"h!WdR\&c UaZEf_hFHA"^ L("7~ƙcifE{_gC`LSye -BR@ŗV_%O`(Ѕ XsnOq&di8B5gB3v5Od|эc֎Qe(F_qTa%f-$tFwiٗ`6ufk*dd# $) Yfgqb%tG’h*;ebR,>ϔΘc%P7SP4c;m˛1 F9?ᾤn q^mT`R͐Tn5 JÀMMja mLcFk]0g1c(Ϡ M= NV0mHcE߁X" P΀T/b@ jH9 @1ZGiPb)xcM7 ؅M$.O]mgi*Lx1 Q LA7ɆA:4bjR#n61fPlemz1Ja,KM"Z1 !p&H)Px1f~j*'P9qU,QҫsJN&&Ad3Esk\ܴ҃4hJ6s UDtS5G8 ?6G\m\pF"<56LUJ69E, $xtH1ڰ3a ƥQp0UbD|gqSh@ Qsc޸!I*D8P$5ްF3fZ&n ]nrdK{cU[tB1ɩ\U2umm[2RI=S GtprT$;%/e A Α@8_e ֫ԊUB 98A,6 %S:tc$4 Cf%F ֎&v}ldM 'Uqٔ,u *Fa02$Y=01RA8P Paq|crF}X&UBHE cEH V<6_U3[۶v=Bn!H ?!8#!{ȓf18nGxitB a 88 j s~K@ BT/@\Y2JH]>e1u8vz䦻@L O"+S{TH6 rT L`@9hQΗc|,T?:)mt;`g12Jw"'9](h~ثE#6Ff0 $a@up`#WKJ a7BPY8¾YPxmoնCS!^x6;k@#_@#۽cd+C=(' ӱWxX xp=G= 3d\H[)cYpiAGXEX$صy*tp=tGZ82;O(E#!+2,|@2,Cې@s!8/=c+=XA,@(/*A@WB+ۺj:bAЫ܉FX"D8:-fVhE0@ZcSJ#*t59?3E  hs8cX$+ LZ8U 8/pYHY *(I[h8Ɉ,˸@Ql,*> 7H8Hq6İ9F "ЂS hfWYpFdFC A WS .`Z@p>2tڌ\ J2vP@74K<6HbZ#x0:" < *FT81@7"нGX@T8EPXXXR@X ͔ $Ѓ* (Pp$lWP,0.p? 8Xgt^D\N_, h!9*Qm,0=1J.p`:PS;ADp|[,8E8è/qTЃ=UN0th48Vh(30- x#.A:X(:yR"<}TH@"8iKc>' n ÍA@(# fTH.b qs(U( .t$0K[HLQX7A؃UEc%0 H>ЃLEp.`B q$]T|Ix#0-gE#Z%0" pg<`G'`֠ˀX9P<." 4 mp؂T8 $)(ІlZepz_-p`UXHdcVPB(X1|` FCP>^QTSN>:=0`R@&u4V…%0orxr`VH08np؆Q&V%ښ5jADfv ֨UdrEzv=dymF^Q&e \Dec?X HkX5*>0(9[pX{DuEp>hGq@Tdss&ĀP8ph_fc=32U(:bq(ޞ!EDhRgLp kR0"huouxZEYzS1 ^Aim$iwXFB>qnV+8 b">jP20U8j(HPٖjO:7%:j8?:vGnd]hxmY-w& /:> sUstp ݌+b#ER30p'Gp*77%s k QxaX<0d8h  l5VcԅE"sWj!r!m%MmmI8B@g$hmT pm;8[TZȄYuL(Qix& 6BqȄMpFX7V/a=* ҵN\G=/sps5- 8=,E*= yٛyHyxQ/6GEokqylo<*2kIA / rhkS8Vw@]txs`8xqJ.Bn`L& oy7Q2o?vO-x}L ` Hk0nqr9Wp8`Cuґ'A zC7n4ef:5 ;֭\7*T2RP@ITm2VZ%`AHV$NJU+?$AR9pמ VQ:Qv3 Xײm-ܸrҭkW._`9Ndig#j.cF1vu'\9`R3b  ȖIt(8 !RTCb͑*U"D@$La{VT*UQdHG].,U,rIWGU:۸?^U8D#Ztl6378SL0eA@8#NJ!U< N9 Ť@9hhL#(WDN*H+,]a`M<F_PL,CD!0:0KhPwmР }i09T 'W_$x`u5 `6#M ,f: hj8 +Tt4ᄍ1Tc5"+~ H**M EH)O3TmaJWvܑ xcM3w|9@+N8n3_{/\hY L]0FcHf  )N倓 }삍zSAJ"Q !{bPx2($gf.P`p2)P'BH'2 vD0 V!eC8MJ/i񫍿5K,DXxĺQ: $j*JF.4Ë7CK!;p |qEXpD&a ڀApC"zpI0Ö]x (zlՎu4TMa5XfIMM6?e,*hABAEGd&AB+x1xgV ! /@>At{Jp'|3^#"*n}#z!.Ռ%AE!(db,7&a+'gP`,0ħ-|BXIc'Lvۿ  DH :1WbH< 21؜0<q:`D D0f RGL8D(L*xQ4D [ae?f뷔8 69]j ܲ.%VF4 9qlnx84}mPİ/3p 1 .$B{07\ kh47hH`c4dNsxC7(p!kh(;3_c7̍_m':MP$nQэ[oF8v]8@6qu&F5Qaɀ5m86 `lTF, hF7ܮe #HF6Oi@6}g ʿ iLm{!qbh} 52Up/蔝=\}^2@۽ T4T[U/d520X0_3@C4Ԡ `=C3 hE3D5RC4/_Y21X/4E20C30^( +3!\H`SmU3\[B Y6"&2uE\ [}^1T!2dbn"'$I| >2*2%2*0\b2$,Za0!`x!>>baE#Bh Y !4b(ȸ0{չ7~ "VT !Tb]c0@fUB"(B+ fjvYAFޡі@ebfh&g!lB#B)$ɜqf<0D o4P[fP`f`R*c6'݂, |@ g TuS Z'yX htvA3T٧.8hV@PhC;k`Q)hOY'tLZx$\!4(\<: Z:[I2hOaSX@c]и${|rC3P}A݅H.xC6H2TNi B<PhҀ雖Vlio0 C XYC4އک"_AiJ<陴T*1_J` 4*!~i. 7p5<jOm}b-f+vb}=./]4T5`&~ L^kOA";#@Jy3k!r+oJޤKF,~0++H$j+l@;commons-math-2.2-src/src/main/assembly/bin.xml100644 1750 1750 3207 11532241244 20121 0ustarlucluc 0 0 tar.gz zip false LICENSE* NOTICE* RELEASE-NOTES.txt target *.jar target/site docs apidocs/** css/** images/** userguide/** commons-math-2.2-src/src/main/assembly/src.xml100644 1750 1750 2345 11532241244 20142 0ustarlucluc 0 0 src tar.gz zip ${project.artifactId}-${commons.release.version}-src *.txt *.xml src commons-math-2.2-src/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties100644 1750 1750 61345 11532241247 30753 0ustarlucluc 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ARGUMENT_OUTSIDE_DOMAIN = argument {0} hors domaine [{1} ; {2}] ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1 = les tableaux devraient avoir une diff\u00e9rence de taille de 1 ({0} != {1} + 1) ARRAY_SUMS_TO_ZERO = somme du tableau nulle ASSYMETRIC_EIGEN_NOT_SUPPORTED = la d\u00e9composition en valeurs/vecteurs propres de matrices AT_LEAST_ONE_COLUMN = une matrice doit comporter au moins une colonne AT_LEAST_ONE_ROW = une matrice doit comporter au moins une ligne BANDWIDTH_OUT_OF_INTERVAL = la bande passante devrait \u00eatre dans l''intervalle [0,1], elle est de {0} BINOMIAL_INVALID_PARAMETERS_ORDER = n doit \u00eatre sup\u00e9rieur ou \u00e9gal \u00e0 k pour le coefficient du bin\u00f4me (n,k), or n = {0}, k = {1} BINOMIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le coefficient du bin\u00f4me (n,k), or n = {0} CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS = les statistiques bas\u00e9es sur des moments externes ne peuvent pas \u00eatre remises \u00e0 z\u00e9ro CANNOT_COMPUTE_0TH_ROOT_OF_UNITY = impossible de calculer la racine z\u00e9roi\u00e8me de l''unit\u00e9, CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA = impossible de calculer la densit\u00e9 beta en 0 lorsque alpha = {0,number} CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA = impossible de calculer la densit\u00e9 beta en 1 lorsque beta = %.3g CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N = impossible de calculer la racine ni\u00e8me pour n n\u00e9gatif ou nul : {0} CANNOT_CONVERT_OBJECT_TO_FRACTION = impossible de convertir l''objet sous forme d''un nombre rationnel : {0} CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS = impossible d''enlever un nombre d''\u00e9l\u00e9ments{0} n\u00e9gatif CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR = impossible de formater une instance de {0} comme un vecteur de dimension 3 CANNOT_FORMAT_INSTANCE_AS_COMPLEX = impossible de formater une instance de {0} comme un nombre complexe CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR = impossible de formater une instance de {0} comme un vecteur r\u00e9el CANNOT_FORMAT_OBJECT_TO_FRACTION = impossible de formater l''objet sous forme d''un nombre rationnel CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS = les statistiques bas\u00e9es sur des moments externes ne peuvent pas \u00eatre incr\u00e9ment\u00e9es CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR = impossible de normer un vecteur de norme nulle CANNOT_RETRIEVE_AT_NEGATIVE_INDEX = impossible d''extraire un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0}) CANNOT_SET_AT_NEGATIVE_INDEX = impossible de mettre un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0}) CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY = impossible de substituer un \u00e9l\u00e9ment dans un tableau vide CANNOT_TRANSFORM_TO_DOUBLE = Exception de conversion dans une transformation : {0} CARDAN_ANGLES_SINGULARITY = singularit\u00e9 d''angles de Cardan CLASS_DOESNT_IMPLEMENT_COMPARABLE = la classe ({0}) n''implante pas l''interface Comparable CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT = la matrice orthogonale la plus proche a un d\u00e9terminant n\u00e9gatif {0} COLUMN_INDEX_OUT_OF_RANGE = l''index de colonne {0} est hors du domaine autoris\u00e9 [{1}, {2}] CONTINUED_FRACTION_INFINITY_DIVERGENCE = Divergence de fraction continue \u00e0 l''infini pour la valeur {0} CONTINUED_FRACTION_NAN_DIVERGENCE = Divergence de fraction continue \u00e0 NaN pour la valeur {0} CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR = crit\u00e8re de contraction ({0}) inf\u00e9rieur au facteur d''extension ({1}). Ceci induit une boucle infinie d''extensions/contractions car tout tableau de stockage fra\u00eechement \u00e9tendu respecte imm\u00e9diatement le crit\u00e8re de contraction. CONTRACTION_CRITERIA_SMALLER_THAN_ONE = crit\u00e8re de contraction inf\u00e9rieur \u00e0 un ({0}). Ceci induit une boucle infinie d''extensions/contractions car tout tableau de stockage de longueur \u00e9gale au nombre d''\u00e9l\u00e9ments respecte le crit\u00e8re de contraction. CONVERGENCE_FAILED = \u00c9chec de convergence CUMULATIVE_PROBABILITY_RETURNED_NAN = Fonction de probabilit\u00e9 cumulative retourn\u00e9 NaN \u00e0 l''argument de {0} p = {1} DIFFERENT_ROWS_LENGTHS = certaines lignes ont une longueur de {0} alors que d''autres ont une longueur de {1} DIGEST_NOT_INITIALIZED = mod\u00e8le empirique non initialis\u00e9 DIMENSIONS_MISMATCH_2x2 = dimensions incoh\u00e9rentes : {0}x{1} \u00e0 la place de {2}x{3} DIMENSIONS_MISMATCH_SIMPLE = dimensions incoh\u00e9rentes {0} != {1} DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN = Discr\u00e8tes fonction de probabilit\u00e9 cumulative retourn\u00e9 NaN \u00e0 l''argument de {0} DISTRIBUTION_NOT_LOADED = aucune distribution n''a \u00e9t\u00e9 charg\u00e9e DUPLICATED_ABSCISSA = Abscisse {0} dupliqu\u00e9e aux indices {1} et {2} EMPTY_CLUSTER_IN_K_MEANS = groupe vide dans l''algorithme des k-moyennes EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY = tableau de coefficients polyn\u00f4miaux vide EMPTY_SELECTED_COLUMN_INDEX_ARRAY = tableau des indices de colonnes s\u00e9lectionn\u00e9es vide EMPTY_SELECTED_ROW_INDEX_ARRAY = tableau des indices de lignes s\u00e9lectionn\u00e9es vide EMPTY_STRING_FOR_IMAGINARY_CHARACTER = cha\u00eene vide pour le caract\u00e8 imaginaire ENDPOINTS_NOT_AN_INTERVAL = les bornes ne d\u00e9finissent pas un intervalle : [{0}, {1}] EQUAL_VERTICES_IN_SIMPLEX = sommets {0} et {1} \u00e9gaux dans la configuration du simplex EULER_ANGLES_SINGULARITY = singularit\u00e9 d''angles d''Euler EVALUATION_FAILED = erreur d''\u00e9valuation pour l''argument {0} EXPANSION_FACTOR_SMALLER_THAN_ONE = facteur d''extension inf\u00e9rieur \u00e0 un ({0}) FACTORIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le calcul de n!, or n = {0} FAILED_BRACKETING = nombre d''it\u00e9rations = {0}, it\u00e9rations maximum = {1}, valeur initiale = {2}, borne inf\u00e9rieure = {3}, borne sup\u00e9rieure = {4}, valeur a finale = {5}, valeur b finale = {6}, f(a) = {7}, f(b) = {8} FAILED_FRACTION_CONVERSION = Impossible de convertir {0} en fraction apr\u00e8s {1} it\u00e9rations FIRST_COLUMNS_NOT_INITIALIZED_YET = les {0} premi\u00e8res colonnes ne sont pas encore initialis\u00e9es FIRST_ELEMENT_NOT_ZERO = le premier \u00e9l\u00e9ment n''est pas nul : {0} FIRST_ROWS_NOT_INITIALIZED_YET = les {0} premi\u00e8res lignes ne sont pas encore initialis\u00e9es FRACTION_CONVERSION_OVERFLOW = D\u00e9passement de capacit\u00e9 lors de la conversion de {0} en fraction ({1}/{2}) FUNCTION_NOT_DIFFERENTIABLE = la fonction n''est pas diff\u00e9rentiable FUNCTION_NOT_POLYNOMIAL = la fonction n''est pas p\u00f4lynomiale GCD_OVERFLOW_32_BITS = d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^31 GCD_OVERFLOW_64_BITS = d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^63 HOLE_BETWEEN_MODELS_TIME_RANGES = trou de longueur {0} entre les domaines temporels des mod\u00e8les IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO = les abscisses identiques x[{0}] == x[{1}] == {2} engendrent une division par z\u00e9ro INDEX_LARGER_THAN_MAX = l''index sp\u00e9cifi\u00e9 ({0}) d\u00e9passe l''index maximal courant ({1}) INDEX_NOT_POSITIVE = l''indice ({0}) n''est pas positif INDEX_OUT_OF_RANGE = l''indice ({0}) est hors du domaine autoris\u00e9 [{1}, {2}] INFINITE_ARRAY_ELEMENT = le tableau contient l''\u00e9l\u00e9ment infini {0} \u00e0 l''index {1} INFINITE_VALUE_CONVERSION = les valeurs infinies ne peuvent \u00eatre converties INITIAL_CAPACITY_NOT_POSITIVE = la capacit\u00e9 initiale ({0}) n''est pas positive INITIAL_COLUMN_AFTER_FINAL_COLUMN = colonne initiale {0} apr\u00e8s la colonne finale {1} INITIAL_ROW_AFTER_FINAL_ROW = ligne initiale {0} apr\u00e8s la ligne finale {1} INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE = les donn\u00e9es d''entr\u00e9e proviennent INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES = l''instance de la classe {0} n''est pas comparable aux valeurs existantes INSUFFICIENT_DATA_FOR_T_STATISTIC = deux valeurs ou plus sont n\u00e9cessaires pour la statistique t, il y en a {0} INSUFFICIENT_DIMENSION = dimension {0} insuffisante, elle devrait \u00eatre au moins {1} INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE = l''\u00e9chantillon ne contient que {0} points alors qu''au moins {1} sont n\u00e9cessaires INSUFFICIENT_ROWS_AND_COLUMNS = donn\u00e9es insuffisantes : seulement {0} lignes et {1} colonnes. INTEGRATION_METHOD_NEEDS_AT_LEAST_ONE_PREVIOUS_POINT = la m\u00e9thode {0} n\u00e9cessite au moins un point pr\u00e9c\u00e9dent INTERNAL_ERROR = erreur interne, veuillez signaler l''erreur \u00e0 {0} INVALID_BRACKETING_PARAMETERS = param\u00e8tres d''encadrement invalides : borne inf\u00e9rieure = {0}, valeur initiale = {1}, borne sup\u00e9rieure = {2} INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS = param\u00e8tres de l''intervalle initial invalides : borne inf = {0}, valeur initiale = {1}, borne sup = {2} INVALID_ITERATIONS_LIMITS = limites d''it\u00e9rations invalides : min = {0}, max = {1} INVALID_MAX_ITERATIONS = valeur invalide pour le nombre maximal d''it\u00e9rations : {0} INVALID_REGRESSION_ARRAY= longueur du tableau de donn\u00e9es = {0} ne correspond pas au nombre d'observations = {1} et le nombre de variables explicatives = {2} INVALID_ROUNDING_METHOD = m\u00e9thode d''arondi {0} invalide, m\u00e9thodes valides : {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16}) ITERATOR_EXHAUSTED = it\u00e9ration achev\u00e9e LCM_OVERFLOW_32_BITS = d\u00e9passement de capacit\u00e9 : le MCM de {0} et {1} vaut 2^31 LCM_OVERFLOW_64_BITS = d\u00e9passement de capacit\u00e9 : le MCM de {0} et {1} vaut 2^63 LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE = la liste des chromosomes d\u00e9passe maxPopulationSize LOESS_EXPECTS_AT_LEAST_ONE_POINT = la r\u00e9gression Loess n\u00e9cessite au moins un point LOWER_BOUND_NOT_BELOW_UPPER_BOUND = la borne inf\u00e9rieure ({0}) doit \u00eatre strictement plus petite que la borne sup\u00e9rieure ({1}) LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT = la borne inf\u00e9rieure ({0}) devrait \u00eatre inf\u00e9rieure MAP_MODIFIED_WHILE_ITERATING = la table d''adressage a \u00e9t\u00e9 modifi\u00e9e pendant l''it\u00e9ration MAX_EVALUATIONS_EXCEEDED = nombre maximal d''\u00e9valuations ({0}) d\u00e9pass\u00e9 MAX_ITERATIONS_EXCEEDED = nombre maximal d''it\u00e9rations ({0}) d\u00e9pass\u00e9 MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION = pas minimal ({0,number,0.00E00}) atteint, l''int\u00e9gration n\u00e9cessite {1,number,0.00E00} MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS = Loess a besoin de tableaux d'abscisses et d'oordonn\u00e9es de m\u00eame taille, mais il y a {0} points en abscisse et {1} en ordonn\u00e9e NAN_ELEMENT_AT_INDEX = l''\u00e9l\u00e9ment {0} est un NaN NAN_VALUE_CONVERSION = les valeurs NaN ne peuvent \u00eatre converties NEGATIVE_BRIGHTNESS_EXPONENT = l''exposant de brillance devrait \u00eatre positif ou null, or e = {0} NEGATIVE_COMPLEX_MODULE = module n\u00e9gatif ({0}) pour un nombre complexe NEGATIVE_ELEMENT_AT_2D_INDEX = l''\u00e9l\u00e9ment ({0}, {1}) est n\u00e9gatif : {2} NEGATIVE_ELEMENT_AT_INDEX = l''\u00e9l\u00e9ment {0} est n\u00e9gatif : {1} NEGATIVE_NUMBER_OF_SUCCESSES = le nombre de succ\u00e8s ne doit pas \u00eatre n\u00e9gatif ({0}) NEGATIVE_NUMBER_OF_TRIALS = le nombre d''essais ne doit pas \u00eatre n\u00e9gatif ({0}) NEGATIVE_ROBUSTNESS_ITERATIONS = le nombre d''it\u00e9rations robuste ne peut \u00eatre n\u00e9gatif, alors qu''il est de {0} START_POSITION = position de d\u00e9part NON_CONVERGENT_CONTINUED_FRACTION = \u00c9chec de convergence de fraction continue pour la valeur {0} NON_POSITIVE_MICROSPHERE_ELEMENTS = le nombre d''\u00e9l\u00e9ments de la microsph\u00e8re devrait \u00eatre positif, or n = {0} NON_POSITIVE_POLYNOMIAL_DEGREE = le polyn\u00f4me doit \u00eatre de degr\u00e9 positif : degr\u00e9 = {0} NON_REAL_FINITE_ABSCISSA = toutes les abscisses doivent \u00eatre des nombres r\u00e9els finis, mais l''abscisse {0} vaut {1} NON_REAL_FINITE_ORDINATE = toutes les ordonn\u00e9es doivent \u00eatre des nombres r\u00e9els finis, mais l''ordonn\u00e9e {0} vaut {1} NON_REAL_FINITE_WEIGHT = tous les poids doivent \u00eatre des nombres r\u00e9els finis, mais le poids {0} vaut {1} NON_SQUARE_MATRIX = une matrice {0}x{1} a \u00e9t\u00e9 fournie \u00e0 la place d''une matrice carr\u00e9e NORMALIZE_INFINITE = impossible de normaliser vers une valeur infinie NORMALIZE_NAN = impossible de normaliser vers NaN NOT_ADDITION_COMPATIBLE_MATRICES = les dimensions {0}x{1} et {2}x{3} sont incompatibles pour l''addition matricielle NOT_DECREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas d\u00e9croissants ({2} < {3}) NOT_DECREASING_SEQUENCE = les points {3} et {2} ne sont pas d\u00e9croissants ({1} < {0}) NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS = pas assez de donn\u00e9es ({0} lignes) pour {1} pr\u00e9dicteurs NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION = une partiction spline n\u00e9cessite au moins {0} points, seuls {1} ont \u00e9t\u00e9 fournis NOT_INCREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas croissants ({2} > {3}) NOT_INCREASING_SEQUENCE = les points {3} et {2} ne sont pas croissants ({1} > {0}) NOT_MULTIPLICATION_COMPATIBLE_MATRICES = les dimensions {0}x{1} et {2}x{3} sont incompatibles pour la multiplication matricielle NOT_OVERRIDEN = m\u00e9thode n'est pas remplac\u00e9e NOT_POSITIVE_ALPHA = alpha doit \u00eatre positif ({0}) NOT_POSITIVE_BETA = beta doit \u00eatre positif ({0}) NOT_POSITIVE_COLUMNDIMENSION = nombre de colonnes invalide : {0} (doit \u00eatre positif) NOT_POSITIVE_DEFINITE_MATRIX = matrice non d\u00e9finie positive NOT_POSITIVE_DEGREES_OF_FREEDOM = les degr\u00e9s de libert\u00e9 doivent \u00eatre positifs ({0}) NOT_POSITIVE_ELEMENT_AT_INDEX = l''\u00e9l\u00e9ment {0} n''est pas positif : {1} NOT_POSITIVE_EXPONENT = exposant {0} invalide (doit \u00eatre positif) NOT_POSITIVE_LENGTH = la longueur doit \u00eatre positive ({0}) LENGTH = longueur ({0}) NOT_POSITIVE_MEAN = la moyenne doit \u00eatre positive ({0}) MEAN = moyenne ({0}) NOT_POSITIVE_NUMBER_OF_SAMPLES = le nombre d''\u00e9chantillons n''est pas positif : {0} NUMBER_OF_SAMPLES = nombre d''\u00e9chantillons ({0}) NOT_POSITIVE_PERMUTATION = la permutation k ({0}) doit \u00eatre positive PERMUTATION_SIZE = taille de la permutation NOT_POSITIVE_POISSON_MEAN = la moyenne de Poisson doit \u00eatre positive ({0}) NOT_POSITIVE_POPULATION_SIZE = la taille de la population doit \u00eatre positive ({0}) NOT_POSITIVE_ROW_DIMENSION = nombre de lignes invalide : {0} (doit \u00eatre positif) NOT_POSITIVE_SAMPLE_SIZE = la taille de l''\u00e9chantillon doit \u00eatre positive ({0}) NOT_POSITIVE_SCALE = l''\u00e9chelle doit \u00eatre positive ({0}) NOT_POSITIVE_SHAPE = le facteur de forme doit \u00eatre positif ({0}) NOT_POSITIVE_STANDARD_DEVIATION = l''\u00e9cart type doit \u00eatre positif ({0}) STANDARD_DEVIATION = \u00e9cart type NOT_POSITIVE_UPPER_BOUND = la borne sup\u00e9rieure doit \u00eatre positive ({0}) NOT_POSITIVE_WINDOW_SIZE = la taille de la fen\u00eatre doit \u00eatre positive ({0}) NOT_POWER_OF_TWO = {0} n''est pas une puissance de 2 NOT_POWER_OF_TWO_CONSIDER_PADDING = {0} n''est pas une puissance de 2, ajoutez des \u00e9l\u00e9ments pour corriger NOT_POWER_OF_TWO_PLUS_ONE = {0} n''est pas une puissance de 2 plus un NOT_STRICTLY_DECREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas strictement d\u00e9croissants ({2} <= {3}) NOT_STRICTLY_DECREASING_SEQUENCE = les points {3} et {2} ne sont pas strictement d\u00e9croissants ({1} <= {0}) NOT_STRICTLY_INCREASING_KNOT_VALUES = les n\u0153uds d''interpolation doivent \u00eatre strictement croissants NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas strictement croissants ({2} >= {3}) NOT_STRICTLY_INCREASING_SEQUENCE = les points {3} et {2} ne sont pas strictement croissants ({1} >= {0}) NOT_SUBTRACTION_COMPATIBLE_MATRICES = les dimensions {0}x{1} et {2}x{3} sont incompatibles pour la soustraction matricielle NOT_SYMMETRIC_MATRIX = matrice non symm\u00e9trique NO_BIN_SELECTED = aucun compartiment s\u00e9lectionn\u00e9 NO_CONVERGENCE_WITH_ANY_START_POINT = aucun des {0} points de d\u00e9part n''aboutit \u00e0 une convergence NO_DATA = aucune donn\u00e9e NO_DEGREES_OF_FREEDOM = aucun degr\u00e9 de libert\u00e9 ({0} mesures, {1} param\u00e8tres) NO_DENSITY_FOR_THIS_DISTRIBUTION = La fonction de densit\u00e9 pour cette distribution n''a pas \u00e9t\u00e9 mis en \u0153uvre NO_FEASIBLE_SOLUTION = aucune solution r\u00e9alisable NO_OPTIMUM_COMPUTED_YET = aucun optimum n''a encore \u00e9t\u00e9 calcul\u00e9 NO_RESULT_AVAILABLE = aucun r\u00e9sultat n''est disponible NO_SUCH_MATRIX_ENTRY = pas d''\u00e9l\u00e9ment ({0}, {1}) dans une matrice {2}x{3} NULL_NOT_ALLOWED = "null" n''est pas permis COVARIANCE_MATRIX = matrice de covariance DENOMINATOR = d\u00e9nominateur DENOMINATOR_FORMAT = format du d\u00e9nominateur FRACTION = fraction FUNCTION = fonction IMAGINARY_FORMAT = format de la partie imaginaire INPUT_ARRAY = tableau d''entr\u00e9e NUMERATOR = num\u00e9rateur NUMERATOR_FORMAT = format du num\u00e9rateur OBJECT_TRANSFORMATION = exception de conversion dans une transformation REAL_FORMAT = format de la partie r\u00e9elle WHOLE_FORMAT = format complet NUMBER_TOO_LARGE = {0} est plus grand que le maximum ({1}) NUMBER_TOO_SMALL = {0} est plus petit que le minimum ({1}) NUMBER_TOO_LARGE_BOUND_EXCLUDED = {0} n''est pas strictement plus grand que le maximum ({1}) NUMBER_TOO_SMALL_BOUND_EXCLUDED = {0} n''est pas strictement plus petit que le minimum ({1}) NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE = le nombre de succ\u00e8s ({0}) doit \u00eatre inf\u00e9rieur ou \u00e9gal \u00e0 la taille de la population ({1}) NUMERATOR_OVERFLOW_AFTER_MULTIPLY = d\u00e9passement de capacit\u00e9 pour le num\u00e9rateur apr\u00e8s multiplication : {0} N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED = l''int\u00e9grateur de Legendre-Gauss en {0} points n''est pas disponible, le nombre de points doit \u00eatre entre {1} et {2} OBSERVED_COUNTS_ALL_ZERO = aucune occurrence dans le tableau des observations {0} OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY = les occurrences observ\u00e9es sont toutes deux nulles pour l''entr\u00e9e {0} OUT_OF_BOUNDS_QUANTILE_VALUE = valeur de quantile {0} hors bornes, doit \u00eatre dans l''intervalle ]0, 100] OUT_OF_BOUND_SIGNIFICANCE_LEVEL = niveau de signification {0} hors domaine, doit \u00eatre entre {1} et {2} OUT_OF_ORDER_ABSCISSA_ARRAY = les abscisses doivent \u00eatre en ordre strictement croissant, mais l''\u00e9l\u00e9ment {0} vaut {1} alors que l''\u00e9l\u00e9ment {2} vaut {3} OUT_OF_RANGE_ROOT_OF_UNITY_INDEX = l''indice de racine de l''unit\u00e9 {0} est hors du domaine autoris\u00e9 [{1};{2}] OUT_OF_RANGE_SIMPLE = {0} hors du domaine [{1}, {2}] OVERFLOW_IN_FRACTION = d\u00e9passement de capacit\u00e9 pour la fraction {0}/{1}, son signe ne peut \u00eatre chang\u00e9 OVERFLOW_IN_ADDITION = d\u00e9passement de capacit\u00e9 pour l''addition : {0} + {1} OVERFLOW_IN_SUBTRACTION = d\u00e9passement de capacit\u00e9 pour la soustraction : {0} - {1} PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD = acc\u00e8s impossible \u00e0 la m\u00e9thode {0} PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD = l''implantation de pourcentage {0} ne dispose pas de la m\u00e9thode {1} PERMUTATION_EXCEEDS_N = la taille de la permutation ({0}) d\u00e9passe le domaine de la permutation ({1}) POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS = le nombre d''interpolants polyn\u00f4miaux doit correspondre au nombre de segments ({0} != {1} - 1) POPULATION_LIMIT_NOT_POSITIVE = la limite de population doit \u00eatre positive POSITION_SIZE_MISMATCH_INPUT_ARRAY = la position {0} et la taille {1} sont incompatibles avec la taille du tableau d''entr\u00e9e {2} POWER_NEGATIVE_PARAMETERS = impossible d''\u00e9lever une valeur enti\u00e8re PROPAGATION_DIRECTION_MISMATCH = directions de propagation incoh\u00e9rentes RANDOMKEY_MUTATION_WRONG_CLASS = RandomKeyMutation ne fonctionne qu''avec la classe RandomKeys, pas avec {0} ROOTS_OF_UNITY_NOT_COMPUTED_YET = les racines de l''unit\u00e9 n''ont pas encore \u00e9t\u00e9 calcul\u00e9es ROTATION_MATRIX_DIMENSIONS = une matrice {0}x{1} ne peut pas \u00eatre une matrice de rotation ROW_INDEX_OUT_OF_RANGE = l''index de ligne {0} est hors du domaine autoris\u00e9 [{1}, {2}] SAME_SIGN_AT_ENDPOINTS = les valeurs aux bornes de la fonction devraient avoir des signes difff\u00e9rents ; bornes : [{0}, {1}], valeurs : [{2}, {3}] SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE = la taille de l''\u00e9chantillon ({0}) d\u00e9passe la taille de la collection ({1}) SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE = la taille de l''\u00e9chantillon doit \u00eatre inf\u00e9rieure SIMPLEX_NEED_ONE_POINT = le simplex doit contenir au moins un point SIMPLE_MESSAGE = {0} SINGULAR_MATRIX = matrice singuli\u00e8re SUBARRAY_ENDS_AFTER_ARRAY_END = le sous-tableau se termine apr\u00e8s la fin du tableau TOO_LARGE_CUTOFF_SINGULAR_VALUE = la valeur singuli\u00e8re de coupure vaut {0}, elle ne devrait pas d\u00e9passer {1} TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY = impossible d''enlever {0} \u00e9l\u00e9ments d''un tableau en contenant {1} TOO_SMALL_BANDWIDTH = la largeur de bande doit \u00eatre assez grande pour supporter au moins 2 points. Il y a {0} donn\u00e9es et la largeur de bande doit \u00eatre au moins de {1}, or elle est seulement de {2} TOO_SMALL_COST_RELATIVE_TOLERANCE = trop petite tol\u00e9rance relative sur le co\u00fbt ({0}), aucune r\u00e9duction de la somme des carr\u00e9s n''est possible TOO_SMALL_INTEGRATION_INTERVAL = intervalle d''int\u00e9gration trop petit : {0} TOO_SMALL_ORTHOGONALITY_TOLERANCE = trop petite tol\u00e9rance sur l''orthogonalit\u00e9 ({0}), la solution est orthogonale \u00e0 la jacobienne TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE = trop petite tol\u00e9rance relative sur les param\u00e8tres ({0}), aucune am\u00e9lioration de la solution approximative n''est possible TWO_OR_MORE_CATEGORIES_REQUIRED = deux cat\u00e9gories ou plus sont n\u00e9cessaires, il y en a {0} TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED = deux valeurs ou plus sont n\u00e9cessaires pour chaque cat\u00e9gorie, une cat\u00e9gorie en a {0} UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH = impossible d''encadrer l''optimum lors de la recherche lin\u00e9aire UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM = impossible de calculer les covariances : probl\u00e8me singulier UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS = impossible de faire une premi\u00e8re estimation des coefficients harmoniques UNABLE_TO_ORTHOGONOLIZE_MATRIX = impossible de rendre la matrice orthogonale en {0} it\u00e9rations UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN = impossible de calculer la factorisation Q.R de la matrice jacobienne {0}x{1} UNABLE_TO_SOLVE_SINGULAR_PROBLEM = r\u00e9solution impossible : probl\u00e8me singulier UNBOUNDED_SOLUTION = solution non born\u00e9e UNKNOWN_MODE = mode {0} inconnu, modes connus : {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) et {11} ({12}) UNPARSEABLE_3D_VECTOR = vecteur 3D non analysable : "{0}" UNPARSEABLE_COMPLEX_NUMBER = nombre complexe non analysable : "{0}" UNPARSEABLE_FRACTION_NUMBER = nombre fractionnaire non analysable : "{0}" UNPARSEABLE_REAL_VECTOR = vecteur r\u00e9el non analysable : "{0}" UNSUPPORTED_EXPANSION_MODE = mode d''extension {0} non support\u00e9, les modes support\u00e9s sont {1} ({2}) et {3} ({4}) UNSUPPORTED_OPERATION = op\u00e9ration non disponible URL_CONTAINS_NO_DATA = l''adresse {0} ne contient aucune donn\u00e9e VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC = {0} valeurs ont \u00e9t\u00e9 ajout\u00e9es VECTOR_LENGTH_MISMATCH = taille de vecteur invalide : {0} au lieu de {1} attendue VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT = un vecteur doit comporter au moins un \u00e9l\u00e9ment WEIGHT_AT_LEAST_ONE_NON_ZERO = le tableau des poids doit contenir au moins une valeur non nulle WRONG_BLOCK_LENGTH = forme de tableau erron\u00e9e (bloc de longueur {0} au lieu des {1} attendus WRONG_NUMBER_OF_POINTS = {0} sont n\u00e9cessaires, seuls {1} ont \u00e9t\u00e9 fournis NUMBER_OF_POINTS = nombre de points ({0}) ZERO_DENOMINATOR = le d\u00e9nominateur doit \u00eatre diff\u00e9rent de 0 ZERO_DENOMINATOR_IN_FRACTION = d\u00e9nominateur null dans le nombre rationnel {0}/{1} ZERO_FRACTION_TO_DIVIDE_BY = division par un nombre rationnel nul : {0}/{1} ZERO_NORM = norme nulle ZERO_NORM_FOR_ROTATION_AXIS = norme nulle pour un axe de rotation ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR = norme nulle pour un axe de d\u00e9finition de rotation ZERO_NOT_ALLOWED = la valeur z\u00e9ro n''est pas autoris\u00e9e ici commons-math-2.2-src/src/main/resources/templates/math-release-notes.vm100644 1750 1750 6167 11532241247 25074 0ustarlucluc 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Apache ${project.name} ${version} RELEASE NOTES ## Hack to improve layout: replace all pairs of spaces with a single new-line $release.description.replaceAll(" ", " ") #if ($release.getActions().size() == 0) No changes defined in this version. #else Changes in this version include: #if ($release.getActions('add').size() !=0) New features: #foreach($actionItem in $release.getActions('add')) #set($action=$actionItem.getAction()) #if ($actionItem.getIssue()) #set($issue=$actionItem.getIssue()) #else #set($issue="") #end #if ($actionItem.getDueTo()) #set($dueto=$actionItem.getDueTo()) #else #set($dueto="") #end o#if($!issue != "") $issue: #end ${action} #if($!dueto != "")Thanks to $dueto. #end #set($issue="") #set($dueto="") #end #end #if ($release.getActions('fix').size() !=0) Fixed Bugs: #foreach($actionItem in $release.getActions('fix')) #set($action=$actionItem.getAction()) #if ($actionItem.getIssue()) #set($issue=$actionItem.getIssue()) #else #set($issue="") #end #if ($actionItem.getDueTo()) #set($dueto=$actionItem.getDueTo()) #else #set($dueto="") #end o#if($!issue != "") $issue: #end ${action} #if($!dueto != "")Thanks to $dueto. #end #set($issue="") #set($dueto="") #end #end #if ($release.getActions('update').size() !=0) Changes: #foreach($actionItem in $release.getActions('update')) #set($action=$actionItem.getAction()) #if ($actionItem.getIssue()) #set($issue=$actionItem.getIssue()) #else #set($issue="") #end #if ($actionItem.getDueTo()) #set($dueto=$actionItem.getDueTo()) #else #set($dueto="") #end o#if($!issue != "") $issue: #end ${action} #if($!dueto != "")Thanks to $dueto. #end #set($issue="") #set($dueto="") #end #end #if ($release.getActions('remove').size() !=0) Removed: #foreach($actionItem in $release.getActions('remove')) #set($action=$actionItem.getAction()) #if ($actionItem.getIssue()) #set($issue=$actionItem.getIssue()) #else #set($issue="") #end #if ($actionItem.getDueTo()) #set($dueto=$actionItem.getDueTo()) #else #set($dueto="") #end o#if($!issue != "") $issue. #end ${action} #if($!dueto != "")Thanks to $dueto. #end #set($issue="") #set($dueto="") #end #end ## End of main loop #end For complete information on ${project.name}, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache ${project.name} website: ${project.url} commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/EstimationException.java100644 1750 1750 4360 11532241245 31361 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * This class represents exceptions thrown by the estimation solvers. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public class EstimationException extends MathException { /** Serializable version identifier. */ private static final long serialVersionUID = -573038581493881337L; /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) */ public EstimationException(String specifier, Object ... parts) { this(new DummyLocalizable(specifier), parts); } /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public EstimationException(Localizable specifier, Object ... parts) { super(specifier, parts); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/EstimationProblem.java100644 1750 1750 5052 11532241245 31022 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; /** * This interface represents an estimation problem. * *

                  This interface should be implemented by all real estimation * problems before they can be handled by the estimators through the * {@link Estimator#estimate Estimator.estimate} method.

                  * *

                  An estimation problem, as seen by a solver is a set of * parameters and a set of measurements. The parameters are adjusted * during the estimation through the {@link #getUnboundParameters * getUnboundParameters} and {@link EstimatedParameter#setEstimate * EstimatedParameter.setEstimate} methods. The measurements both have * a measured value which is generally fixed at construction and a * theoretical value which depends on the model and hence varies as * the parameters are adjusted. The purpose of the solver is to reduce * the residual between these values, it can retrieve the measurements * through the {@link #getMeasurements getMeasurements} method.

                  * * @see Estimator * @see WeightedMeasurement * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public interface EstimationProblem { /** * Get the measurements of an estimation problem. * @return measurements */ WeightedMeasurement[] getMeasurements(); /** * Get the unbound parameters of the problem. * @return unbound parameters */ EstimatedParameter[] getUnboundParameters(); /** * Get all the parameters of the problem. * @return parameters */ EstimatedParameter[] getAllParameters(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java100644 1750 1750 22423 11532241245 31553 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.io.Serializable; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.InvalidMatrixException; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.linear.ArrayRealVector; import org.apache.commons.math.util.FastMath; /** * This class implements a solver for estimation problems. * *

                  This class solves estimation problems using a weighted least * squares criterion on the measurement residuals. It uses a * Gauss-Newton algorithm.

                  * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public class GaussNewtonEstimator extends AbstractEstimator implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 5485001826076289109L; /** Default threshold for cost steady state detection. */ private static final double DEFAULT_STEADY_STATE_THRESHOLD = 1.0e-6; /** Default threshold for cost convergence. */ private static final double DEFAULT_CONVERGENCE = 1.0e-6; /** Threshold for cost steady state detection. */ private double steadyStateThreshold; /** Threshold for cost convergence. */ private double convergence; /** Simple constructor with default settings. *

                  * The estimator is built with default values for all settings. *

                  * @see #DEFAULT_STEADY_STATE_THRESHOLD * @see #DEFAULT_CONVERGENCE * @see AbstractEstimator#DEFAULT_MAX_COST_EVALUATIONS */ public GaussNewtonEstimator() { this.steadyStateThreshold = DEFAULT_STEADY_STATE_THRESHOLD; this.convergence = DEFAULT_CONVERGENCE; } /** * Simple constructor. * *

                  This constructor builds an estimator and stores its convergence * characteristics.

                  * *

                  An estimator is considered to have converged whenever either * the criterion goes below a physical threshold under which * improvements are considered useless or when the algorithm is * unable to improve it (even if it is still high). The first * condition that is met stops the iterations.

                  * *

                  The fact an estimator has converged does not mean that the * model accurately fits the measurements. It only means no better * solution can be found, it does not mean this one is good. Such an * analysis is left to the caller.

                  * *

                  If neither conditions are fulfilled before a given number of * iterations, the algorithm is considered to have failed and an * {@link EstimationException} is thrown.

                  * * @param maxCostEval maximal number of cost evaluations allowed * @param convergence criterion threshold below which we do not need * to improve the criterion anymore * @param steadyStateThreshold steady state detection threshold, the * problem has converged has reached a steady state if * FastMath.abs(Jn - Jn-1) < * Jn × convergence, where Jn * and Jn-1 are the current and preceding criterion * values (square sum of the weighted residuals of considered measurements). */ public GaussNewtonEstimator(final int maxCostEval, final double convergence, final double steadyStateThreshold) { setMaxCostEval(maxCostEval); this.steadyStateThreshold = steadyStateThreshold; this.convergence = convergence; } /** * Set the convergence criterion threshold. * @param convergence criterion threshold below which we do not need * to improve the criterion anymore */ public void setConvergence(final double convergence) { this.convergence = convergence; } /** * Set the steady state detection threshold. *

                  * The problem has converged has reached a steady state if * FastMath.abs(Jn - Jn-1) < * Jn × convergence, where Jn * and Jn-1 are the current and preceding criterion * values (square sum of the weighted residuals of considered measurements). *

                  * @param steadyStateThreshold steady state detection threshold */ public void setSteadyStateThreshold(final double steadyStateThreshold) { this.steadyStateThreshold = steadyStateThreshold; } /** * Solve an estimation problem using a least squares criterion. * *

                  This method set the unbound parameters of the given problem * starting from their current values through several iterations. At * each step, the unbound parameters are changed in order to * minimize a weighted least square criterion based on the * measurements of the problem.

                  * *

                  The iterations are stopped either when the criterion goes * below a physical threshold under which improvement are considered * useless or when the algorithm is unable to improve it (even if it * is still high). The first condition that is met stops the * iterations. If the convergence it not reached before the maximum * number of iterations, an {@link EstimationException} is * thrown.

                  * * @param problem estimation problem to solve * @exception EstimationException if the problem cannot be solved * * @see EstimationProblem * */ @Override public void estimate(EstimationProblem problem) throws EstimationException { initializeEstimate(problem); // work matrices double[] grad = new double[parameters.length]; ArrayRealVector bDecrement = new ArrayRealVector(parameters.length); double[] bDecrementData = bDecrement.getDataRef(); RealMatrix wGradGradT = MatrixUtils.createRealMatrix(parameters.length, parameters.length); // iterate until convergence is reached double previous = Double.POSITIVE_INFINITY; do { // build the linear problem incrementJacobianEvaluationsCounter(); RealVector b = new ArrayRealVector(parameters.length); RealMatrix a = MatrixUtils.createRealMatrix(parameters.length, parameters.length); for (int i = 0; i < measurements.length; ++i) { if (! measurements [i].isIgnored()) { double weight = measurements[i].getWeight(); double residual = measurements[i].getResidual(); // compute the normal equation for (int j = 0; j < parameters.length; ++j) { grad[j] = measurements[i].getPartial(parameters[j]); bDecrementData[j] = weight * residual * grad[j]; } // build the contribution matrix for measurement i for (int k = 0; k < parameters.length; ++k) { double gk = grad[k]; for (int l = 0; l < parameters.length; ++l) { wGradGradT.setEntry(k, l, weight * gk * grad[l]); } } // update the matrices a = a.add(wGradGradT); b = b.add(bDecrement); } } try { // solve the linearized least squares problem RealVector dX = new LUDecompositionImpl(a).getSolver().solve(b); // update the estimated parameters for (int i = 0; i < parameters.length; ++i) { parameters[i].setEstimate(parameters[i].getEstimate() + dX.getEntry(i)); } } catch(InvalidMatrixException e) { throw new EstimationException(LocalizedFormats.UNABLE_TO_SOLVE_SINGULAR_PROBLEM); } previous = cost; updateResidualsAndCost(); } while ((getCostEvaluations() < 2) || (FastMath.abs(previous - cost) > (cost * steadyStateThreshold) && (FastMath.abs(cost) > convergence))); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/EstimatedParameter.java100644 1750 1750 10114 11532241245 31160 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.io.Serializable; /** This class represents the estimated parameters of an estimation problem. * *

                  The parameters of an estimation problem have a name, a value and * a bound flag. The value of bound parameters is considered trusted * and the solvers should not adjust them. On the other hand, the * solvers should adjust the value of unbounds parameters until they * satisfy convergence criterions specific to each solver.

                  * * @version $Revision: 922710 $ $Date: 2010-03-14 02:20:56 +0100 (dim. 14 mars 2010) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public class EstimatedParameter implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -555440800213416949L; /** Current value of the parameter */ protected double estimate; /** Name of the parameter */ private final String name; /** Indicator for bound parameters * (ie parameters that should not be estimated) */ private boolean bound; /** Simple constructor. * Build an instance from a first estimate of the parameter, * initially considered unbound. * @param name name of the parameter * @param firstEstimate first estimate of the parameter */ public EstimatedParameter(String name, double firstEstimate) { this.name = name; estimate = firstEstimate; bound = false; } /** Simple constructor. * Build an instance from a first estimate of the parameter and a * bound flag * @param name name of the parameter * @param firstEstimate first estimate of the parameter * @param bound flag, should be true if the parameter is bound */ public EstimatedParameter(String name, double firstEstimate, boolean bound) { this.name = name; estimate = firstEstimate; this.bound = bound; } /** Copy constructor. * Build a copy of a parameter * @param parameter instance to copy */ public EstimatedParameter(EstimatedParameter parameter) { name = parameter.name; estimate = parameter.estimate; bound = parameter.bound; } /** Set a new estimated value for the parameter. * @param estimate new estimate for the parameter */ public void setEstimate(double estimate) { this.estimate = estimate; } /** Get the current estimate of the parameter * @return current estimate */ public double getEstimate() { return estimate; } /** get the name of the parameter * @return parameter name */ public String getName() { return name; } /** Set the bound flag of the parameter * @param bound this flag should be set to true if the parameter is * bound (i.e. if it should not be adjusted by the solver). */ public void setBound(boolean bound) { this.bound = bound; } /** Check if the parameter is bound * @return true if the parameter is bound */ public boolean isBound() { return bound; } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.ja100644 1750 1750 76005 11532241245 32546 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * This class solves a least squares problem. * *

                  This implementation should work even for over-determined systems * (i.e. systems having more variables than equations). Over-determined systems * are solved by ignoring the variables which have the smallest impact according * to their jacobian column norm. Only the rank of the matrix and some loop bounds * are changed to implement this.

                  * *

                  The resolution engine is a simple translation of the MINPACK lmder routine with minor * changes. The changes include the over-determined resolution and the Q.R. * decomposition which has been rewritten following the algorithm described in the * P. Lascaux and R. Theodor book Analyse numérique matricielle * appliquée à l'art de l'ingénieur, Masson 1986.

                  *

                  The authors of the original fortran version are: *

                    *
                  • Argonne National Laboratory. MINPACK project. March 1980
                  • *
                  • Burton S. Garbow
                  • *
                  • Kenneth E. Hillstrom
                  • *
                  • Jorge J. More
                  • *
                  * The redistribution policy for MINPACK is available here, for convenience, it * is reproduced below.

                  * * * * *
                  * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
                  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                    *
                  1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
                  2. *
                  3. 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.
                  4. *
                  5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
                  6. *
                  7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
                  8. *
                  9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
                  10. *
                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public class LevenbergMarquardtEstimator extends AbstractEstimator implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -5705952631533171019L; /** Number of solved variables. */ private int solvedCols; /** Diagonal elements of the R matrix in the Q.R. decomposition. */ private double[] diagR; /** Norms of the columns of the jacobian matrix. */ private double[] jacNorm; /** Coefficients of the Householder transforms vectors. */ private double[] beta; /** Columns permutation array. */ private int[] permutation; /** Rank of the jacobian matrix. */ private int rank; /** Levenberg-Marquardt parameter. */ private double lmPar; /** Parameters evolution direction associated with lmPar. */ private double[] lmDir; /** Positive input variable used in determining the initial step bound. */ private double initialStepBoundFactor; /** Desired relative error in the sum of squares. */ private double costRelativeTolerance; /** Desired relative error in the approximate solution parameters. */ private double parRelativeTolerance; /** Desired max cosine on the orthogonality between the function vector * and the columns of the jacobian. */ private double orthoTolerance; /** * Build an estimator for least squares problems. *

                    The default values for the algorithm settings are: *

                      *
                    • {@link #setInitialStepBoundFactor initial step bound factor}: 100.0
                    • *
                    • {@link #setMaxCostEval maximal cost evaluations}: 1000
                    • *
                    • {@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10
                    • *
                    • {@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10
                    • *
                    • {@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10
                    • *
                    *

                    */ public LevenbergMarquardtEstimator() { // set up the superclass with a default max cost evaluations setting setMaxCostEval(1000); // default values for the tuning parameters setInitialStepBoundFactor(100.0); setCostRelativeTolerance(1.0e-10); setParRelativeTolerance(1.0e-10); setOrthoTolerance(1.0e-10); } /** * Set the positive input variable used in determining the initial step bound. * This bound is set to the product of initialStepBoundFactor and the euclidean norm of diag*x if nonzero, * or else to initialStepBoundFactor itself. In most cases factor should lie * in the interval (0.1, 100.0). 100.0 is a generally recommended value * * @param initialStepBoundFactor initial step bound factor * @see #estimate */ public void setInitialStepBoundFactor(double initialStepBoundFactor) { this.initialStepBoundFactor = initialStepBoundFactor; } /** * Set the desired relative error in the sum of squares. * * @param costRelativeTolerance desired relative error in the sum of squares * @see #estimate */ public void setCostRelativeTolerance(double costRelativeTolerance) { this.costRelativeTolerance = costRelativeTolerance; } /** * Set the desired relative error in the approximate solution parameters. * * @param parRelativeTolerance desired relative error * in the approximate solution parameters * @see #estimate */ public void setParRelativeTolerance(double parRelativeTolerance) { this.parRelativeTolerance = parRelativeTolerance; } /** * Set the desired max cosine on the orthogonality. * * @param orthoTolerance desired max cosine on the orthogonality * between the function vector and the columns of the jacobian * @see #estimate */ public void setOrthoTolerance(double orthoTolerance) { this.orthoTolerance = orthoTolerance; } /** * Solve an estimation problem using the Levenberg-Marquardt algorithm. *

                    The algorithm used is a modified Levenberg-Marquardt one, based * on the MINPACK lmder * routine. The algorithm settings must have been set up before this method * is called with the {@link #setInitialStepBoundFactor}, * {@link #setMaxCostEval}, {@link #setCostRelativeTolerance}, * {@link #setParRelativeTolerance} and {@link #setOrthoTolerance} methods. * If these methods have not been called, the default values set up by the * {@link #LevenbergMarquardtEstimator() constructor} will be used.

                    *

                    The authors of the original fortran function are:

                    *
                      *
                    • Argonne National Laboratory. MINPACK project. March 1980
                    • *
                    • Burton S. Garbow
                    • *
                    • Kenneth E. Hillstrom
                    • *
                    • Jorge J. More
                    • *
                    *

                    Luc Maisonobe did the Java translation.

                    * * @param problem estimation problem to solve * @exception EstimationException if convergence cannot be * reached with the specified algorithm settings or if there are more variables * than equations * @see #setInitialStepBoundFactor * @see #setCostRelativeTolerance * @see #setParRelativeTolerance * @see #setOrthoTolerance */ @Override public void estimate(EstimationProblem problem) throws EstimationException { initializeEstimate(problem); // arrays shared with the other private methods solvedCols = FastMath.min(rows, cols); diagR = new double[cols]; jacNorm = new double[cols]; beta = new double[cols]; permutation = new int[cols]; lmDir = new double[cols]; // local variables double delta = 0; double xNorm = 0; double[] diag = new double[cols]; double[] oldX = new double[cols]; double[] oldRes = new double[rows]; double[] work1 = new double[cols]; double[] work2 = new double[cols]; double[] work3 = new double[cols]; // evaluate the function at the starting point and calculate its norm updateResidualsAndCost(); // outer loop lmPar = 0; boolean firstIteration = true; while (true) { // compute the Q.R. decomposition of the jacobian matrix updateJacobian(); qrDecomposition(); // compute Qt.res qTy(residuals); // now we don't need Q anymore, // so let jacobian contain the R matrix with its diagonal elements for (int k = 0; k < solvedCols; ++k) { int pk = permutation[k]; jacobian[k * cols + pk] = diagR[pk]; } if (firstIteration) { // scale the variables according to the norms of the columns // of the initial jacobian xNorm = 0; for (int k = 0; k < cols; ++k) { double dk = jacNorm[k]; if (dk == 0) { dk = 1.0; } double xk = dk * parameters[k].getEstimate(); xNorm += xk * xk; diag[k] = dk; } xNorm = FastMath.sqrt(xNorm); // initialize the step bound delta delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm); } // check orthogonality between function vector and jacobian columns double maxCosine = 0; if (cost != 0) { for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double s = jacNorm[pj]; if (s != 0) { double sum = 0; int index = pj; for (int i = 0; i <= j; ++i) { sum += jacobian[index] * residuals[i]; index += cols; } maxCosine = FastMath.max(maxCosine, FastMath.abs(sum) / (s * cost)); } } } if (maxCosine <= orthoTolerance) { return; } // rescale if necessary for (int j = 0; j < cols; ++j) { diag[j] = FastMath.max(diag[j], jacNorm[j]); } // inner loop for (double ratio = 0; ratio < 1.0e-4;) { // save the state for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; oldX[pj] = parameters[pj].getEstimate(); } double previousCost = cost; double[] tmpVec = residuals; residuals = oldRes; oldRes = tmpVec; // determine the Levenberg-Marquardt parameter determineLMParameter(oldRes, delta, diag, work1, work2, work3); // compute the new point and the norm of the evolution direction double lmNorm = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; lmDir[pj] = -lmDir[pj]; parameters[pj].setEstimate(oldX[pj] + lmDir[pj]); double s = diag[pj] * lmDir[pj]; lmNorm += s * s; } lmNorm = FastMath.sqrt(lmNorm); // on the first iteration, adjust the initial step bound. if (firstIteration) { delta = FastMath.min(delta, lmNorm); } // evaluate the function at x + p and calculate its norm updateResidualsAndCost(); // compute the scaled actual reduction double actRed = -1.0; if (0.1 * cost < previousCost) { double r = cost / previousCost; actRed = 1.0 - r * r; } // compute the scaled predicted reduction // and the scaled directional derivative for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double dirJ = lmDir[pj]; work1[j] = 0; int index = pj; for (int i = 0; i <= j; ++i) { work1[i] += jacobian[index] * dirJ; index += cols; } } double coeff1 = 0; for (int j = 0; j < solvedCols; ++j) { coeff1 += work1[j] * work1[j]; } double pc2 = previousCost * previousCost; coeff1 = coeff1 / pc2; double coeff2 = lmPar * lmNorm * lmNorm / pc2; double preRed = coeff1 + 2 * coeff2; double dirDer = -(coeff1 + coeff2); // ratio of the actual to the predicted reduction ratio = (preRed == 0) ? 0 : (actRed / preRed); // update the step bound if (ratio <= 0.25) { double tmp = (actRed < 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5; if ((0.1 * cost >= previousCost) || (tmp < 0.1)) { tmp = 0.1; } delta = tmp * FastMath.min(delta, 10.0 * lmNorm); lmPar /= tmp; } else if ((lmPar == 0) || (ratio >= 0.75)) { delta = 2 * lmNorm; lmPar *= 0.5; } // test for successful iteration. if (ratio >= 1.0e-4) { // successful iteration, update the norm firstIteration = false; xNorm = 0; for (int k = 0; k < cols; ++k) { double xK = diag[k] * parameters[k].getEstimate(); xNorm += xK * xK; } xNorm = FastMath.sqrt(xNorm); } else { // failed iteration, reset the previous values cost = previousCost; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; parameters[pj].setEstimate(oldX[pj]); } tmpVec = residuals; residuals = oldRes; oldRes = tmpVec; } // tests for convergence. if (((FastMath.abs(actRed) <= costRelativeTolerance) && (preRed <= costRelativeTolerance) && (ratio <= 2.0)) || (delta <= parRelativeTolerance * xNorm)) { return; } // tests for termination and stringent tolerances // (2.2204e-16 is the machine epsilon for IEEE754) if ((FastMath.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) { throw new EstimationException("cost relative tolerance is too small ({0})," + " no further reduction in the" + " sum of squares is possible", costRelativeTolerance); } else if (delta <= 2.2204e-16 * xNorm) { throw new EstimationException("parameters relative tolerance is too small" + " ({0}), no further improvement in" + " the approximate solution is possible", parRelativeTolerance); } else if (maxCosine <= 2.2204e-16) { throw new EstimationException("orthogonality tolerance is too small ({0})," + " solution is orthogonal to the jacobian", orthoTolerance); } } } } /** * Determine the Levenberg-Marquardt parameter. *

                    This implementation is a translation in Java of the MINPACK * lmpar * routine.

                    *

                    This method sets the lmPar and lmDir attributes.

                    *

                    The authors of the original fortran function are:

                    *
                      *
                    • Argonne National Laboratory. MINPACK project. March 1980
                    • *
                    • Burton S. Garbow
                    • *
                    • Kenneth E. Hillstrom
                    • *
                    • Jorge J. More
                    • *
                    *

                    Luc Maisonobe did the Java translation.

                    * * @param qy array containing qTy * @param delta upper bound on the euclidean norm of diagR * lmDir * @param diag diagonal matrix * @param work1 work array * @param work2 work array * @param work3 work array */ private void determineLMParameter(double[] qy, double delta, double[] diag, double[] work1, double[] work2, double[] work3) { // compute and store in x the gauss-newton direction, if the // jacobian is rank-deficient, obtain a least squares solution for (int j = 0; j < rank; ++j) { lmDir[permutation[j]] = qy[j]; } for (int j = rank; j < cols; ++j) { lmDir[permutation[j]] = 0; } for (int k = rank - 1; k >= 0; --k) { int pk = permutation[k]; double ypk = lmDir[pk] / diagR[pk]; int index = pk; for (int i = 0; i < k; ++i) { lmDir[permutation[i]] -= ypk * jacobian[index]; index += cols; } lmDir[pk] = ypk; } // evaluate the function at the origin, and test // for acceptance of the Gauss-Newton direction double dxNorm = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double s = diag[pj] * lmDir[pj]; work1[pj] = s; dxNorm += s * s; } dxNorm = FastMath.sqrt(dxNorm); double fp = dxNorm - delta; if (fp <= 0.1 * delta) { lmPar = 0; return; } // if the jacobian is not rank deficient, the Newton step provides // a lower bound, parl, for the zero of the function, // otherwise set this bound to zero double sum2; double parl = 0; if (rank == solvedCols) { for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] *= diag[pj] / dxNorm; } sum2 = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double sum = 0; int index = pj; for (int i = 0; i < j; ++i) { sum += jacobian[index] * work1[permutation[i]]; index += cols; } double s = (work1[pj] - sum) / diagR[pj]; work1[pj] = s; sum2 += s * s; } parl = fp / (delta * sum2); } // calculate an upper bound, paru, for the zero of the function sum2 = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double sum = 0; int index = pj; for (int i = 0; i <= j; ++i) { sum += jacobian[index] * qy[i]; index += cols; } sum /= diag[pj]; sum2 += sum * sum; } double gNorm = FastMath.sqrt(sum2); double paru = gNorm / delta; if (paru == 0) { // 2.2251e-308 is the smallest positive real for IEE754 paru = 2.2251e-308 / FastMath.min(delta, 0.1); } // if the input par lies outside of the interval (parl,paru), // set par to the closer endpoint lmPar = FastMath.min(paru, FastMath.max(lmPar, parl)); if (lmPar == 0) { lmPar = gNorm / dxNorm; } for (int countdown = 10; countdown >= 0; --countdown) { // evaluate the function at the current value of lmPar if (lmPar == 0) { lmPar = FastMath.max(2.2251e-308, 0.001 * paru); } double sPar = FastMath.sqrt(lmPar); for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] = sPar * diag[pj]; } determineLMDirection(qy, work1, work2, work3); dxNorm = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double s = diag[pj] * lmDir[pj]; work3[pj] = s; dxNorm += s * s; } dxNorm = FastMath.sqrt(dxNorm); double previousFP = fp; fp = dxNorm - delta; // if the function is small enough, accept the current value // of lmPar, also test for the exceptional cases where parl is zero if ((FastMath.abs(fp) <= 0.1 * delta) || ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) { return; } // compute the Newton correction for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] = work3[pj] * diag[pj] / dxNorm; } for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] /= work2[j]; double tmp = work1[pj]; for (int i = j + 1; i < solvedCols; ++i) { work1[permutation[i]] -= jacobian[i * cols + pj] * tmp; } } sum2 = 0; for (int j = 0; j < solvedCols; ++j) { double s = work1[permutation[j]]; sum2 += s * s; } double correction = fp / (delta * sum2); // depending on the sign of the function, update parl or paru. if (fp > 0) { parl = FastMath.max(parl, lmPar); } else if (fp < 0) { paru = FastMath.min(paru, lmPar); } // compute an improved estimate for lmPar lmPar = FastMath.max(parl, lmPar + correction); } } /** * Solve a*x = b and d*x = 0 in the least squares sense. *

                    This implementation is a translation in Java of the MINPACK * qrsolv * routine.

                    *

                    This method sets the lmDir and lmDiag attributes.

                    *

                    The authors of the original fortran function are:

                    *
                      *
                    • Argonne National Laboratory. MINPACK project. March 1980
                    • *
                    • Burton S. Garbow
                    • *
                    • Kenneth E. Hillstrom
                    • *
                    • Jorge J. More
                    • *
                    *

                    Luc Maisonobe did the Java translation.

                    * * @param qy array containing qTy * @param diag diagonal matrix * @param lmDiag diagonal elements associated with lmDir * @param work work array */ private void determineLMDirection(double[] qy, double[] diag, double[] lmDiag, double[] work) { // copy R and Qty to preserve input and initialize s // in particular, save the diagonal elements of R in lmDir for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; for (int i = j + 1; i < solvedCols; ++i) { jacobian[i * cols + pj] = jacobian[j * cols + permutation[i]]; } lmDir[j] = diagR[pj]; work[j] = qy[j]; } // eliminate the diagonal matrix d using a Givens rotation for (int j = 0; j < solvedCols; ++j) { // prepare the row of d to be eliminated, locating the // diagonal element using p from the Q.R. factorization int pj = permutation[j]; double dpj = diag[pj]; if (dpj != 0) { Arrays.fill(lmDiag, j + 1, lmDiag.length, 0); } lmDiag[j] = dpj; // the transformations to eliminate the row of d // modify only a single element of Qty // beyond the first n, which is initially zero. double qtbpj = 0; for (int k = j; k < solvedCols; ++k) { int pk = permutation[k]; // determine a Givens rotation which eliminates the // appropriate element in the current row of d if (lmDiag[k] != 0) { final double sin; final double cos; double rkk = jacobian[k * cols + pk]; if (FastMath.abs(rkk) < FastMath.abs(lmDiag[k])) { final double cotan = rkk / lmDiag[k]; sin = 1.0 / FastMath.sqrt(1.0 + cotan * cotan); cos = sin * cotan; } else { final double tan = lmDiag[k] / rkk; cos = 1.0 / FastMath.sqrt(1.0 + tan * tan); sin = cos * tan; } // compute the modified diagonal element of R and // the modified element of (Qty,0) jacobian[k * cols + pk] = cos * rkk + sin * lmDiag[k]; final double temp = cos * work[k] + sin * qtbpj; qtbpj = -sin * work[k] + cos * qtbpj; work[k] = temp; // accumulate the tranformation in the row of s for (int i = k + 1; i < solvedCols; ++i) { double rik = jacobian[i * cols + pk]; final double temp2 = cos * rik + sin * lmDiag[i]; lmDiag[i] = -sin * rik + cos * lmDiag[i]; jacobian[i * cols + pk] = temp2; } } } // store the diagonal element of s and restore // the corresponding diagonal element of R int index = j * cols + permutation[j]; lmDiag[j] = jacobian[index]; jacobian[index] = lmDir[j]; } // solve the triangular system for z, if the system is // singular, then obtain a least squares solution int nSing = solvedCols; for (int j = 0; j < solvedCols; ++j) { if ((lmDiag[j] == 0) && (nSing == solvedCols)) { nSing = j; } if (nSing < solvedCols) { work[j] = 0; } } if (nSing > 0) { for (int j = nSing - 1; j >= 0; --j) { int pj = permutation[j]; double sum = 0; for (int i = j + 1; i < nSing; ++i) { sum += jacobian[i * cols + pj] * work[i]; } work[j] = (work[j] - sum) / lmDiag[j]; } } // permute the components of z back to components of lmDir for (int j = 0; j < lmDir.length; ++j) { lmDir[permutation[j]] = work[j]; } } /** * Decompose a matrix A as A.P = Q.R using Householder transforms. *

                    As suggested in the P. Lascaux and R. Theodor book * Analyse numérique matricielle appliquée à * l'art de l'ingénieur (Masson, 1986), instead of representing * the Householder transforms with uk unit vectors such that: *

                       * Hk = I - 2uk.ukt
                       * 
                    * we use k non-unit vectors such that: *
                       * Hk = I - betakvk.vkt
                       * 
                    * where vk = ak - alphak ek. * The betak coefficients are provided upon exit as recomputing * them from the vk vectors would be costly.

                    *

                    This decomposition handles rank deficient cases since the tranformations * are performed in non-increasing columns norms order thanks to columns * pivoting. The diagonal elements of the R matrix are therefore also in * non-increasing absolute values order.

                    * @exception EstimationException if the decomposition cannot be performed */ private void qrDecomposition() throws EstimationException { // initializations for (int k = 0; k < cols; ++k) { permutation[k] = k; double norm2 = 0; for (int index = k; index < jacobian.length; index += cols) { double akk = jacobian[index]; norm2 += akk * akk; } jacNorm[k] = FastMath.sqrt(norm2); } // transform the matrix column after column for (int k = 0; k < cols; ++k) { // select the column with the greatest norm on active components int nextColumn = -1; double ak2 = Double.NEGATIVE_INFINITY; for (int i = k; i < cols; ++i) { double norm2 = 0; int iDiag = k * cols + permutation[i]; for (int index = iDiag; index < jacobian.length; index += cols) { double aki = jacobian[index]; norm2 += aki * aki; } if (Double.isInfinite(norm2) || Double.isNaN(norm2)) { throw new EstimationException( LocalizedFormats.UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN, rows, cols); } if (norm2 > ak2) { nextColumn = i; ak2 = norm2; } } if (ak2 == 0) { rank = k; return; } int pk = permutation[nextColumn]; permutation[nextColumn] = permutation[k]; permutation[k] = pk; // choose alpha such that Hk.u = alpha ek int kDiag = k * cols + pk; double akk = jacobian[kDiag]; double alpha = (akk > 0) ? -FastMath.sqrt(ak2) : FastMath.sqrt(ak2); double betak = 1.0 / (ak2 - akk * alpha); beta[pk] = betak; // transform the current column diagR[pk] = alpha; jacobian[kDiag] -= alpha; // transform the remaining columns for (int dk = cols - 1 - k; dk > 0; --dk) { int dkp = permutation[k + dk] - pk; double gamma = 0; for (int index = kDiag; index < jacobian.length; index += cols) { gamma += jacobian[index] * jacobian[index + dkp]; } gamma *= betak; for (int index = kDiag; index < jacobian.length; index += cols) { jacobian[index + dkp] -= gamma * jacobian[index]; } } } rank = solvedCols; } /** * Compute the product Qt.y for some Q.R. decomposition. * * @param y vector to multiply (will be overwritten with the result) */ private void qTy(double[] y) { for (int k = 0; k < cols; ++k) { int pk = permutation[k]; int kDiag = k * cols + pk; double gamma = 0; int index = kDiag; for (int i = k; i < rows; ++i) { gamma += jacobian[index] * y[i]; index += cols; } gamma *= beta[pk]; index = kDiag; for (int i = k; i < rows; ++i) { y[i] -= gamma * jacobian[index]; index += cols; } } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/package.html100644 1750 1750 2035 11532241245 27001 0ustarlucluc 0 0 This package provided classes to solve estimation problems, it is deprecated since 2.0.

                    This package has been deprecated as of 2.0. It is replaced by the optimization.general package.

                    commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/WeightedMeasurement.java100644 1750 1750 13166 11532241245 31360 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.io.Serializable; /** * This class represents measurements in estimation problems. * *

                    This abstract class implements all the methods needed to handle * measurements in a general way. It defines neither the {@link * #getTheoreticalValue getTheoreticalValue} nor the {@link * #getPartial getPartial} methods, which should be defined by * sub-classes according to the specific problem.

                    * *

                    The {@link #getTheoreticalValue getTheoreticalValue} and {@link * #getPartial getPartial} methods must always use the current * estimate of the parameters set by the solver in the problem. These * parameters can be retrieved through the {@link * EstimationProblem#getAllParameters * EstimationProblem.getAllParameters} method if the measurements are * independent of the problem, or directly if they are implemented as * inner classes of the problem.

                    * *

                    The instances for which the ignored flag is set * through the {@link #setIgnored setIgnored} method are ignored by the * solvers. This can be used to reject wrong measurements at some * steps of the estimation.

                    * * @see EstimationProblem * * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general */ @Deprecated public abstract class WeightedMeasurement implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 4360046376796901941L; /** Measurement weight. */ private final double weight; /** Value of the measurements. */ private final double measuredValue; /** Ignore measurement indicator. */ private boolean ignored; /** * Simple constructor. * Build a measurement with the given parameters, and set its ignore * flag to false. * @param weight weight of the measurement in the least squares problem * (two common choices are either to use 1.0 for all measurements, or to * use a value proportional to the inverse of the variance of the measurement * type) * * @param measuredValue measured value */ public WeightedMeasurement(double weight, double measuredValue) { this.weight = weight; this.measuredValue = measuredValue; ignored = false; } /** Simple constructor. * * Build a measurement with the given parameters * * @param weight weight of the measurement in the least squares problem * @param measuredValue measured value * @param ignored true if the measurement should be ignored */ public WeightedMeasurement(double weight, double measuredValue, boolean ignored) { this.weight = weight; this.measuredValue = measuredValue; this.ignored = ignored; } /** * Get the weight of the measurement in the least squares problem * * @return weight */ public double getWeight() { return weight; } /** * Get the measured value * * @return measured value */ public double getMeasuredValue() { return measuredValue; } /** * Get the residual for this measurement * The residual is the measured value minus the theoretical value. * * @return residual */ public double getResidual() { return measuredValue - getTheoreticalValue(); } /** * Get the theoretical value expected for this measurement *

                    The theoretical value is the value expected for this measurement * if the model and its parameter were all perfectly known.

                    *

                    The value must be computed using the current estimate of the parameters * set by the solver in the problem.

                    * * @return theoretical value */ public abstract double getTheoreticalValue(); /** * Get the partial derivative of the {@link #getTheoreticalValue * theoretical value} according to the parameter. *

                    The value must be computed using the current estimate of the parameters * set by the solver in the problem.

                    * * @param parameter parameter against which the partial derivative * should be computed * @return partial derivative of the {@link #getTheoreticalValue * theoretical value} */ public abstract double getPartial(EstimatedParameter parameter); /** * Set the ignore flag to the specified value * Setting the ignore flag to true allow to reject wrong * measurements, which sometimes can be detected only rather late. * * @param ignored value for the ignore flag */ public void setIgnored(boolean ignored) { this.ignored = ignored; } /** * Check if this measurement should be ignored * * @return true if the measurement should be ignored */ public boolean isIgnored() { return ignored; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/AbstractEstimator.java100644 1750 1750 25623 11532241245 31046 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.util.Arrays; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.InvalidMatrixException; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.util.FastMath; /** * Base class for implementing estimators. *

                    This base class handles the boilerplates methods associated to thresholds * settings, jacobian and error estimation.

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public abstract class AbstractEstimator implements Estimator { /** Default maximal number of cost evaluations allowed. */ public static final int DEFAULT_MAX_COST_EVALUATIONS = 100; /** Array of measurements. */ protected WeightedMeasurement[] measurements; /** Array of parameters. */ protected EstimatedParameter[] parameters; /** * Jacobian matrix. *

                    This matrix is in canonical form just after the calls to * {@link #updateJacobian()}, but may be modified by the solver * in the derived class (the {@link LevenbergMarquardtEstimator * Levenberg-Marquardt estimator} does this).

                    */ protected double[] jacobian; /** Number of columns of the jacobian matrix. */ protected int cols; /** Number of rows of the jacobian matrix. */ protected int rows; /** Residuals array. *

                    This array is in canonical form just after the calls to * {@link #updateJacobian()}, but may be modified by the solver * in the derived class (the {@link LevenbergMarquardtEstimator * Levenberg-Marquardt estimator} does this).

                    */ protected double[] residuals; /** Cost value (square root of the sum of the residuals). */ protected double cost; /** Maximal allowed number of cost evaluations. */ private int maxCostEval; /** Number of cost evaluations. */ private int costEvaluations; /** Number of jacobian evaluations. */ private int jacobianEvaluations; /** * Build an abstract estimator for least squares problems. *

                    The maximal number of cost evaluations allowed is set * to its default value {@link #DEFAULT_MAX_COST_EVALUATIONS}.

                    */ protected AbstractEstimator() { setMaxCostEval(DEFAULT_MAX_COST_EVALUATIONS); } /** * Set the maximal number of cost evaluations allowed. * * @param maxCostEval maximal number of cost evaluations allowed * @see #estimate */ public final void setMaxCostEval(int maxCostEval) { this.maxCostEval = maxCostEval; } /** * Get the number of cost evaluations. * * @return number of cost evaluations * */ public final int getCostEvaluations() { return costEvaluations; } /** * Get the number of jacobian evaluations. * * @return number of jacobian evaluations * */ public final int getJacobianEvaluations() { return jacobianEvaluations; } /** * Update the jacobian matrix. */ protected void updateJacobian() { incrementJacobianEvaluationsCounter(); Arrays.fill(jacobian, 0); int index = 0; for (int i = 0; i < rows; i++) { WeightedMeasurement wm = measurements[i]; double factor = -FastMath.sqrt(wm.getWeight()); for (int j = 0; j < cols; ++j) { jacobian[index++] = factor * wm.getPartial(parameters[j]); } } } /** * Increment the jacobian evaluations counter. */ protected final void incrementJacobianEvaluationsCounter() { ++jacobianEvaluations; } /** * Update the residuals array and cost function value. * @exception EstimationException if the number of cost evaluations * exceeds the maximum allowed */ protected void updateResidualsAndCost() throws EstimationException { if (++costEvaluations > maxCostEval) { throw new EstimationException(LocalizedFormats.MAX_EVALUATIONS_EXCEEDED, maxCostEval); } cost = 0; int index = 0; for (int i = 0; i < rows; i++, index += cols) { WeightedMeasurement wm = measurements[i]; double residual = wm.getResidual(); residuals[i] = FastMath.sqrt(wm.getWeight()) * residual; cost += wm.getWeight() * residual * residual; } cost = FastMath.sqrt(cost); } /** * Get the Root Mean Square value. * Get the Root Mean Square value, i.e. the root of the arithmetic * mean of the square of all weighted residuals. This is related to the * criterion that is minimized by the estimator as follows: if * c if the criterion, and n is the number of * measurements, then the RMS is sqrt (c/n). * * @param problem estimation problem * @return RMS value */ public double getRMS(EstimationProblem problem) { WeightedMeasurement[] wm = problem.getMeasurements(); double criterion = 0; for (int i = 0; i < wm.length; ++i) { double residual = wm[i].getResidual(); criterion += wm[i].getWeight() * residual * residual; } return FastMath.sqrt(criterion / wm.length); } /** * Get the Chi-Square value. * @param problem estimation problem * @return chi-square value */ public double getChiSquare(EstimationProblem problem) { WeightedMeasurement[] wm = problem.getMeasurements(); double chiSquare = 0; for (int i = 0; i < wm.length; ++i) { double residual = wm[i].getResidual(); chiSquare += residual * residual / wm[i].getWeight(); } return chiSquare; } /** * Get the covariance matrix of unbound estimated parameters. * @param problem estimation problem * @return covariance matrix * @exception EstimationException if the covariance matrix * cannot be computed (singular problem) */ public double[][] getCovariances(EstimationProblem problem) throws EstimationException { // set up the jacobian updateJacobian(); // compute transpose(J).J, avoiding building big intermediate matrices final int n = problem.getMeasurements().length; final int m = problem.getUnboundParameters().length; final int max = m * n; double[][] jTj = new double[m][m]; for (int i = 0; i < m; ++i) { for (int j = i; j < m; ++j) { double sum = 0; for (int k = 0; k < max; k += m) { sum += jacobian[k + i] * jacobian[k + j]; } jTj[i][j] = sum; jTj[j][i] = sum; } } try { // compute the covariances matrix RealMatrix inverse = new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse(); return inverse.getData(); } catch (InvalidMatrixException ime) { throw new EstimationException(LocalizedFormats.UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM); } } /** * Guess the errors in unbound estimated parameters. *

                    Guessing is covariance-based, it only gives rough order of magnitude.

                    * @param problem estimation problem * @return errors in estimated parameters * @exception EstimationException if the covariances matrix cannot be computed * or the number of degrees of freedom is not positive (number of measurements * lesser or equal to number of parameters) */ public double[] guessParametersErrors(EstimationProblem problem) throws EstimationException { int m = problem.getMeasurements().length; int p = problem.getUnboundParameters().length; if (m <= p) { throw new EstimationException( LocalizedFormats.NO_DEGREES_OF_FREEDOM, m, p); } double[] errors = new double[problem.getUnboundParameters().length]; final double c = FastMath.sqrt(getChiSquare(problem) / (m - p)); double[][] covar = getCovariances(problem); for (int i = 0; i < errors.length; ++i) { errors[i] = FastMath.sqrt(covar[i][i]) * c; } return errors; } /** * Initialization of the common parts of the estimation. *

                    This method must be called at the start * of the {@link #estimate(EstimationProblem) estimate} * method.

                    * @param problem estimation problem to solve */ protected void initializeEstimate(EstimationProblem problem) { // reset counters costEvaluations = 0; jacobianEvaluations = 0; // retrieve the equations and the parameters measurements = problem.getMeasurements(); parameters = problem.getUnboundParameters(); // arrays shared with the other private methods rows = measurements.length; cols = parameters.length; jacobian = new double[rows * cols]; residuals = new double[rows]; cost = Double.POSITIVE_INFINITY; } /** * Solve an estimation problem. * *

                    The method should set the parameters of the problem to several * trial values until it reaches convergence. If this method returns * normally (i.e. without throwing an exception), then the best * estimate of the parameters can be retrieved from the problem * itself, through the {@link EstimationProblem#getAllParameters * EstimationProblem.getAllParameters} method.

                    * * @param problem estimation problem to solve * @exception EstimationException if the problem cannot be solved * */ public abstract void estimate(EstimationProblem problem) throws EstimationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/Estimator.java100644 1750 1750 6621 11532241245 27337 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; /** * This interface represents solvers for estimation problems. * *

                    The classes which are devoted to solve estimation problems * should implement this interface. The problems which can be handled * should implement the {@link EstimationProblem} interface which * gather all the information needed by the solver.

                    * *

                    The interface is composed only of the {@link #estimate estimate} * method.

                    * * @see EstimationProblem * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general * */ @Deprecated public interface Estimator { /** * Solve an estimation problem. * *

                    The method should set the parameters of the problem to several * trial values until it reaches convergence. If this method returns * normally (i.e. without throwing an exception), then the best * estimate of the parameters can be retrieved from the problem * itself, through the {@link EstimationProblem#getAllParameters * EstimationProblem.getAllParameters} method.

                    * * @param problem estimation problem to solve * @exception EstimationException if the problem cannot be solved * */ void estimate(EstimationProblem problem) throws EstimationException; /** * Get the Root Mean Square value. * Get the Root Mean Square value, i.e. the root of the arithmetic * mean of the square of all weighted residuals. This is related to the * criterion that is minimized by the estimator as follows: if * c is the criterion, and n is the number of * measurements, then the RMS is sqrt (c/n). * @see #guessParametersErrors(EstimationProblem) * * @param problem estimation problem * @return RMS value */ double getRMS(EstimationProblem problem); /** * Get the covariance matrix of estimated parameters. * @param problem estimation problem * @return covariance matrix * @exception EstimationException if the covariance matrix * cannot be computed (singular problem) */ double[][] getCovariances(EstimationProblem problem) throws EstimationException; /** * Guess the errors in estimated parameters. * @see #getRMS(EstimationProblem) * @param problem estimation problem * @return errors in estimated parameters * @exception EstimationException if the error cannot be guessed */ double[] guessParametersErrors(EstimationProblem problem) throws EstimationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/estimation/SimpleEstimationProblem.java100644 1750 1750 7507 11532241245 32203 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.estimation; import java.util.ArrayList; import java.util.List; /** * Simple implementation of the {@link EstimationProblem * EstimationProblem} interface for boilerplate data handling. *

                    This class only handles parameters and measurements * storage and unbound parameters filtering. It does not compute * anything by itself. It should either be used with measurements * implementation that are smart enough to know about the * various parameters in order to compute the partial derivatives * appropriately. Since the problem-specific logic is mainly related to * the various measurements models, the simplest way to use this class * is by extending it and using one internal class extending * {@link WeightedMeasurement WeightedMeasurement} for each measurement * type. The instances of the internal classes would have access to the * various parameters and their current estimate.

                    * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has * been deprecated and replaced by package org.apache.commons.math.optimization.general */ @Deprecated public class SimpleEstimationProblem implements EstimationProblem { /** Estimated parameters. */ private final List parameters; /** Measurements. */ private final List measurements; /** * Build an empty instance without parameters nor measurements. */ public SimpleEstimationProblem() { parameters = new ArrayList(); measurements = new ArrayList(); } /** * Get all the parameters of the problem. * @return parameters */ public EstimatedParameter[] getAllParameters() { return parameters.toArray(new EstimatedParameter[parameters.size()]); } /** * Get the unbound parameters of the problem. * @return unbound parameters */ public EstimatedParameter[] getUnboundParameters() { // filter the unbound parameters List unbound = new ArrayList(parameters.size()); for (EstimatedParameter p : parameters) { if (! p.isBound()) { unbound.add(p); } } // convert to an array return unbound.toArray(new EstimatedParameter[unbound.size()]); } /** * Get the measurements of an estimation problem. * @return measurements */ public WeightedMeasurement[] getMeasurements() { return measurements.toArray(new WeightedMeasurement[measurements.size()]); } /** Add a parameter to the problem. * @param p parameter to add */ protected void addParameter(EstimatedParameter p) { parameters.add(p); } /** * Add a new measurement to the set. * @param m measurement to add */ protected void addMeasurement(WeightedMeasurement m) { measurements.add(m); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/RandomData.java100644 1750 1750 24566 11532241245 26536 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Collection; /** * Random data generation utilities. * @version $Revision: 780975 $ $Date: 2009-06-02 11:05:37 +0200 (mar. 02 juin 2009) $ */ public interface RandomData { /** * Generates a random string of hex characters of length * len. *

                    * The generated string will be random, but not cryptographically * secure. To generate cryptographically secure strings, use * nextSecureHexString

                    *

                    * Preconditions:

                      *
                    • len > 0 (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param len the length of the string to be generated * @return random string of hex characters of length len */ String nextHexString(int len); /** * Generates a uniformly distributed random integer between * lower and upper (endpoints included). *

                    * The generated integer will be random, but not cryptographically secure. * To generate cryptographically secure integer sequences, use * nextSecureInt.

                    *

                    * Preconditions:

                      *
                    • lower < upper (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param lower lower bound for generated integer * @param upper upper bound for generated integer * @return a random integer greater than or equal to lower * and less than or equal to upper. */ int nextInt(int lower, int upper); /** * Generates a uniformly distributed random long integer between * lower and upper (endpoints included). *

                    * The generated long integer values will be random, but not * cryptographically secure. * To generate cryptographically secure sequences of longs, use * nextSecureLong

                    *

                    * Preconditions:

                      *
                    • lower < upper (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param lower lower bound for generated integer * @param upper upper bound for generated integer * @return a random integer greater than or equal to lower * and less than or equal to upper. */ long nextLong(long lower, long upper); /** * Generates a random string of hex characters from a secure random * sequence. *

                    * If cryptographic security is not required, * use nextHexString().

                    *

                    * Preconditions:

                      *
                    • len > 0 (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * @param len length of return string * @return the random hex string */ String nextSecureHexString(int len); /** * Generates a uniformly distributed random integer between * lower and upper (endpoints included) * from a secure random sequence. *

                    * Sequences of integers generated using this method will be * cryptographically secure. If cryptographic security is not required, * nextInt should be used instead of this method.

                    *

                    * Definition: * * Secure Random Sequence

                    *

                    * Preconditions:

                      *
                    • lower < upper (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param lower lower bound for generated integer * @param upper upper bound for generated integer * @return a random integer greater than or equal to lower * and less than or equal to upper. */ int nextSecureInt(int lower, int upper); /** * Generates a random long integer between lower * and upper (endpoints included). *

                    * Sequences of long values generated using this method will be * cryptographically secure. If cryptographic security is not required, * nextLong should be used instead of this method.

                    *

                    * Definition: * * Secure Random Sequence

                    *

                    * Preconditions:

                      *
                    • lower < upper (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param lower lower bound for generated integer * @param upper upper bound for generated integer * @return a long integer greater than or equal to lower * and less than or equal to upper. */ long nextSecureLong(long lower, long upper); /** * Generates a random value from the Poisson distribution with * the given mean. *

                    * Definition: * * Poisson Distribution

                    *

                    * Preconditions:

                      *
                    • The specified mean must be positive (otherwise an * IllegalArgumentException is thrown.)
                    • *

                    * @param mean Mean of the distribution * @return poisson deviate with the specified mean */ long nextPoisson(double mean); /** * Generates a random value from the * Normal (or Gaussian) distribution with the given mean * and standard deviation. *

                    * Definition: * * Normal Distribution

                    *

                    * Preconditions:

                      *
                    • sigma > 0 (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * @param mu Mean of the distribution * @param sigma Standard deviation of the distribution * @return random value from Gaussian distribution with mean = mu, * standard deviation = sigma */ double nextGaussian(double mu, double sigma); /** * Generates a random value from the exponential distribution * with expected value = mean. *

                    * Definition: * * Exponential Distribution

                    *

                    * Preconditions:

                      *
                    • mu >= 0 (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * @param mean Mean of the distribution * @return random value from exponential distribution */ double nextExponential(double mean); /** * Generates a uniformly distributed random value from the open interval * (lower,upper) (i.e., endpoints excluded). *

                    * Definition: * * Uniform Distribution lower and * upper - lower are the * * location and scale parameters, respectively.

                    *

                    * Preconditions:

                      *
                    • lower < upper (otherwise an IllegalArgumentException * is thrown.)
                    • *

                    * * @param lower lower endpoint of the interval of support * @param upper upper endpoint of the interval of support * @return uniformly distributed random value between lower * and upper (exclusive) */ double nextUniform(double lower, double upper); /** * Generates an integer array of length k whose entries * are selected randomly, without repetition, from the integers * 0 through n-1 (inclusive). *

                    * Generated arrays represent permutations * of n taken k at a time.

                    *

                    * Preconditions:

                      *
                    • k <= n
                    • *
                    • n > 0
                    • *
                    * If the preconditions are not met, an IllegalArgumentException is * thrown.

                    * * @param n domain of the permutation * @param k size of the permutation * @return random k-permutation of n */ int[] nextPermutation(int n, int k); /** * Returns an array of k objects selected randomly * from the Collection c. *

                    * Sampling from c * is without replacement; but if c contains identical * objects, the sample may include repeats. If all elements of * c are distinct, the resulting object array represents a * * Simple Random Sample of size * k from the elements of c.

                    *

                    * Preconditions:

                      *
                    • k must be less than or equal to the size of c
                    • *
                    • c must not be empty
                    • *
                    * If the preconditions are not met, an IllegalArgumentException is * thrown.

                    * * @param c collection to be sampled * @param k size of the sample * @return random sample of k elements from c */ Object[] nextSample(Collection c, int k); } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/AbstractRandomGenerator.java100644 1750 1750 23050 11532241245 31262 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.util.FastMath; /** * Abstract class implementing the {@link RandomGenerator} interface. * Default implementations for all methods other than {@link #nextDouble()} and * {@link #setSeed(long)} are provided. *

                    * All data generation methods are based on {@code code nextDouble()}. * Concrete implementations must override * this method and should provide better / more * performant implementations of the other methods if the underlying PRNG * supplies them.

                    * * @since 1.1 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class AbstractRandomGenerator implements RandomGenerator { /** * Cached random normal value. The default implementation for * {@link #nextGaussian} generates pairs of values and this field caches the * second value so that the full algorithm is not executed for every * activation. The value {@code Double.NaN} signals that there is * no cached value. Use {@link #clear} to clear the cached value. */ private double cachedNormalDeviate = Double.NaN; /** * Construct a RandomGenerator. */ public AbstractRandomGenerator() { super(); } /** * Clears the cache used by the default implementation of * {@link #nextGaussian}. Implemementations that do not override the * default implementation of {@code nextGaussian} should call this * method in the implementation of {@link #setSeed(long)} */ public void clear() { cachedNormalDeviate = Double.NaN; } /** {@inheritDoc} */ public void setSeed(int seed) { setSeed((long) seed); } /** {@inheritDoc} */ public void setSeed(int[] seed) { // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5) final long prime = 4294967291l; long combined = 0l; for (int s : seed) { combined = combined * prime + s; } setSeed(combined); } /** * Sets the seed of the underyling random number generator using a * {@code long} seed. Sequences of values generated starting with the * same seeds should be identical. *

                    * Implementations that do not override the default implementation of * {@code nextGaussian} should include a call to {@link #clear} in the * implementation of this method.

                    * * @param seed the seed value */ public abstract void setSeed(long seed); /** * Generates random bytes and places them into a user-supplied * byte array. The number of random bytes produced is equal to * the length of the byte array. *

                    * The default implementation fills the array with bytes extracted from * random integers generated using {@link #nextInt}.

                    * * @param bytes the non-null byte array in which to put the * random bytes */ public void nextBytes(byte[] bytes) { int bytesOut = 0; while (bytesOut < bytes.length) { int randInt = nextInt(); for (int i = 0; i < 3; i++) { if ( i > 0) { randInt = randInt >> 8; } bytes[bytesOut++] = (byte) randInt; if (bytesOut == bytes.length) { return; } } } } /** * Returns the next pseudorandom, uniformly distributed {@code int} * value from this random number generator's sequence. * All 232 possible {@code int} values * should be produced with (approximately) equal probability. *

                    * The default implementation provided here returns *

                         * (int) (nextDouble() * Integer.MAX_VALUE)
                         * 

                    * * @return the next pseudorandom, uniformly distributed {@code int} * value from this random number generator's sequence */ public int nextInt() { return (int) (nextDouble() * Integer.MAX_VALUE); } /** * Returns a pseudorandom, uniformly distributed {@code int} value * between 0 (inclusive) and the specified value (exclusive), drawn from * this random number generator's sequence. *

                    * The default implementation returns *

                         * (int) (nextDouble() * n
                         * 

                    * * @param n the bound on the random number to be returned. Must be * positive. * @return a pseudorandom, uniformly distributed {@code int} * value between 0 (inclusive) and n (exclusive). * @throws NotStrictlyPositiveException if {@code n <= 0}. */ public int nextInt(int n) { if (n <= 0 ) { throw new NotStrictlyPositiveException(n); } int result = (int) (nextDouble() * n); return result < n ? result : n - 1; } /** * Returns the next pseudorandom, uniformly distributed {@code long} * value from this random number generator's sequence. All * 264 possible {@code long} values * should be produced with (approximately) equal probability. *

                    * The default implementation returns *

                         * (long) (nextDouble() * Long.MAX_VALUE)
                         * 

                    * * @return the next pseudorandom, uniformly distributed {@code long} *value from this random number generator's sequence */ public long nextLong() { return (long) (nextDouble() * Long.MAX_VALUE); } /** * Returns the next pseudorandom, uniformly distributed * {@code boolean} value from this random number generator's * sequence. *

                    * The default implementation returns *

                         * nextDouble() <= 0.5
                         * 

                    * * @return the next pseudorandom, uniformly distributed * {@code boolean} value from this random number generator's * sequence */ public boolean nextBoolean() { return nextDouble() <= 0.5; } /** * Returns the next pseudorandom, uniformly distributed {@code float} * value between {@code 0.0} and {@code 1.0} from this random * number generator's sequence. *

                    * The default implementation returns *

                         * (float) nextDouble() 
                         * 

                    * * @return the next pseudorandom, uniformly distributed {@code float} * value between {@code 0.0} and {@code 1.0} from this * random number generator's sequence */ public float nextFloat() { return (float) nextDouble(); } /** * Returns the next pseudorandom, uniformly distributed * {@code double} value between {@code 0.0} and * {@code 1.0} from this random number generator's sequence. *

                    * This method provides the underlying source of random data used by the * other methods.

                    * * @return the next pseudorandom, uniformly distributed * {@code double} value between {@code 0.0} and * {@code 1.0} from this random number generator's sequence */ public abstract double nextDouble(); /** * Returns the next pseudorandom, Gaussian ("normally") distributed * {@code double} value with mean {@code 0.0} and standard * deviation {@code 1.0} from this random number generator's sequence. *

                    * The default implementation uses the Polar Method * due to G.E.P. Box, M.E. Muller and G. Marsaglia, as described in * D. Knuth, The Art of Computer Programming, 3.4.1C.

                    *

                    * The algorithm generates a pair of independent random values. One of * these is cached for reuse, so the full algorithm is not executed on each * activation. Implementations that do not override this method should * make sure to call {@link #clear} to clear the cached value in the * implementation of {@link #setSeed(long)}.

                    * * @return the next pseudorandom, Gaussian ("normally") distributed * {@code double} value with mean {@code 0.0} and * standard deviation {@code 1.0} from this random number * generator's sequence */ public double nextGaussian() { if (!Double.isNaN(cachedNormalDeviate)) { double dev = cachedNormalDeviate; cachedNormalDeviate = Double.NaN; return dev; } double v1 = 0; double v2 = 0; double s = 1; while (s >=1 ) { v1 = 2 * nextDouble() - 1; v2 = 2 * nextDouble() - 1; s = v1 * v1 + v2 * v2; } if (s != 0) { s = FastMath.sqrt(-2 * FastMath.log(s) / s); } cachedNormalDeviate = v2 * s; return v1 * s; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/AbstractWell.java100644 1750 1750 16637 11532241245 27113 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.Serializable; /** This abstract class implements the WELL class of pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public abstract class AbstractWell extends BitsStreamGenerator implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -817701723016583596L; /** Current index in the bytes pool. */ protected int index; /** Bytes pool. */ protected final int[] v; /** Index indirection table giving for each index its predecessor taking table size into account. */ protected final int[] iRm1; /** Index indirection table giving for each index its second predecessor taking table size into account. */ protected final int[] iRm2; /** Index indirection table giving for each index the value index + m1 taking table size into account. */ protected final int[] i1; /** Index indirection table giving for each index the value index + m2 taking table size into account. */ protected final int[] i2; /** Index indirection table giving for each index the value index + m3 taking table size into account. */ protected final int[] i3; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    * @param k number of bits in the pool (not necessarily a multiple of 32) * @param m1 first parameter of the algorithm * @param m2 second parameter of the algorithm * @param m3 third parameter of the algorithm */ protected AbstractWell(final int k, final int m1, final int m2, final int m3) { this(k, m1, m2, m3, System.currentTimeMillis()); } /** Creates a new random number generator using a single int seed. * @param k number of bits in the pool (not necessarily a multiple of 32) * @param m1 first parameter of the algorithm * @param m2 second parameter of the algorithm * @param m3 third parameter of the algorithm * @param seed the initial seed (32 bits integer) */ protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int seed) { this(k, m1, m2, m3, new int[] { seed }); } /** Creates a new random number generator using an int array seed. * @param k number of bits in the pool (not necessarily a multiple of 32) * @param m1 first parameter of the algorithm * @param m2 second parameter of the algorithm * @param m3 third parameter of the algorithm * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int[] seed) { // the bits pool contains k bits, k = r w - p where r is the number // of w bits blocks, w is the block size (always 32 in the original paper) // and p is the number of unused bits in the last block final int w = 32; final int r = (k + w - 1) / w; this.v = new int[r]; this.index = 0; // precompute indirection index tables. These tables are used for optimizing access // they allow saving computations like "(j + r - 2) % r" with costly modulo operations iRm1 = new int[r]; iRm2 = new int[r]; i1 = new int[r]; i2 = new int[r]; i3 = new int[r]; for (int j = 0; j < r; ++j) { iRm1[j] = (j + r - 1) % r; iRm2[j] = (j + r - 2) % r; i1[j] = (j + m1) % r; i2[j] = (j + m2) % r; i3[j] = (j + m3) % r; } // initialize the pool content setSeed(seed); } /** Creates a new random number generator using a single long seed. * @param k number of bits in the pool (not necessarily a multiple of 32) * @param m1 first parameter of the algorithm * @param m2 second parameter of the algorithm * @param m3 third parameter of the algorithm * @param seed the initial seed (64 bits integer) */ protected AbstractWell(final int k, final int m1, final int m2, final int m3, final long seed) { this(k, m1, m2, m3, new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) }); } /** Reinitialize the generator as if just built with the given int seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (32 bits integer) */ @Override public void setSeed(final int seed) { setSeed(new int[] { seed }); } /** Reinitialize the generator as if just built with the given int array seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ @Override public void setSeed(final int[] seed) { if (seed == null) { setSeed(System.currentTimeMillis()); return; } System.arraycopy(seed, 0, v, 0, Math.min(seed.length, v.length)); if (seed.length < v.length) { for (int i = seed.length; i < v.length; ++i) { final long l = v[i - seed.length]; v[i] = (int) ((1812433253l * (l ^ (l >> 30)) + i) & 0xffffffffL); } } index = 0; } /** Reinitialize the generator as if just built with the given long seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (64 bits integer) */ @Override public void setSeed(final long seed) { setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) }); } /** {@inheritDoc} */ @Override protected abstract int next(final int bits); } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well1024a.java100644 1750 1750 7276 11532241245 26056 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL1024a pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well1024a extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = 5680173464174485492L; /** Number of bits in the pool. */ private static final int K = 1024; /** First parameter of the algorithm. */ private static final int M1 = 3; /** Second parameter of the algorithm. */ private static final int M2 = 24; /** Third parameter of the algorithm. */ private static final int M3 = 10; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well1024a() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well1024a(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well1024a(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well1024a(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { final int indexRm1 = iRm1[index]; final int v0 = v[index]; final int vM1 = v[i1[index]]; final int vM2 = v[i2[index]]; final int vM3 = v[i3[index]]; final int z0 = v[indexRm1]; final int z1 = v0 ^ (vM1 ^ (vM1 >>> 8)); final int z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14)); final int z3 = z1 ^ z2; final int z4 = (z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7)) ^ (z2 ^ (z2 << 13)); v[index] = z3; v[indexRm1] = z4; index = indexRm1; return z4 >>> (32 - bits); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/BitsStreamGenerator.java100644 1750 1750 11126 11532241245 30434 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.util.FastMath; /** Base class for random number generators that generates bits streams. * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public abstract class BitsStreamGenerator implements RandomGenerator { /** Next gaussian. */ private double nextGaussian; /** Creates a new random number generator. */ public BitsStreamGenerator() { nextGaussian = Double.NaN; } /** {@inheritDoc} */ public abstract void setSeed(int seed); /** {@inheritDoc} */ public abstract void setSeed(int[] seed); /** {@inheritDoc} */ public abstract void setSeed(long seed); /** Generate next pseudorandom number. *

                    This method is the core generation algorithm. It is used by all the * public generation methods for the various primitive types {@link * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()}, * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()}, * {@link #next(int)} and {@link #nextLong()}.

                    * @param bits number of random bits to produce * @return random bits generated */ protected abstract int next(int bits); /** {@inheritDoc} */ public boolean nextBoolean() { return next(1) != 0; } /** {@inheritDoc} */ public void nextBytes(byte[] bytes) { int i = 0; final int iEnd = bytes.length - 3; while (i < iEnd) { final int random = next(32); bytes[i] = (byte) (random & 0xff); bytes[i + 1] = (byte) ((random >> 8) & 0xff); bytes[i + 2] = (byte) ((random >> 16) & 0xff); bytes[i + 3] = (byte) ((random >> 24) & 0xff); i += 4; } int random = next(32); while (i < bytes.length) { bytes[i++] = (byte) (random & 0xff); random = random >> 8; } } /** {@inheritDoc} */ public double nextDouble() { final long high = ((long) next(26)) << 26; final int low = next(26); return (high | low) * 0x1.0p-52d; } /** {@inheritDoc} */ public float nextFloat() { return next(23) * 0x1.0p-23f; } /** {@inheritDoc} */ public double nextGaussian() { final double random; if (Double.isNaN(nextGaussian)) { // generate a new pair of gaussian numbers final double x = nextDouble(); final double y = nextDouble(); final double alpha = 2 * FastMath.PI * x; final double r = FastMath.sqrt(-2 * FastMath.log(y)); random = r * FastMath.cos(alpha); nextGaussian = r * FastMath.sin(alpha); } else { // use the second element of the pair already generated random = nextGaussian; nextGaussian = Double.NaN; } return random; } /** {@inheritDoc} */ public int nextInt() { return next(32); } /** {@inheritDoc} */ public int nextInt(int n) throws IllegalArgumentException { if (n < 1) { throw new NotStrictlyPositiveException(n); } // find bit mask for n int mask = n; mask |= mask >> 1; mask |= mask >> 2; mask |= mask >> 4; mask |= mask >> 8; mask |= mask >> 16; while (true) { final int random = next(32) & mask; if (random < n) { return random; } } } /** {@inheritDoc} */ public long nextLong() { final long high = ((long) next(32)) << 32; final long low = ((long) next(32)) & 0xffffffffL; return high | low; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/GaussianRandomGenerator.java100644 1750 1750 3321 11532241245 31250 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** * This class is a gaussian normalized random generator for scalars. *

                    This class is a simple wrapper around the {@link * RandomGenerator#nextGaussian} method.

                    * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 */ public class GaussianRandomGenerator implements NormalizedRandomGenerator { /** Underlying generator. */ private final RandomGenerator generator; /** Create a new generator. * @param generator underlying random generator to use */ public GaussianRandomGenerator(final RandomGenerator generator) { this.generator = generator; } /** Generate a random scalar with null mean and unit standard deviation. * @return a random scalar with null mean and unit standard deviation */ public double nextNormalizedDouble() { return generator.nextGaussian(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/RandomDataImpl.java100644 1750 1750 111347 11532241245 27372 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.Serializable; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.util.Collection; import org.apache.commons.math.MathException; import org.apache.commons.math.distribution.BetaDistributionImpl; import org.apache.commons.math.distribution.BinomialDistributionImpl; import org.apache.commons.math.distribution.CauchyDistributionImpl; import org.apache.commons.math.distribution.ChiSquaredDistributionImpl; import org.apache.commons.math.distribution.ContinuousDistribution; import org.apache.commons.math.distribution.FDistributionImpl; import org.apache.commons.math.distribution.GammaDistributionImpl; import org.apache.commons.math.distribution.HypergeometricDistributionImpl; import org.apache.commons.math.distribution.IntegerDistribution; import org.apache.commons.math.distribution.PascalDistributionImpl; import org.apache.commons.math.distribution.TDistributionImpl; import org.apache.commons.math.distribution.WeibullDistributionImpl; import org.apache.commons.math.distribution.ZipfDistributionImpl; import org.apache.commons.math.exception.MathInternalError; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.exception.NumberIsTooLargeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Implements the {@link RandomData} interface using a {@link RandomGenerator} * instance to generate non-secure data and a {@link java.security.SecureRandom} * instance to provide data for the nextSecureXxx methods. If no * RandomGenerator is provided in the constructor, the default is * to use a generator based on {@link java.util.Random}. To plug in a different * implementation, either implement RandomGenerator directly or * extend {@link AbstractRandomGenerator}. *

                    * Supports reseeding the underlying pseudo-random number generator (PRNG). The * SecurityProvider and Algorithm used by the * SecureRandom instance can also be reset. *

                    *

                    * For details on the default PRNGs, see {@link java.util.Random} and * {@link java.security.SecureRandom}. *

                    *

                    * Usage Notes: *

                      *
                    • * Instance variables are used to maintain RandomGenerator and * SecureRandom instances used in data generation. Therefore, to * generate a random sequence of values or strings, you should use just * one RandomDataImpl instance repeatedly.
                    • *
                    • * The "secure" methods are *much* slower. These should be used only when a * cryptographically secure random sequence is required. A secure random * sequence is a sequence of pseudo-random values which, in addition to being * well-dispersed (so no subsequence of values is an any more likely than other * subsequence of the the same length), also has the additional property that * knowledge of values generated up to any point in the sequence does not make * it any easier to predict subsequent values.
                    • *
                    • * When a new RandomDataImpl is created, the underlying random * number generators are not initialized. If you do not * explicitly seed the default non-secure generator, it is seeded with the * current time in milliseconds on first use. The same holds for the secure * generator. If you provide a RandomGenerator to the constructor, * however, this generator is not reseeded by the constructor nor is it reseeded * on first use.
                    • *
                    • * The reSeed and reSeedSecure methods delegate to the * corresponding methods on the underlying RandomGenerator and * SecureRandom instances. Therefore, reSeed(long) * fully resets the initial state of the non-secure random number generator (so * that reseeding with a specific value always results in the same subsequent * random sequence); whereas reSeedSecure(long) does not * reinitialize the secure random number generator (so secure sequences started * with calls to reseedSecure(long) won't be identical).
                    • *
                    • * This implementation is not synchronized. *
                    *

                    * * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $ */ public class RandomDataImpl implements RandomData, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -626730818244969716L; /** underlying random number generator */ private RandomGenerator rand = null; /** underlying secure random number generator */ private SecureRandom secRand = null; /** * Construct a RandomDataImpl. */ public RandomDataImpl() { } /** * Construct a RandomDataImpl using the supplied {@link RandomGenerator} as * the source of (non-secure) random data. * * @param rand * the source of (non-secure) random data * @since 1.1 */ public RandomDataImpl(RandomGenerator rand) { super(); this.rand = rand; } /** * {@inheritDoc} *

                    * Algorithm Description: hex strings are generated using a * 2-step process. *

                      *
                    1. * len/2+1 binary bytes are generated using the underlying Random
                    2. *
                    3. * Each binary byte is translated into 2 hex digits
                    4. *
                    *

                    * * @param len * the desired string length. * @return the random string. * @throws NotStrictlyPositiveException if {@code len <= 0}. */ public String nextHexString(int len) { if (len <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.LENGTH, len); } // Get a random number generator RandomGenerator ran = getRan(); // Initialize output buffer StringBuilder outBuffer = new StringBuilder(); // Get int(len/2)+1 random bytes byte[] randomBytes = new byte[(len / 2) + 1]; ran.nextBytes(randomBytes); // Convert each byte to 2 hex digits for (int i = 0; i < randomBytes.length; i++) { Integer c = Integer.valueOf(randomBytes[i]); /* * Add 128 to byte value to make interval 0-255 before doing hex * conversion. This guarantees <= 2 hex digits from toHexString() * toHexString would otherwise add 2^32 to negative arguments. */ String hex = Integer.toHexString(c.intValue() + 128); // Make sure we add 2 hex digits for each byte if (hex.length() == 1) { hex = "0" + hex; } outBuffer.append(hex); } return outBuffer.toString().substring(0, len); } /** * Generate a random int value uniformly distributed between * lower and upper, inclusive. * * @param lower * the lower bound. * @param upper * the upper bound. * @return the random integer. * @throws NumberIsTooLargeException if {@code lower >= upper}. */ public int nextInt(int lower, int upper) { if (lower >= upper) { throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false); } double r = getRan().nextDouble(); return (int) ((r * upper) + ((1.0 - r) * lower) + r); } /** * Generate a random long value uniformly distributed between * lower and upper, inclusive. * * @param lower * the lower bound. * @param upper * the upper bound. * @return the random integer. * @throws NumberIsTooLargeException if {@code lower >= upper}. */ public long nextLong(long lower, long upper) { if (lower >= upper) { throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false); } double r = getRan().nextDouble(); return (long) ((r * upper) + ((1.0 - r) * lower) + r); } /** * {@inheritDoc} *

                    * Algorithm Description: hex strings are generated in * 40-byte segments using a 3-step process. *

                      *
                    1. * 20 random bytes are generated using the underlying * SecureRandom.
                    2. *
                    3. * SHA-1 hash is applied to yield a 20-byte binary digest.
                    4. *
                    5. * Each byte of the binary digest is converted to 2 hex digits.
                    6. *
                    *

                    * * @param len * the length of the generated string * @return the random string * @throws NotStrictlyPositiveException if {@code len <= 0}. */ public String nextSecureHexString(int len) { if (len <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.LENGTH, len); } // Get SecureRandom and setup Digest provider SecureRandom secRan = getSecRan(); MessageDigest alg = null; try { alg = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException ex) { // this should never happen throw new MathInternalError(ex); } alg.reset(); // Compute number of iterations required (40 bytes each) int numIter = (len / 40) + 1; StringBuilder outBuffer = new StringBuilder(); for (int iter = 1; iter < numIter + 1; iter++) { byte[] randomBytes = new byte[40]; secRan.nextBytes(randomBytes); alg.update(randomBytes); // Compute hash -- will create 20-byte binary hash byte hash[] = alg.digest(); // Loop over the hash, converting each byte to 2 hex digits for (int i = 0; i < hash.length; i++) { Integer c = Integer.valueOf(hash[i]); /* * Add 128 to byte value to make interval 0-255 This guarantees * <= 2 hex digits from toHexString() toHexString would * otherwise add 2^32 to negative arguments */ String hex = Integer.toHexString(c.intValue() + 128); // Keep strings uniform length -- guarantees 40 bytes if (hex.length() == 1) { hex = "0" + hex; } outBuffer.append(hex); } } return outBuffer.toString().substring(0, len); } /** * Generate a random int value uniformly distributed between * lower and upper, inclusive. This algorithm uses * a secure random number generator. * * @param lower * the lower bound. * @param upper * the upper bound. * @return the random integer. * @throws NumberIsTooLargeException if {@code lower >= upper}. */ public int nextSecureInt(int lower, int upper) { if (lower >= upper) { throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false); } SecureRandom sec = getSecRan(); return lower + (int) (sec.nextDouble() * (upper - lower + 1)); } /** * Generate a random long value uniformly distributed between * lower and upper, inclusive. This algorithm uses * a secure random number generator. * * @param lower * the lower bound. * @param upper * the upper bound. * @return the random integer. * @throws NumberIsTooLargeException if {@code lower >= upper}. */ public long nextSecureLong(long lower, long upper) { if (lower >= upper) { throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false); } SecureRandom sec = getSecRan(); return lower + (long) (sec.nextDouble() * (upper - lower + 1)); } /** * {@inheritDoc} *

                    * Algorithm Description: *

                    • For small means, uses simulation of a Poisson process * using Uniform deviates, as described * here. * The Poisson process (and hence value returned) is bounded by 1000 * mean.
                    • * *
                    • For large means, uses the rejection algorithm described in
                      * Devroye, Luc. (1981).The Computer Generation of Poisson Random Variables * Computing vol. 26 pp. 197-207.

                    * * @param mean mean of the Poisson distribution. * @return the random Poisson value. * @throws NotStrictlyPositiveException if {@code mean <= 0}. */ public long nextPoisson(double mean) { if (mean <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.MEAN, mean); } final RandomGenerator generator = getRan(); final double pivot = 40.0d; if (mean < pivot) { double p = FastMath.exp(-mean); long n = 0; double r = 1.0d; double rnd = 1.0d; while (n < 1000 * mean) { rnd = generator.nextDouble(); r = r * rnd; if (r >= p) { n++; } else { return n; } } return n; } else { final double lambda = FastMath.floor(mean); final double lambdaFractional = mean - lambda; final double logLambda = FastMath.log(lambda); final double logLambdaFactorial = MathUtils.factorialLog((int) lambda); final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional); final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1)); final double halfDelta = delta / 2; final double twolpd = 2 * lambda + delta; final double a1 = FastMath.sqrt(FastMath.PI * twolpd) * FastMath.exp(1 / 8 * lambda); final double a2 = (twolpd / delta) * FastMath.exp(-delta * (1 + delta) / twolpd); final double aSum = a1 + a2 + 1; final double p1 = a1 / aSum; final double p2 = a2 / aSum; final double c1 = 1 / (8 * lambda); double x = 0; double y = 0; double v = 0; int a = 0; double t = 0; double qr = 0; double qa = 0; for (;;) { final double u = nextUniform(0.0, 1); if (u <= p1) { final double n = nextGaussian(0d, 1d); x = n * FastMath.sqrt(lambda + halfDelta) - 0.5d; if (x > delta || x < -lambda) { continue; } y = x < 0 ? FastMath.floor(x) : FastMath.ceil(x); final double e = nextExponential(1d); v = -e - (n * n / 2) + c1; } else { if (u > p1 + p2) { y = lambda; break; } else { x = delta + (twolpd / delta) * nextExponential(1d); y = FastMath.ceil(x); v = -nextExponential(1d) - delta * (x + 1) / twolpd; } } a = x < 0 ? 1 : 0; t = y * (y + 1) / (2 * lambda); if (v < -t && a == 0) { y = lambda + y; break; } qr = t * ((2 * y + 1) / (6 * lambda) - 1); qa = qr - (t * t) / (3 * (lambda + a * (y + 1))); if (v < qa) { y = lambda + y; break; } if (v > qr) { continue; } if (v < y * logLambda - MathUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) { y = lambda + y; break; } } return y2 + (long) y; } } /** * Generate a random value from a Normal (a.k.a. Gaussian) distribution with * the given mean, mu and the given standard deviation, * sigma. * * @param mu * the mean of the distribution * @param sigma * the standard deviation of the distribution * @return the random Normal value * @throws NotStrictlyPositiveException if {@code sigma <= 0}. */ public double nextGaussian(double mu, double sigma) { if (sigma <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.STANDARD_DEVIATION, sigma); } return sigma * getRan().nextGaussian() + mu; } /** * Returns a random value from an Exponential distribution with the given * mean. *

                    * Algorithm Description: Uses the Inversion * Method to generate exponentially distributed random values from * uniform deviates. *

                    * * @param mean the mean of the distribution * @return the random Exponential value * @throws NotStrictlyPositiveException if {@code mean <= 0}. */ public double nextExponential(double mean) { if (mean <= 0.0) { throw new NotStrictlyPositiveException(LocalizedFormats.MEAN, mean); } final RandomGenerator generator = getRan(); double unif = generator.nextDouble(); while (unif == 0.0d) { unif = generator.nextDouble(); } return -mean * FastMath.log(unif); } /** * {@inheritDoc} *

                    * Algorithm Description: scales the output of * Random.nextDouble(), but rejects 0 values (i.e., will generate another * random double if Random.nextDouble() returns 0). This is necessary to * provide a symmetric output interval (both endpoints excluded). *

                    * * @param lower * the lower bound. * @param upper * the upper bound. * @return a uniformly distributed random value from the interval (lower, * upper) * @throws NumberIsTooLargeException if {@code lower >= upper}. */ public double nextUniform(double lower, double upper) { if (lower >= upper) { throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false); } final RandomGenerator generator = getRan(); // ensure nextDouble() isn't 0.0 double u = generator.nextDouble(); while (u <= 0.0) { u = generator.nextDouble(); } return lower + u * (upper - lower); } /** * Generates a random value from the {@link BetaDistributionImpl Beta Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param alpha first distribution shape parameter * @param beta second distribution shape parameter * @return random value sampled from the beta(alpha, beta) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextBeta(double alpha, double beta) throws MathException { return nextInversionDeviate(new BetaDistributionImpl(alpha, beta)); } /** * Generates a random value from the {@link BinomialDistributionImpl Binomial Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param numberOfTrials number of trials of the Binomial distribution * @param probabilityOfSuccess probability of success of the Binomial distribution * @return random value sampled from the Binomial(numberOfTrials, probabilityOfSuccess) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public int nextBinomial(int numberOfTrials, double probabilityOfSuccess) throws MathException { return nextInversionDeviate(new BinomialDistributionImpl(numberOfTrials, probabilityOfSuccess)); } /** * Generates a random value from the {@link CauchyDistributionImpl Cauchy Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param median the median of the Cauchy distribution * @param scale the scale parameter of the Cauchy distribution * @return random value sampled from the Cauchy(median, scale) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextCauchy(double median, double scale) throws MathException { return nextInversionDeviate(new CauchyDistributionImpl(median, scale)); } /** * Generates a random value from the {@link ChiSquaredDistributionImpl ChiSquare Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param df the degrees of freedom of the ChiSquare distribution * @return random value sampled from the ChiSquare(df) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextChiSquare(double df) throws MathException { return nextInversionDeviate(new ChiSquaredDistributionImpl(df)); } /** * Generates a random value from the {@link FDistributionImpl F Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param numeratorDf the numerator degrees of freedom of the F distribution * @param denominatorDf the denominator degrees of freedom of the F distribution * @return random value sampled from the F(numeratorDf, denominatorDf) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextF(double numeratorDf, double denominatorDf) throws MathException { return nextInversionDeviate(new FDistributionImpl(numeratorDf, denominatorDf)); } /** * Generates a random value from the {@link GammaDistributionImpl Gamma Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param shape the median of the Gamma distribution * @param scale the scale parameter of the Gamma distribution * @return random value sampled from the Gamma(shape, scale) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextGamma(double shape, double scale) throws MathException { return nextInversionDeviate(new GammaDistributionImpl(shape, scale)); } /** * Generates a random value from the {@link HypergeometricDistributionImpl Hypergeometric Distribution}. * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion} * to generate random values. * * @param populationSize the population size of the Hypergeometric distribution * @param numberOfSuccesses number of successes in the population of the Hypergeometric distribution * @param sampleSize the sample size of the Hypergeometric distribution * @return random value sampled from the Hypergeometric(numberOfSuccesses, sampleSize) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public int nextHypergeometric(int populationSize, int numberOfSuccesses, int sampleSize) throws MathException { return nextInversionDeviate(new HypergeometricDistributionImpl(populationSize, numberOfSuccesses, sampleSize)); } /** * Generates a random value from the {@link PascalDistributionImpl Pascal Distribution}. * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion} * to generate random values. * * @param r the number of successes of the Pascal distribution * @param p the probability of success of the Pascal distribution * @return random value sampled from the Pascal(r, p) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public int nextPascal(int r, double p) throws MathException { return nextInversionDeviate(new PascalDistributionImpl(r, p)); } /** * Generates a random value from the {@link TDistributionImpl T Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param df the degrees of freedom of the T distribution * @return random value from the T(df) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextT(double df) throws MathException { return nextInversionDeviate(new TDistributionImpl(df)); } /** * Generates a random value from the {@link WeibullDistributionImpl Weibull Distribution}. * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion} * to generate random values. * * @param shape the shape parameter of the Weibull distribution * @param scale the scale parameter of the Weibull distribution * @return random value sampled from the Weibull(shape, size) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public double nextWeibull(double shape, double scale) throws MathException { return nextInversionDeviate(new WeibullDistributionImpl(shape, scale)); } /** * Generates a random value from the {@link ZipfDistributionImpl Zipf Distribution}. * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion} * to generate random values. * * @param numberOfElements the number of elements of the ZipfDistribution * @param exponent the exponent of the ZipfDistribution * @return random value sampled from the Zipf(numberOfElements, exponent) distribution * @throws MathException if an error occurs generating the random value * @since 2.2 */ public int nextZipf(int numberOfElements, double exponent) throws MathException { return nextInversionDeviate(new ZipfDistributionImpl(numberOfElements, exponent)); } /** * Returns the RandomGenerator used to generate non-secure random data. *

                    * Creates and initializes a default generator if null. *

                    * * @return the Random used to generate random data * @since 1.1 */ private RandomGenerator getRan() { if (rand == null) { rand = new JDKRandomGenerator(); rand.setSeed(System.currentTimeMillis()); } return rand; } /** * Returns the SecureRandom used to generate secure random data. *

                    * Creates and initializes if null. *

                    * * @return the SecureRandom used to generate secure random data */ private SecureRandom getSecRan() { if (secRand == null) { secRand = new SecureRandom(); secRand.setSeed(System.currentTimeMillis()); } return secRand; } /** * Reseeds the random number generator with the supplied seed. *

                    * Will create and initialize if null. *

                    * * @param seed * the seed value to use */ public void reSeed(long seed) { if (rand == null) { rand = new JDKRandomGenerator(); } rand.setSeed(seed); } /** * Reseeds the secure random number generator with the current time in * milliseconds. *

                    * Will create and initialize if null. *

                    */ public void reSeedSecure() { if (secRand == null) { secRand = new SecureRandom(); } secRand.setSeed(System.currentTimeMillis()); } /** * Reseeds the secure random number generator with the supplied seed. *

                    * Will create and initialize if null. *

                    * * @param seed * the seed value to use */ public void reSeedSecure(long seed) { if (secRand == null) { secRand = new SecureRandom(); } secRand.setSeed(seed); } /** * Reseeds the random number generator with the current time in * milliseconds. */ public void reSeed() { if (rand == null) { rand = new JDKRandomGenerator(); } rand.setSeed(System.currentTimeMillis()); } /** * Sets the PRNG algorithm for the underlying SecureRandom instance using * the Security Provider API. The Security Provider API is defined in * Java Cryptography Architecture API Specification & Reference. *

                    * USAGE NOTE: This method carries significant * overhead and may take several seconds to execute. *

                    * * @param algorithm * the name of the PRNG algorithm * @param provider * the name of the provider * @throws NoSuchAlgorithmException * if the specified algorithm is not available * @throws NoSuchProviderException * if the specified provider is not installed */ public void setSecureAlgorithm(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { secRand = SecureRandom.getInstance(algorithm, provider); } /** * Generates an integer array of length k whose entries are * selected randomly, without repetition, from the integers * 0 through n-1 (inclusive). *

                    * Generated arrays represent permutations of n taken * k at a time. *

                    *

                    * Preconditions: *

                      *
                    • k <= n
                    • *
                    • n > 0
                    • *
                    * If the preconditions are not met, an IllegalArgumentException is thrown. *

                    *

                    * Uses a 2-cycle permutation shuffle. The shuffling process is described * here. *

                    * * @param n * domain of the permutation (must be positive) * @param k * size of the permutation (must satisfy 0 < k <= n). * @return the random permutation as an int array * @throws NumberIsTooLargeException if {@code k > n}. * @throws NotStrictlyPositiveException if {@code k <= 0}. */ public int[] nextPermutation(int n, int k) { if (k > n) { throw new NumberIsTooLargeException(LocalizedFormats.PERMUTATION_EXCEEDS_N, k, n, true); } if (k == 0) { throw new NotStrictlyPositiveException(LocalizedFormats.PERMUTATION_SIZE, k); } int[] index = getNatural(n); shuffle(index, n - k); int[] result = new int[k]; for (int i = 0; i < k; i++) { result[i] = index[n - i - 1]; } return result; } /** * Uses a 2-cycle permutation shuffle to generate a random permutation. * Algorithm Description: Uses a 2-cycle permutation * shuffle to generate a random permutation of c.size() and * then returns the elements whose indexes correspond to the elements of the * generated permutation. This technique is described, and proven to * generate random samples, * here * * @param c * Collection to sample from. * @param k * sample size. * @return the random sample. * @throws NumberIsTooLargeException if {@code k > c.size()}. * @throws NotStrictlyPositiveException if {@code k <= 0}. */ public Object[] nextSample(Collection c, int k) { int len = c.size(); if (k > len) { throw new NumberIsTooLargeException(LocalizedFormats.SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE, k, len, true); } if (k <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_SAMPLES, k); } Object[] objects = c.toArray(); int[] index = nextPermutation(len, k); Object[] result = new Object[k]; for (int i = 0; i < k; i++) { result[i] = objects[index[i]]; } return result; } /** * Generate a random deviate from the given distribution using the * inversion method. * * @param distribution Continuous distribution to generate a random value from * @return a random value sampled from the given distribution * @throws MathException if an error occurs computing the inverse cumulative distribution function * @since 2.2 */ public double nextInversionDeviate(ContinuousDistribution distribution) throws MathException { return distribution.inverseCumulativeProbability(nextUniform(0, 1)); } /** * Generate a random deviate from the given distribution using the * inversion method. * * @param distribution Integer distribution to generate a random value from * @return a random value sampled from the given distribution * @throws MathException if an error occurs computing the inverse cumulative distribution function * @since 2.2 */ public int nextInversionDeviate(IntegerDistribution distribution) throws MathException { final double target = nextUniform(0, 1); final int glb = distribution.inverseCumulativeProbability(target); if (distribution.cumulativeProbability(glb) == 1.0d) { // No mass above return glb; } else { return glb + 1; } } // ------------------------Private methods---------------------------------- /** * Uses a 2-cycle permutation shuffle to randomly re-order the last elements * of list. * * @param list * list to be shuffled * @param end * element past which shuffling begins */ private void shuffle(int[] list, int end) { int target = 0; for (int i = list.length - 1; i >= end; i--) { if (i == 0) { target = 0; } else { target = nextInt(0, i); } int temp = list[target]; list[target] = list[i]; list[i] = temp; } } /** * Returns an array representing n. * * @param n * the natural number to represent * @return array with entries = elements of n */ private int[] getNatural(int n) { int[] natural = new int[n]; for (int i = 0; i < n; i++) { natural[i] = i; } return natural; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/EmpiricalDistribution.java100644 1750 1750 11255 11532241245 31020 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.IOException; import java.io.File; import java.net.URL; import java.util.List; import org.apache.commons.math.stat.descriptive.StatisticalSummary; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Represents an * empirical probability distribution -- a probability distribution derived * from observed data without making any assumptions about the functional form * of the population distribution that the data come from.

                    * Implementations of this interface maintain data structures, called * distribution digests, that describe empirical distributions and * support the following operations:

                      *
                    • loading the distribution from a file of observed data values
                    • *
                    • dividing the input data into "bin ranges" and reporting bin frequency * counts (data for histogram)
                    • *
                    • reporting univariate statistics describing the full set of data values * as well as the observations within each bin
                    • *
                    • generating random values from the distribution
                    • *
                    * Applications can use EmpiricalDistribution implementations to * build grouped frequency histograms representing the input data or to * generate random values "like" those in the input file -- i.e., the values * generated will follow the distribution of the values in the file.

                    * * @version $Revision: 817128 $ $Date: 2009-09-21 03:30:53 +0200 (lun. 21 sept. 2009) $ */ public interface EmpiricalDistribution { /** * Computes the empirical distribution from the provided * array of numbers. * * @param dataArray the data array */ void load(double[] dataArray); /** * Computes the empirical distribution from the input file. * * @param file the input file * @throws IOException if an IO error occurs */ void load(File file) throws IOException; /** * Computes the empirical distribution using data read from a URL. * * @param url url of the input file * @throws IOException if an IO error occurs */ void load(URL url) throws IOException; /** * Generates a random value from this distribution. * Preconditions:
                      *
                    • the distribution must be loaded before invoking this method
                    * @return the random value. * * @throws IllegalStateException if the distribution has not been loaded */ double getNextValue() throws IllegalStateException; /** * Returns a * {@link org.apache.commons.math.stat.descriptive.StatisticalSummary} * describing this distribution. * Preconditions:
                      *
                    • the distribution must be loaded before invoking this method
                    • *
                    * * @return the sample statistics * @throws IllegalStateException if the distribution has not been loaded */ StatisticalSummary getSampleStats() throws IllegalStateException; /** * Property indicating whether or not the distribution has been loaded. * * @return true if the distribution has been loaded */ boolean isLoaded(); /** * Returns the number of bins. * * @return the number of bins */ int getBinCount(); /** * Returns a list of * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics} * containing statistics describing the values in each of the bins. The * List is indexed on the bin number. * * @return List of bin statistics */ List getBinStats(); /** * Returns the array of upper bounds for the bins. Bins are:
                    * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],..., * (upperBounds[binCount-2], upperBounds[binCount-1] = max]. * * @return array of bin upper bounds */ double[] getUpperBounds(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/ValueServer.java100644 1750 1750 31301 11532241245 26750 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Generates values for use in simulation applications. *

                    * How values are generated is determined by the mode * property.

                    *

                    * Supported mode values are:

                      *
                    • DIGEST_MODE -- uses an empirical distribution
                    • *
                    • REPLAY_MODE -- replays data from valuesFileURL
                    • *
                    • UNIFORM_MODE -- generates uniformly distributed random values with * mean = mu
                    • *
                    • EXPONENTIAL_MODE -- generates exponentially distributed random values * with mean = mu
                    • *
                    • GAUSSIAN_MODE -- generates Gaussian distributed random values with * mean = mu and * standard deviation = sigma
                    • *
                    • CONSTANT_MODE -- returns mu every time.

                    * * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ * */ public class ValueServer { /** Use empirical distribution. */ public static final int DIGEST_MODE = 0; /** Replay data from valuesFilePath. */ public static final int REPLAY_MODE = 1; /** Uniform random deviates with mean = μ. */ public static final int UNIFORM_MODE = 2; /** Exponential random deviates with mean = μ. */ public static final int EXPONENTIAL_MODE = 3; /** Gaussian random deviates with mean = μ, std dev = σ. */ public static final int GAUSSIAN_MODE = 4; /** Always return mu */ public static final int CONSTANT_MODE = 5; /** mode determines how values are generated. */ private int mode = 5; /** URI to raw data values. */ private URL valuesFileURL = null; /** Mean for use with non-data-driven modes. */ private double mu = 0.0; /** Standard deviation for use with GAUSSIAN_MODE. */ private double sigma = 0.0; /** Empirical probability distribution for use with DIGEST_MODE. */ private EmpiricalDistribution empiricalDistribution = null; /** File pointer for REPLAY_MODE. */ private BufferedReader filePointer = null; /** RandomDataImpl to use for random data generation. */ private final RandomData randomData; // Data generation modes ====================================== /** Creates new ValueServer */ public ValueServer() { randomData = new RandomDataImpl(); } /** * Construct a ValueServer instance using a RandomData as its source * of random data. * * @param randomData the RandomData instance used to source random data * @since 1.1 */ public ValueServer(RandomData randomData) { this.randomData = randomData; } /** * Returns the next generated value, generated according * to the mode value (see MODE constants). * * @return generated value * @throws IOException in REPLAY_MODE if a file I/O error occurs */ public double getNext() throws IOException { switch (mode) { case DIGEST_MODE: return getNextDigest(); case REPLAY_MODE: return getNextReplay(); case UNIFORM_MODE: return getNextUniform(); case EXPONENTIAL_MODE: return getNextExponential(); case GAUSSIAN_MODE: return getNextGaussian(); case CONSTANT_MODE: return mu; default: throw MathRuntimeException.createIllegalStateException( LocalizedFormats.UNKNOWN_MODE, mode, "DIGEST_MODE", DIGEST_MODE, "REPLAY_MODE", REPLAY_MODE, "UNIFORM_MODE", UNIFORM_MODE, "EXPONENTIAL_MODE", EXPONENTIAL_MODE, "GAUSSIAN_MODE", GAUSSIAN_MODE, "CONSTANT_MODE", CONSTANT_MODE); } } /** * Fills the input array with values generated using getNext() repeatedly. * * @param values array to be filled * @throws IOException in REPLAY_MODE if a file I/O error occurs */ public void fill(double[] values) throws IOException { for (int i = 0; i < values.length; i++) { values[i] = getNext(); } } /** * Returns an array of length length with values generated * using getNext() repeatedly. * * @param length length of output array * @return array of generated values * @throws IOException in REPLAY_MODE if a file I/O error occurs */ public double[] fill(int length) throws IOException { double[] out = new double[length]; for (int i = 0; i < length; i++) { out[i] = getNext(); } return out; } /** * Computes the empirical distribution using values from the file * in valuesFileURL, using the default number of bins. *

                    * valuesFileURL must exist and be * readable by *this at runtime.

                    *

                    * This method must be called before using getNext() * with mode = DIGEST_MODE

                    * * @throws IOException if an I/O error occurs reading the input file */ public void computeDistribution() throws IOException { empiricalDistribution = new EmpiricalDistributionImpl(); empiricalDistribution.load(valuesFileURL); } /** * Computes the empirical distribution using values from the file * in valuesFileURL and binCount bins. *

                    * valuesFileURL must exist and be readable by this process * at runtime.

                    *

                    * This method must be called before using getNext() * with mode = DIGEST_MODE

                    * * @param binCount the number of bins used in computing the empirical * distribution * @throws IOException if an error occurs reading the input file */ public void computeDistribution(int binCount) throws IOException { empiricalDistribution = new EmpiricalDistributionImpl(binCount); empiricalDistribution.load(valuesFileURL); mu = empiricalDistribution.getSampleStats().getMean(); sigma = empiricalDistribution.getSampleStats().getStandardDeviation(); } /** Getter for property mode. * @return Value of property mode. */ public int getMode() { return mode; } /** Setter for property mode. * @param mode New value of property mode. */ public void setMode(int mode) { this.mode = mode; } /** * Getter for valuesFileURL * @return Value of property valuesFileURL. */ public URL getValuesFileURL() { return valuesFileURL; } /** * Sets the valuesFileURL using a string URL representation * @param url String representation for new valuesFileURL. * @throws MalformedURLException if url is not well formed */ public void setValuesFileURL(String url) throws MalformedURLException { this.valuesFileURL = new URL(url); } /** * Sets the valuesFileURL * @param url New value of property valuesFileURL. */ public void setValuesFileURL(URL url) { this.valuesFileURL = url; } /** Getter for property empiricalDistribution. * @return Value of property empiricalDistribution. */ public EmpiricalDistribution getEmpiricalDistribution() { return empiricalDistribution; } /** * Resets REPLAY_MODE file pointer to the beginning of the valuesFileURL. * * @throws IOException if an error occurs opening the file */ public void resetReplayFile() throws IOException { if (filePointer != null) { try { filePointer.close(); filePointer = null; } catch (IOException ex) { // ignore } } filePointer = new BufferedReader(new InputStreamReader(valuesFileURL.openStream())); } /** * Closes valuesFileURL after use in REPLAY_MODE. * * @throws IOException if an error occurs closing the file */ public void closeReplayFile() throws IOException { if (filePointer != null) { filePointer.close(); filePointer = null; } } /** Getter for property mu. * @return Value of property mu. */ public double getMu() { return mu; } /** Setter for property mu. * @param mu New value of property mu. */ public void setMu(double mu) { this.mu = mu; } /** Getter for property sigma. * @return Value of property sigma. */ public double getSigma() { return sigma; } /** Setter for property sigma. * @param sigma New value of property sigma. */ public void setSigma(double sigma) { this.sigma = sigma; } //------------- private methods --------------------------------- /** * Gets a random value in DIGEST_MODE. *

                    * Preconditions:

                      *
                    • Before this method is called, computeDistribution() * must have completed successfully; otherwise an * IllegalStateException will be thrown

                    * * @return next random value from the empirical distribution digest */ private double getNextDigest() { if ((empiricalDistribution == null) || (empiricalDistribution.getBinStats().size() == 0)) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.DIGEST_NOT_INITIALIZED); } return empiricalDistribution.getNextValue(); } /** * Gets next sequential value from the valuesFileURL. *

                    * Throws an IOException if the read fails.

                    *

                    * This method will open the valuesFileURL if there is no * replay file open.

                    *

                    * The valuesFileURL will be closed and reopened to wrap around * from EOF to BOF if EOF is encountered. EOFException (which is a kind of * IOException) may still be thrown if the valuesFileURL is * empty.

                    * * @return next value from the replay file * @throws IOException if there is a problem reading from the file * @throws NumberFormatException if an invalid numeric string is * encountered in the file */ private double getNextReplay() throws IOException { String str = null; if (filePointer == null) { resetReplayFile(); } if ((str = filePointer.readLine()) == null) { // we have probably reached end of file, wrap around from EOF to BOF closeReplayFile(); resetReplayFile(); if ((str = filePointer.readLine()) == null) { throw MathRuntimeException.createEOFException(LocalizedFormats.URL_CONTAINS_NO_DATA, valuesFileURL); } } return Double.valueOf(str).doubleValue(); } /** * Gets a uniformly distributed random value with mean = mu. * * @return random uniform value */ private double getNextUniform() { return randomData.nextUniform(0, 2 * mu); } /** * Gets an exponentially distributed random value with mean = mu. * * @return random exponential value */ private double getNextExponential() { return randomData.nextExponential(mu); } /** * Gets a Gaussian distributed random value with mean = mu * and standard deviation = sigma. * * @return random Gaussian value */ private double getNextGaussian() { return randomData.nextGaussian(mu, sigma); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/RandomGenerator.java100644 1750 1750 12543 11532241245 27603 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** * Interface extracted from java.util.Random. This interface is * implemented by {@link AbstractRandomGenerator}. * * @since 1.1 * @version $Revision: 949750 $ $Date: 2010-05-31 16:06:04 +0200 (lun. 31 mai 2010) $ */ public interface RandomGenerator { /** * Sets the seed of the underlying random number generator using an * int seed. *

                    Sequences of values generated starting with the same seeds * should be identical. *

                    * @param seed the seed value */ void setSeed(int seed); /** * Sets the seed of the underlying random number generator using an * int array seed. *

                    Sequences of values generated starting with the same seeds * should be identical. *

                    * @param seed the seed value */ void setSeed(int[] seed); /** * Sets the seed of the underlying random number generator using a * long seed. *

                    Sequences of values generated starting with the same seeds * should be identical. *

                    * @param seed the seed value */ void setSeed(long seed); /** * Generates random bytes and places them into a user-supplied * byte array. The number of random bytes produced is equal to * the length of the byte array. * * @param bytes the non-null byte array in which to put the * random bytes */ void nextBytes(byte[] bytes); /** * Returns the next pseudorandom, uniformly distributed int * value from this random number generator's sequence. * All 232 possible int values * should be produced with (approximately) equal probability. * * @return the next pseudorandom, uniformly distributed int * value from this random number generator's sequence */ int nextInt(); /** * Returns a pseudorandom, uniformly distributed int value * between 0 (inclusive) and the specified value (exclusive), drawn from * this random number generator's sequence. * * @param n the bound on the random number to be returned. Must be * positive. * @return a pseudorandom, uniformly distributed int * value between 0 (inclusive) and n (exclusive). * @throws IllegalArgumentException if n is not positive. */ int nextInt(int n); /** * Returns the next pseudorandom, uniformly distributed long * value from this random number generator's sequence. All * 264 possible long values * should be produced with (approximately) equal probability. * * @return the next pseudorandom, uniformly distributed long *value from this random number generator's sequence */ long nextLong(); /** * Returns the next pseudorandom, uniformly distributed * boolean value from this random number generator's * sequence. * * @return the next pseudorandom, uniformly distributed * boolean value from this random number generator's * sequence */ boolean nextBoolean(); /** * Returns the next pseudorandom, uniformly distributed float * value between 0.0 and 1.0 from this random * number generator's sequence. * * @return the next pseudorandom, uniformly distributed float * value between 0.0 and 1.0 from this * random number generator's sequence */ float nextFloat(); /** * Returns the next pseudorandom, uniformly distributed * double value between 0.0 and * 1.0 from this random number generator's sequence. * * @return the next pseudorandom, uniformly distributed * double value between 0.0 and * 1.0 from this random number generator's sequence */ double nextDouble(); /** * Returns the next pseudorandom, Gaussian ("normally") distributed * double value with mean 0.0 and standard * deviation 1.0 from this random number generator's sequence. * * @return the next pseudorandom, Gaussian ("normally") distributed * double value with mean 0.0 and * standard deviation 1.0 from this random number * generator's sequence */ double nextGaussian(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/RandomVectorGenerator.java100644 1750 1750 2253 11532241245 30743 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This interface represents a random generator for whole vectors. * * @since 1.2 * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * */ public interface RandomVectorGenerator { /** Generate a random vector. * @return a random vector as an array of double. */ double[] nextVector(); } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.ja100644 1750 1750 5023 11532241245 32421 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.util.FastMath; /** * Generate random vectors isotropically located on the surface of a sphere. * * @since 2.1 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class UnitSphereRandomVectorGenerator implements RandomVectorGenerator { /** * RNG used for generating the individual components of the vectors. */ private final RandomGenerator rand; /** * Space dimension. */ private final int dimension; /** * @param dimension Space dimension. * @param rand RNG for the individual components of the vectors. */ public UnitSphereRandomVectorGenerator(final int dimension, final RandomGenerator rand) { this.dimension = dimension; this.rand = rand; } /** * Create an object that will use a default RNG ({@link MersenneTwister}), * in order to generate the individual components. * * @param dimension Space dimension. */ public UnitSphereRandomVectorGenerator(final int dimension) { this(dimension, new MersenneTwister()); } /** {@inheritDoc} */ public double[] nextVector() { final double[] v = new double[dimension]; double normSq; do { normSq = 0; for (int i = 0; i < dimension; i++) { final double comp = 2 * rand.nextDouble() - 1; v[i] = comp; normSq += comp * comp; } } while (normSq > 1); final double f = 1 / FastMath.sqrt(normSq); for (int i = 0; i < dimension; i++) { v[i] *= f; } return v; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java100644 1750 1750 37735 11532241245 31655 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Serializable; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.StatisticalSummary; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.apache.commons.math.util.FastMath; /** * Implements EmpiricalDistribution interface. This implementation * uses what amounts to the * * Variable Kernel Method with Gaussian smoothing:

                    * Digesting the input file *

                    1. Pass the file once to compute min and max.
                    2. *
                    3. Divide the range from min-max into binCount "bins."
                    4. *
                    5. Pass the data file again, computing bin counts and univariate * statistics (mean, std dev.) for each of the bins
                    6. *
                    7. Divide the interval (0,1) into subintervals associated with the bins, * with the length of a bin's subinterval proportional to its count.
                    * Generating random values from the distribution
                      *
                    1. Generate a uniformly distributed value in (0,1)
                    2. *
                    3. Select the subinterval to which the value belongs. *
                    4. Generate a random Gaussian value with mean = mean of the associated * bin and std dev = std dev of associated bin.

                    *USAGE NOTES:

                      *
                    • The binCount is set by default to 1000. A good rule of thumb * is to set the bin count to approximately the length of the input file divided * by 10.
                    • *
                    • The input file must be a plain text file containing one valid numeric * entry per line.
                    • *

                    * * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ */ public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistribution { /** Serializable version identifier */ private static final long serialVersionUID = 5729073523949762654L; /** List of SummaryStatistics objects characterizing the bins */ private final List binStats; /** Sample statistics */ private SummaryStatistics sampleStats = null; /** Max loaded value */ private double max = Double.NEGATIVE_INFINITY; /** Min loaded value */ private double min = Double.POSITIVE_INFINITY; /** Grid size */ private double delta = 0d; /** number of bins */ private final int binCount; /** is the distribution loaded? */ private boolean loaded = false; /** upper bounds of subintervals in (0,1) "belonging" to the bins */ private double[] upperBounds = null; /** RandomData instance to use in repeated calls to getNext() */ private final RandomData randomData = new RandomDataImpl(); /** * Creates a new EmpiricalDistribution with the default bin count. */ public EmpiricalDistributionImpl() { binCount = 1000; binStats = new ArrayList(); } /** * Creates a new EmpiricalDistribution with the specified bin count. * * @param binCount number of bins */ public EmpiricalDistributionImpl(int binCount) { this.binCount = binCount; binStats = new ArrayList(); } /** * Computes the empirical distribution from the provided * array of numbers. * * @param in the input data array */ public void load(double[] in) { DataAdapter da = new ArrayDataAdapter(in); try { da.computeStats(); fillBinStats(in); } catch (IOException e) { throw new MathRuntimeException(e); } loaded = true; } /** * Computes the empirical distribution using data read from a URL. * @param url url of the input file * * @throws IOException if an IO error occurs */ public void load(URL url) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); try { DataAdapter da = new StreamDataAdapter(in); da.computeStats(); if (sampleStats.getN() == 0) { throw MathRuntimeException.createEOFException(LocalizedFormats.URL_CONTAINS_NO_DATA, url); } in = new BufferedReader(new InputStreamReader(url.openStream())); fillBinStats(in); loaded = true; } finally { try { in.close(); } catch (IOException ex) { // ignore } } } /** * Computes the empirical distribution from the input file. * * @param file the input file * @throws IOException if an IO error occurs */ public void load(File file) throws IOException { BufferedReader in = new BufferedReader(new FileReader(file)); try { DataAdapter da = new StreamDataAdapter(in); da.computeStats(); in = new BufferedReader(new FileReader(file)); fillBinStats(in); loaded = true; } finally { try { in.close(); } catch (IOException ex) { // ignore } } } /** * Provides methods for computing sampleStats and * beanStats abstracting the source of data. */ private abstract class DataAdapter{ /** * Compute bin stats. * * @throws IOException if an error occurs computing bin stats */ public abstract void computeBinStats() throws IOException; /** * Compute sample statistics. * * @throws IOException if an error occurs computing sample stats */ public abstract void computeStats() throws IOException; } /** * Factory of DataAdapter objects. For every supported source * of data (array of doubles, file, etc.) an instance of the proper object * is returned. */ private class DataAdapterFactory{ /** * Creates a DataAdapter from a data object * * @param in object providing access to the data * @return DataAdapter instance */ public DataAdapter getAdapter(Object in) { if (in instanceof BufferedReader) { BufferedReader inputStream = (BufferedReader) in; return new StreamDataAdapter(inputStream); } else if (in instanceof double[]) { double[] inputArray = (double[]) in; return new ArrayDataAdapter(inputArray); } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE, in.getClass().getName(), BufferedReader.class.getName(), double[].class.getName()); } } } /** * DataAdapter for data provided through some input stream */ private class StreamDataAdapter extends DataAdapter{ /** Input stream providing access to the data */ private BufferedReader inputStream; /** * Create a StreamDataAdapter from a BufferedReader * * @param in BufferedReader input stream */ public StreamDataAdapter(BufferedReader in){ super(); inputStream = in; } /** {@inheritDoc} */ @Override public void computeBinStats() throws IOException { String str = null; double val = 0.0d; while ((str = inputStream.readLine()) != null) { val = Double.parseDouble(str); SummaryStatistics stats = binStats.get(findBin(val)); stats.addValue(val); } inputStream.close(); inputStream = null; } /** {@inheritDoc} */ @Override public void computeStats() throws IOException { String str = null; double val = 0.0; sampleStats = new SummaryStatistics(); while ((str = inputStream.readLine()) != null) { val = Double.valueOf(str).doubleValue(); sampleStats.addValue(val); } inputStream.close(); inputStream = null; } } /** * DataAdapter for data provided as array of doubles. */ private class ArrayDataAdapter extends DataAdapter { /** Array of input data values */ private double[] inputArray; /** * Construct an ArrayDataAdapter from a double[] array * * @param in double[] array holding the data */ public ArrayDataAdapter(double[] in){ super(); inputArray = in; } /** {@inheritDoc} */ @Override public void computeStats() throws IOException { sampleStats = new SummaryStatistics(); for (int i = 0; i < inputArray.length; i++) { sampleStats.addValue(inputArray[i]); } } /** {@inheritDoc} */ @Override public void computeBinStats() throws IOException { for (int i = 0; i < inputArray.length; i++) { SummaryStatistics stats = binStats.get(findBin(inputArray[i])); stats.addValue(inputArray[i]); } } } /** * Fills binStats array (second pass through data file). * * @param in object providing access to the data * @throws IOException if an IO error occurs */ private void fillBinStats(Object in) throws IOException { // Set up grid min = sampleStats.getMin(); max = sampleStats.getMax(); delta = (max - min)/(Double.valueOf(binCount)).doubleValue(); // Initialize binStats ArrayList if (!binStats.isEmpty()) { binStats.clear(); } for (int i = 0; i < binCount; i++) { SummaryStatistics stats = new SummaryStatistics(); binStats.add(i,stats); } // Filling data in binStats Array DataAdapterFactory aFactory = new DataAdapterFactory(); DataAdapter da = aFactory.getAdapter(in); da.computeBinStats(); // Assign upperBounds based on bin counts upperBounds = new double[binCount]; upperBounds[0] = ((double) binStats.get(0).getN()) / (double) sampleStats.getN(); for (int i = 1; i < binCount-1; i++) { upperBounds[i] = upperBounds[i-1] + ((double) binStats.get(i).getN()) / (double) sampleStats.getN(); } upperBounds[binCount-1] = 1.0d; } /** * Returns the index of the bin to which the given value belongs * * @param value the value whose bin we are trying to find * @return the index of the bin containing the value */ private int findBin(double value) { return FastMath.min( FastMath.max((int) FastMath.ceil((value- min) / delta) - 1, 0), binCount - 1); } /** * Generates a random value from this distribution. * * @return the random value. * @throws IllegalStateException if the distribution has not been loaded */ public double getNextValue() throws IllegalStateException { if (!loaded) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.DISTRIBUTION_NOT_LOADED); } // Start with a uniformly distributed random number in (0,1) double x = FastMath.random(); // Use this to select the bin and generate a Gaussian within the bin for (int i = 0; i < binCount; i++) { if (x <= upperBounds[i]) { SummaryStatistics stats = binStats.get(i); if (stats.getN() > 0) { if (stats.getStandardDeviation() > 0) { // more than one obs return randomData.nextGaussian (stats.getMean(),stats.getStandardDeviation()); } else { return stats.getMean(); // only one obs in bin } } } } throw new MathRuntimeException(LocalizedFormats.NO_BIN_SELECTED); } /** * Returns a {@link StatisticalSummary} describing this distribution. * Preconditions:
                      *
                    • the distribution must be loaded before invoking this method
                    * * @return the sample statistics * @throws IllegalStateException if the distribution has not been loaded */ public StatisticalSummary getSampleStats() { return sampleStats; } /** * Returns the number of bins. * * @return the number of bins. */ public int getBinCount() { return binCount; } /** * Returns a List of {@link SummaryStatistics} instances containing * statistics describing the values in each of the bins. The list is * indexed on the bin number. * * @return List of bin statistics. */ public List getBinStats() { return binStats; } /** *

                    Returns a fresh copy of the array of upper bounds for the bins. * Bins are:
                    * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],..., * (upperBounds[binCount-2], upperBounds[binCount-1] = max].

                    * *

                    Note: In versions 1.0-2.0 of commons-math, this method * incorrectly returned the array of probability generator upper * bounds now returned by {@link #getGeneratorUpperBounds()}.

                    * * @return array of bin upper bounds * @since 2.1 */ public double[] getUpperBounds() { double[] binUpperBounds = new double[binCount]; binUpperBounds[0] = min + delta; for (int i = 1; i < binCount - 1; i++) { binUpperBounds[i] = binUpperBounds[i-1] + delta; } binUpperBounds[binCount - 1] = max; return binUpperBounds; } /** *

                    Returns a fresh copy of the array of upper bounds of the subintervals * of [0,1] used in generating data from the empirical distribution. * Subintervals correspond to bins with lengths proportional to bin counts.

                    * *

                    In versions 1.0-2.0 of commons-math, this array was (incorrectly) returned * by {@link #getUpperBounds()}.

                    * * @since 2.1 * @return array of upper bounds of subintervals used in data generation */ public double[] getGeneratorUpperBounds() { int len = upperBounds.length; double[] out = new double[len]; System.arraycopy(upperBounds, 0, out, 0, len); return out; } /** * Property indicating whether or not the distribution has been loaded. * * @return true if the distribution has been loaded */ public boolean isLoaded() { return loaded; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/package.html100644 1750 1750 20706 11532241245 26132 0ustarlucluc 0 0

                    Random number and random data generators.

                    Commons-math provides a few pseudo random number generators. The top level interface is RandomGenerator. It is implemented by three classes:

                    • {@link org.apache.commons.math.random.JDKRandomGenerator JDKRandomGenerator} that extends the JDK provided generator
                    • AbstractRandomGenerator as a helper for users generators
                    • BitStreamGenerator which is an abstract class for several generators and which in turn is extended by:
                      • {@link org.apache.commons.math.random.MersenneTwister MersenneTwister}
                      • {@link org.apache.commons.math.random.Well512a Well512a}
                      • {@link org.apache.commons.math.random.Well1024a Well1024a}
                      • {@link org.apache.commons.math.random.Well19937a Well19937a}
                      • {@link org.apache.commons.math.random.Well19937c Well19937c}
                      • {@link org.apache.commons.math.random.Well44497a Well44497a}
                      • {@link org.apache.commons.math.random.Well44497b Well44497b}

                    The JDK provided generator is a simple one that can be used only for very simple needs. The Mersenne Twister is a fast generator with very good properties well suited for Monte-Carlo simulation. It is equidistributed for generating vectors up to dimension 623 and has a huge period: 219937 - 1 (which is a Mersenne prime). This generator is described in a paper by Makoto Matsumoto and Takuji Nishimura in 1998: Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30. The WELL generators are a family of generators with period ranging from 2512 - 1 to 244497 - 1 (this last one is also a Mersenne prime) with even better properties than Mersenne Twister. These generators are described in a paper by François Panneton, Pierre L'Ecuyer and Makoto Matsumoto Improved Long-Period Generators Based on Linear Recurrences Modulo 2 ACM Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper are in wellrng-errata.txt.

                    For simple sampling, any of these generators is sufficient. For Monte-Carlo simulations the JDK generator does not have any of the good mathematical properties of the other generators, so it should be avoided. The Mersenne twister and WELL generators have equidistribution properties proven according to their bits pool size which is directly linked to their period (all of them have maximal period, i.e. a generator with size n pool has a period 2n-1). They also have equidistribution properties for 32 bits blocks up to s/32 dimension where s is their pool size. So WELL19937c for exemple is equidistributed up to dimension 623 (19937/32). This means a Monte-Carlo simulation generating a vector of n variables at each iteration has some guarantees on the properties of the vector as long as its dimension does not exceed the limit. However, since we use bits from two successive 32 bits generated integers to create one double, this limit is smaller when the variables are of type double. so for Monte-Carlo simulation where less the 16 doubles are generated at each round, WELL1024 may be sufficient. If a larger number of doubles are needed a generator with a larger pool would be useful.

                    The WELL generators are more modern then MersenneTwister (the paper describing than has been published in 2006 instead of 1998) and fix some of its (few) drawbacks. If initialization array contains many zero bits, MersenneTwister may take a very long time (several hundreds of thousands of iterations to reach a steady state with a balanced number of zero and one in its bits pool). So the WELL generators are better to escape zeroland as explained by the WELL generators creators. The Well19937a and Well44497a generator are not maximally equidistributed (i.e. there are some dimensions or bits blocks size for which they are not equidistributed). The Well512a, Well1024a, Well19937c and Well44497b are maximally equidistributed for blocks size up to 32 bits (they should behave correctly also for double based on more than 32 bits blocks, but equidistribution is not proven at these blocks sizes).

                    The MersenneTwister generator uses a 624 elements integer array, so it consumes less than 2.5 kilobytes. The WELL generators use 6 integer arrays with a size equal to the pool size, so for example the WELL44497b generator uses about 33 kilobytes. This may be important if a very large number of generator instances were used at the same time.

                    All generators are quite fast. As an example, here are some comparisons, obtained on a 64 bits JVM on a linux computer with a 2008 processor (AMD phenom Quad 9550 at 2.2 GHz). The generation rate for MersenneTwister was about 27 millions doubles per second (remember we generate two 32 bits integers for each double). Generation rates for other PRNG, relative to MersenneTwister:

                    Example of performances
                    Namegeneration rate (relative to MersenneTwister)
                    {@link org.apache.commons.math.random.MersenneTwister MersenneTwister}1
                    {@link org.apache.commons.math.random.JDKRandomGenerator JDKRandomGenerator}between 0.96 and 1.16
                    {@link org.apache.commons.math.random.Well512a Well512a}between 0.85 and 0.88
                    {@link org.apache.commons.math.random.Well1024a Well1024a}between 0.63 and 0.73
                    {@link org.apache.commons.math.random.Well19937a Well19937a}between 0.70 and 0.71
                    {@link org.apache.commons.math.random.Well19937c Well19937c}between 0.57 and 0.71
                    {@link org.apache.commons.math.random.Well44497a Well44497a}between 0.69 and 0.71
                    {@link org.apache.commons.math.random.Well44497b Well44497b}between 0.65 and 0.71

                    So for most simulation problems, the better generators like {@link org.apache.commons.math.random.Well19937c Well19937c} and {@link org.apache.commons.math.random.Well44497b Well44497b} are probably very good choices.

                    Note that none of these generators are suitable for cryptography. They are devoted to simulation, and to generate very long series with strong properties on the series as a whole (equidistribution, no correlation ...). They do not attempt to create small series but with very strong properties of unpredictability as needed in cryptography.

                    commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well44497b.java100644 1750 1750 10547 11532241245 26177 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL44497b pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well44497b extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = 4032007538246675492L; /** Number of bits in the pool. */ private static final int K = 44497; /** First parameter of the algorithm. */ private static final int M1 = 23; /** Second parameter of the algorithm. */ private static final int M2 = 481; /** Third parameter of the algorithm. */ private static final int M3 = 229; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well44497b() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well44497b(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well44497b(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well44497b(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { // compute raw value given by WELL44497a generator // which is NOT maximally-equidistributed final int indexRm1 = iRm1[index]; final int indexRm2 = iRm2[index]; final int v0 = v[index]; final int vM1 = v[i1[index]]; final int vM2 = v[i2[index]]; final int vM3 = v[i3[index]]; // the values below include the errata of the original article final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]); final int z1 = (v0 ^ (v0 << 24)) ^ (vM1 ^ (vM1 >>> 30)); final int z2 = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26); final int z3 = z1 ^ z2; final int z2Prime = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff; final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) : z2Prime; int z4 = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3; v[index] = z3; v[indexRm1] = z4; v[indexRm2] &= 0xFFFF8000; index = indexRm1; // add Matsumoto-Kurita tempering // to get a maximally-equidistributed generator z4 = z4 ^ ((z4 << 7) & 0x93dd1400); z4 = z4 ^ ((z4 << 15) & 0xfa118000); return z4 >>> (32 - bits); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/RandomAdaptor.java100644 1750 1750 15274 11532241245 27253 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Random; /** * Extension of java.util.Random wrapping a * {@link RandomGenerator}. * * @since 1.1 * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ */ public class RandomAdaptor extends Random implements RandomGenerator { /** Serializable version identifier. */ private static final long serialVersionUID = 2306581345647615033L; /** Wrapped randomGenerator instance */ private final RandomGenerator randomGenerator; /** * Prevent instantiation without a generator argument */ @SuppressWarnings("unused") private RandomAdaptor() { randomGenerator = null; } /** * Construct a RandomAdaptor wrapping the supplied RandomGenerator. * * @param randomGenerator the wrapped generator */ public RandomAdaptor(RandomGenerator randomGenerator) { this.randomGenerator = randomGenerator; } /** * Factory method to create a Random using the supplied * RandomGenerator. * * @param randomGenerator wrapped RandomGenerator instance * @return a Random instance wrapping the RandomGenerator */ public static Random createAdaptor(RandomGenerator randomGenerator) { return new RandomAdaptor(randomGenerator); } /** * Returns the next pseudorandom, uniformly distributed * boolean value from this random number generator's * sequence. * * @return the next pseudorandom, uniformly distributed * boolean value from this random number generator's * sequence */ @Override public boolean nextBoolean() { return randomGenerator.nextBoolean(); } /** * Generates random bytes and places them into a user-supplied * byte array. The number of random bytes produced is equal to * the length of the byte array. * * @param bytes the non-null byte array in which to put the * random bytes */ @Override public void nextBytes(byte[] bytes) { randomGenerator.nextBytes(bytes); } /** * Returns the next pseudorandom, uniformly distributed * double value between 0.0 and * 1.0 from this random number generator's sequence. * * @return the next pseudorandom, uniformly distributed * double value between 0.0 and * 1.0 from this random number generator's sequence */ @Override public double nextDouble() { return randomGenerator.nextDouble(); } /** * Returns the next pseudorandom, uniformly distributed float * value between 0.0 and 1.0 from this random * number generator's sequence. * * @return the next pseudorandom, uniformly distributed float * value between 0.0 and 1.0 from this * random number generator's sequence */ @Override public float nextFloat() { return randomGenerator.nextFloat(); } /** * Returns the next pseudorandom, Gaussian ("normally") distributed * double value with mean 0.0 and standard * deviation 1.0 from this random number generator's sequence. * * @return the next pseudorandom, Gaussian ("normally") distributed * double value with mean 0.0 and * standard deviation 1.0 from this random number * generator's sequence */ @Override public double nextGaussian() { return randomGenerator.nextGaussian(); } /** * Returns the next pseudorandom, uniformly distributed int * value from this random number generator's sequence. * All 232 possible int values * should be produced with (approximately) equal probability. * * @return the next pseudorandom, uniformly distributed int * value from this random number generator's sequence */ @Override public int nextInt() { return randomGenerator.nextInt(); } /** * Returns a pseudorandom, uniformly distributed int value * between 0 (inclusive) and the specified value (exclusive), drawn from * this random number generator's sequence. * * @param n the bound on the random number to be returned. Must be * positive. * @return a pseudorandom, uniformly distributed int * value between 0 (inclusive) and n (exclusive). * @throws IllegalArgumentException if n is not positive. */ @Override public int nextInt(int n) { return randomGenerator.nextInt(n); } /** * Returns the next pseudorandom, uniformly distributed long * value from this random number generator's sequence. All * 264 possible long values * should be produced with (approximately) equal probability. * * @return the next pseudorandom, uniformly distributed long *value from this random number generator's sequence */ @Override public long nextLong() { return randomGenerator.nextLong(); } /** {@inheritDoc} */ public void setSeed(int seed) { if (randomGenerator != null) { // required to avoid NPE in constructor randomGenerator.setSeed(seed); } } /** {@inheritDoc} */ public void setSeed(int[] seed) { if (randomGenerator != null) { // required to avoid NPE in constructor randomGenerator.setSeed(seed); } } /** {@inheritDoc} */ @Override public void setSeed(long seed) { if (randomGenerator != null) { // required to avoid NPE in constructor randomGenerator.setSeed(seed); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well44497a.java100644 1750 1750 10075 11532241245 26172 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL44497a pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well44497a extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = -3859207588353972099L; /** Number of bits in the pool. */ private static final int K = 44497; /** First parameter of the algorithm. */ private static final int M1 = 23; /** Second parameter of the algorithm. */ private static final int M2 = 481; /** Third parameter of the algorithm. */ private static final int M3 = 229; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well44497a() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well44497a(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well44497a(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well44497a(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { final int indexRm1 = iRm1[index]; final int indexRm2 = iRm2[index]; final int v0 = v[index]; final int vM1 = v[i1[index]]; final int vM2 = v[i2[index]]; final int vM3 = v[i3[index]]; // the values below include the errata of the original article final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]); final int z1 = (v0 ^ (v0 << 24)) ^ (vM1 ^ (vM1 >>> 30)); final int z2 = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26); final int z3 = z1 ^ z2; final int z2Prime = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff; final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) : z2Prime; final int z4 = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3; v[index] = z3; v[indexRm1] = z4; v[indexRm2] &= 0xFFFF8000; index = indexRm1; return z4 >>> (32 - bits); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/MersenneTwister.java100644 1750 1750 23177 11532241245 27657 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.io.Serializable; import org.apache.commons.math.util.FastMath; /** This class implements a powerful pseudo-random number generator * developed by Makoto Matsumoto and Takuji Nishimura during * 1996-1997. *

                    This generator features an extremely long period * (219937-1) and 623-dimensional equidistribution up to 32 * bits accuracy. The home page for this generator is located at * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html.

                    *

                    This generator is described in a paper by Makoto Matsumoto and * Takuji Nishimura in 1998: Mersenne * Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random * Number Generator, ACM Transactions on Modeling and Computer * Simulation, Vol. 8, No. 1, January 1998, pp 3--30

                    *

                    This class is mainly a Java port of the 2002-01-26 version of * the generator written in C by Makoto Matsumoto and Takuji * Nishimura. Here is their original copyright:

                    * * * * *
                    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, * All rights reserved.
                    Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                      *
                    1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
                    2. *
                    3. 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.
                    4. *
                    5. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission.
                    6. *
                    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR 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.
                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class MersenneTwister extends BitsStreamGenerator implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 8661194735290153518L; /** Size of the bytes pool. */ private static final int N = 624; /** Period second parameter. */ private static final int M = 397; /** X * MATRIX_A for X = {0, 1}. */ private static final int[] MAG01 = { 0x0, 0x9908b0df }; /** Bytes pool. */ private int[] mt; /** Current index in the bytes pool. */ private int mti; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public MersenneTwister() { mt = new int[N]; setSeed(System.currentTimeMillis()); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public MersenneTwister(int seed) { mt = new int[N]; setSeed(seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public MersenneTwister(int[] seed) { mt = new int[N]; setSeed(seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public MersenneTwister(long seed) { mt = new int[N]; setSeed(seed); } /** Reinitialize the generator as if just built with the given int seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (32 bits integer) */ @Override public void setSeed(int seed) { // we use a long masked by 0xffffffffL as a poor man unsigned int long longMT = seed; mt[0]= (int) longMT; for (mti = 1; mti < N; ++mti) { // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. // initializer from the 2002-01-09 C version by Makoto Matsumoto longMT = (1812433253l * (longMT ^ (longMT >> 30)) + mti) & 0xffffffffL; mt[mti]= (int) longMT; } } /** Reinitialize the generator as if just built with the given int array seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ @Override public void setSeed(int[] seed) { if (seed == null) { setSeed(System.currentTimeMillis()); return; } setSeed(19650218); int i = 1; int j = 0; for (int k = FastMath.max(N, seed.length); k != 0; k--) { long l0 = (mt[i] & 0x7fffffffl) | ((mt[i] < 0) ? 0x80000000l : 0x0l); long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l); long l = (l0 ^ ((l1 ^ (l1 >> 30)) * 1664525l)) + seed[j] + j; // non linear mt[i] = (int) (l & 0xffffffffl); i++; j++; if (i >= N) { mt[0] = mt[N - 1]; i = 1; } if (j >= seed.length) { j = 0; } } for (int k = N - 1; k != 0; k--) { long l0 = (mt[i] & 0x7fffffffl) | ((mt[i] < 0) ? 0x80000000l : 0x0l); long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l); long l = (l0 ^ ((l1 ^ (l1 >> 30)) * 1566083941l)) - i; // non linear mt[i] = (int) (l & 0xffffffffL); i++; if (i >= N) { mt[0] = mt[N - 1]; i = 1; } } mt[0] = 0x80000000; // MSB is 1; assuring non-zero initial array } /** Reinitialize the generator as if just built with the given long seed. *

                    The state of the generator is exactly the same as a new * generator built with the same seed.

                    * @param seed the initial seed (64 bits integer) */ @Override public void setSeed(long seed) { setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) }); } /** Generate next pseudorandom number. *

                    This method is the core generation algorithm. It is used by all the * public generation methods for the various primitive types {@link * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()}, * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()}, * {@link #next(int)} and {@link #nextLong()}.

                    * @param bits number of random bits to produce * @return random bits generated */ @Override protected int next(int bits) { int y; if (mti >= N) { // generate N words at one time int mtNext = mt[0]; for (int k = 0; k < N - M; ++k) { int mtCurr = mtNext; mtNext = mt[k + 1]; y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff); mt[k] = mt[k + M] ^ (y >>> 1) ^ MAG01[y & 0x1]; } for (int k = N - M; k < N - 1; ++k) { int mtCurr = mtNext; mtNext = mt[k + 1]; y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff); mt[k] = mt[k + (M - N)] ^ (y >>> 1) ^ MAG01[y & 0x1]; } y = (mtNext & 0x80000000) | (mt[0] & 0x7fffffff); mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ MAG01[y & 0x1]; mti = 0; } y = mt[mti++]; // tempering y ^= y >>> 11; y ^= (y << 7) & 0x9d2c5680; y ^= (y << 15) & 0xefc60000; y ^= y >>> 18; return y >>> (32 - bits); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.100644 1750 1750 6473 11532241245 32461 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Arrays; import org.apache.commons.math.exception.DimensionMismatchException; /** * A {@link RandomVectorGenerator} that generates vectors with uncorrelated * components. Components of generated vectors follow (independent) Gaussian * distributions, with parameters supplied in the constructor. * * @version $Revision: 962515 $ $Date: 2010-07-09 15:15:28 +0200 (ven. 09 juil. 2010) $ * @since 1.2 */ public class UncorrelatedRandomVectorGenerator implements RandomVectorGenerator { /** Underlying scalar generator. */ private final NormalizedRandomGenerator generator; /** Mean vector. */ private final double[] mean; /** Standard deviation vector. */ private final double[] standardDeviation; /** Simple constructor. *

                    Build an uncorrelated random vector generator from * its mean and standard deviation vectors.

                    * @param mean expected mean values for each component * @param standardDeviation standard deviation for each component * @param generator underlying generator for uncorrelated normalized * components */ public UncorrelatedRandomVectorGenerator(double[] mean, double[] standardDeviation, NormalizedRandomGenerator generator) { if (mean.length != standardDeviation.length) { throw new DimensionMismatchException(mean.length, standardDeviation.length); } this.mean = mean.clone(); this.standardDeviation = standardDeviation.clone(); this.generator = generator; } /** Simple constructor. *

                    Build a null mean random and unit standard deviation * uncorrelated vector generator

                    * @param dimension dimension of the vectors to generate * @param generator underlying generator for uncorrelated normalized * components */ public UncorrelatedRandomVectorGenerator(int dimension, NormalizedRandomGenerator generator) { mean = new double[dimension]; standardDeviation = new double[dimension]; Arrays.fill(standardDeviation, 1.0); this.generator = generator; } /** Generate an uncorrelated random vector. * @return a random vector as a newly built array of double */ public double[] nextVector() { double[] random = new double[mean.length]; for (int i = 0; i < random.length; ++i) { random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble(); } return random; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/JDKRandomGenerator.java100644 1750 1750 3251 11532241245 30110 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import java.util.Random; /** * Extension of java.util.Random to implement * {@link RandomGenerator}. * * @since 1.1 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class JDKRandomGenerator extends Random implements RandomGenerator { /** Serializable version identifier. */ private static final long serialVersionUID = -7745277476784028798L; /** {@inheritDoc} */ public void setSeed(int seed) { setSeed((long) seed); } /** {@inheritDoc} */ public void setSeed(int[] seed) { // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5) final long prime = 4294967291l; long combined = 0l; for (int s : seed) { combined = combined * prime + s; } setSeed(combined); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/NormalizedRandomGenerator.java100644 1750 1750 3060 11532241245 31602 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** * This interface represent a normalized random generator for * scalars. * Normalized generator provide null mean and unit standard deviation scalars. * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 1.2 */ public interface NormalizedRandomGenerator { /** Generate a random scalar with null mean and unit standard deviation. *

                    This method does not specify the shape of the * distribution, it is the implementing class that provides it. The * only contract here is to generate numbers with null mean and unit * standard deviation.

                    * @return a random scalar with null mean and unit standard deviation */ double nextNormalizedDouble(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/UniformRandomGenerator.java100644 1750 1750 4304 11532241245 31117 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.util.FastMath; /** * This class implements a normalized uniform random generator. *

                    Since it is a normalized random generator, it generates values * from a uniform distribution with mean equal to 0 and standard * deviation equal to 1. Generated values fall in the range * [-√3, +√3].

                    * * @since 1.2 * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class UniformRandomGenerator implements NormalizedRandomGenerator { /** Serializable version identifier. */ private static final long serialVersionUID = 1569292426375546027L; /** Square root of three. */ private static final double SQRT3 = FastMath.sqrt(3.0); /** Underlying generator. */ private final RandomGenerator generator; /** Create a new generator. * @param generator underlying random generator to use */ public UniformRandomGenerator(RandomGenerator generator) { this.generator = generator; } /** Generate a random scalar with null mean and unit standard deviation. *

                    The number generated is uniformly distributed between -&sqrt;(3) * and +&sqrt;(3).

                    * @return a random scalar with null mean and unit standard deviation */ public double nextNormalizedDouble() { return SQRT3 * (2 * generator.nextDouble() - 1.0); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well19937a.java100644 1750 1750 7520 11532241245 26154 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL19937a pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well19937a extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = -7462102162223815419L; /** Number of bits in the pool. */ private static final int K = 19937; /** First parameter of the algorithm. */ private static final int M1 = 70; /** Second parameter of the algorithm. */ private static final int M2 = 179; /** Third parameter of the algorithm. */ private static final int M3 = 449; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well19937a() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well19937a(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well19937a(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well19937a(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { final int indexRm1 = iRm1[index]; final int indexRm2 = iRm2[index]; final int v0 = v[index]; final int vM1 = v[i1[index]]; final int vM2 = v[i2[index]]; final int vM3 = v[i3[index]]; final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]); final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27)); final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1)); final int z3 = z1 ^ z2; final int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 >>> 21)); v[index] = z3; v[indexRm1] = z4; v[indexRm2] &= 0x80000000; index = indexRm1; return z4 >>> (32 - bits); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well512a.java100644 1750 1750 7313 11532241245 25767 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL512a pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well512a extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = -6104179812103820574L; /** Number of bits in the pool. */ private static final int K = 512; /** First parameter of the algorithm. */ private static final int M1 = 13; /** Second parameter of the algorithm. */ private static final int M2 = 9; /** Third parameter of the algorithm. */ private static final int M3 = 5; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well512a() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well512a(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well512a(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well512a(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { final int indexRm1 = iRm1[index]; final int vi = v[index]; final int vi1 = v[i1[index]]; final int vi2 = v[i2[index]]; final int z0 = v[indexRm1]; // the values below include the errata of the original article final int z1 = (vi ^ (vi << 16)) ^ (vi1 ^ (vi1 << 15)); final int z2 = vi2 ^ (vi2 >>> 11); final int z3 = z1 ^ z2; final int z4 = (z0 ^ (z0 << 2)) ^ (z1 ^ (z1 << 18)) ^ (z2 << 28) ^ (z3 ^ ((z3 << 5) & 0xda442d24)); v[index] = z3; v[indexRm1] = z4; index = indexRm1; return z4 >>> (32 - bits); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.ja100644 1750 1750 26662 11532241245 32453 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.util.FastMath; /** * A {@link RandomVectorGenerator} that generates vectors with with * correlated components. *

                    Random vectors with correlated components are built by combining * the uncorrelated components of another random vector in such a way that * the resulting correlations are the ones specified by a positive * definite covariance matrix.

                    *

                    The main use for correlated random vector generation is for Monte-Carlo * simulation of physical problems with several variables, for example to * generate error vectors to be added to a nominal vector. A particularly * interesting case is when the generated vector should be drawn from a * Multivariate Normal Distribution. The approach using a Cholesky * decomposition is quite usual in this case. However, it can be extended * to other cases as long as the underlying random generator provides * {@link NormalizedRandomGenerator normalized values} like {@link * GaussianRandomGenerator} or {@link UniformRandomGenerator}.

                    *

                    Sometimes, the covariance matrix for a given simulation is not * strictly positive definite. This means that the correlations are * not all independent from each other. In this case, however, the non * strictly positive elements found during the Cholesky decomposition * of the covariance matrix should not be negative either, they * should be null. Another non-conventional extension handling this case * is used here. Rather than computing C = UT.U * where C is the covariance matrix and U * is an upper-triangular matrix, we compute C = B.BT * where B is a rectangular matrix having * more rows than columns. The number of columns of B is * the rank of the covariance matrix, and it is the dimension of the * uncorrelated random vector that is needed to compute the component * of the correlated vector. This class handles this situation * automatically.

                    * * @version $Revision: 1043908 $ $Date: 2010-12-09 12:53:14 +0100 (jeu. 09 déc. 2010) $ * @since 1.2 */ public class CorrelatedRandomVectorGenerator implements RandomVectorGenerator { /** Mean vector. */ private final double[] mean; /** Underlying generator. */ private final NormalizedRandomGenerator generator; /** Storage for the normalized vector. */ private final double[] normalized; /** Permutated Cholesky root of the covariance matrix. */ private RealMatrix root; /** Rank of the covariance matrix. */ private int rank; /** Simple constructor. *

                    Build a correlated random vector generator from its mean * vector and covariance matrix.

                    * @param mean expected mean values for all components * @param covariance covariance matrix * @param small diagonal elements threshold under which column are * considered to be dependent on previous ones and are discarded * @param generator underlying generator for uncorrelated normalized * components * @exception IllegalArgumentException if there is a dimension * mismatch between the mean vector and the covariance matrix * @exception NotPositiveDefiniteMatrixException if the * covariance matrix is not strictly positive definite * @exception DimensionMismatchException if the mean and covariance * arrays dimensions don't match */ public CorrelatedRandomVectorGenerator(double[] mean, RealMatrix covariance, double small, NormalizedRandomGenerator generator) throws NotPositiveDefiniteMatrixException, DimensionMismatchException { int order = covariance.getRowDimension(); if (mean.length != order) { throw new DimensionMismatchException(mean.length, order); } this.mean = mean.clone(); decompose(covariance, small); this.generator = generator; normalized = new double[rank]; } /** Simple constructor. *

                    Build a null mean random correlated vector generator from its * covariance matrix.

                    * @param covariance covariance matrix * @param small diagonal elements threshold under which column are * considered to be dependent on previous ones and are discarded * @param generator underlying generator for uncorrelated normalized * components * @exception NotPositiveDefiniteMatrixException if the * covariance matrix is not strictly positive definite */ public CorrelatedRandomVectorGenerator(RealMatrix covariance, double small, NormalizedRandomGenerator generator) throws NotPositiveDefiniteMatrixException { int order = covariance.getRowDimension(); mean = new double[order]; for (int i = 0; i < order; ++i) { mean[i] = 0; } decompose(covariance, small); this.generator = generator; normalized = new double[rank]; } /** Get the underlying normalized components generator. * @return underlying uncorrelated components generator */ public NormalizedRandomGenerator getGenerator() { return generator; } /** Get the root of the covariance matrix. * The root is the rectangular matrix B such that * the covariance matrix is equal to B.BT * @return root of the square matrix * @see #getRank() */ public RealMatrix getRootMatrix() { return root; } /** Get the rank of the covariance matrix. * The rank is the number of independent rows in the covariance * matrix, it is also the number of columns of the rectangular * matrix of the decomposition. * @return rank of the square matrix. * @see #getRootMatrix() */ public int getRank() { return rank; } /** Decompose the original square matrix. *

                    The decomposition is based on a Choleski decomposition * where additional transforms are performed: *

                      *
                    • the rows of the decomposed matrix are permuted
                    • *
                    • columns with the too small diagonal element are discarded
                    • *
                    • the matrix is permuted
                    • *
                    * This means that rather than computing M = UT.U where U * is an upper triangular matrix, this method computed M=B.BT * where B is a rectangular matrix. * @param covariance covariance matrix * @param small diagonal elements threshold under which column are * considered to be dependent on previous ones and are discarded * @exception NotPositiveDefiniteMatrixException if the * covariance matrix is not strictly positive definite */ private void decompose(RealMatrix covariance, double small) throws NotPositiveDefiniteMatrixException { int order = covariance.getRowDimension(); double[][] c = covariance.getData(); double[][] b = new double[order][order]; int[] swap = new int[order]; int[] index = new int[order]; for (int i = 0; i < order; ++i) { index[i] = i; } rank = 0; for (boolean loop = true; loop;) { // find maximal diagonal element swap[rank] = rank; for (int i = rank + 1; i < order; ++i) { int ii = index[i]; int isi = index[swap[i]]; if (c[ii][ii] > c[isi][isi]) { swap[rank] = i; } } // swap elements if (swap[rank] != rank) { int tmp = index[rank]; index[rank] = index[swap[rank]]; index[swap[rank]] = tmp; } // check diagonal element int ir = index[rank]; if (c[ir][ir] < small) { if (rank == 0) { throw new NotPositiveDefiniteMatrixException(); } // check remaining diagonal elements for (int i = rank; i < order; ++i) { if (c[index[i]][index[i]] < -small) { // there is at least one sufficiently negative diagonal element, // the covariance matrix is wrong throw new NotPositiveDefiniteMatrixException(); } } // all remaining diagonal elements are close to zero, // we consider we have found the rank of the covariance matrix ++rank; loop = false; } else { // transform the matrix double sqrt = FastMath.sqrt(c[ir][ir]); b[rank][rank] = sqrt; double inverse = 1 / sqrt; for (int i = rank + 1; i < order; ++i) { int ii = index[i]; double e = inverse * c[ii][ir]; b[i][rank] = e; c[ii][ii] -= e * e; for (int j = rank + 1; j < i; ++j) { int ij = index[j]; double f = c[ii][ij] - e * b[j][rank]; c[ii][ij] = f; c[ij][ii] = f; } } // prepare next iteration loop = ++rank < order; } } // build the root matrix root = MatrixUtils.createRealMatrix(order, rank); for (int i = 0; i < order; ++i) { for (int j = 0; j < rank; ++j) { root.setEntry(index[i], j, b[i][j]); } } } /** Generate a correlated random vector. * @return a random vector as an array of double. The returned array * is created at each call, the caller can do what it wants with it. */ public double[] nextVector() { // generate uncorrelated vector for (int i = 0; i < rank; ++i) { normalized[i] = generator.nextNormalizedDouble(); } // compute correlated vector double[] correlated = new double[mean.length]; for (int i = 0; i < correlated.length; ++i) { correlated[i] = mean[i]; for (int j = 0; j < rank; ++j) { correlated[i] += root.getEntry(i, j) * normalized[j]; } } return correlated; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/random/Well19937c.java100644 1750 1750 10011 11532241245 26163 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.random; /** This class implements the WELL19937c pseudo-random number generator * from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto. *

                    This generator is described in a paper by François Panneton, * Pierre L'Ecuyer and Makoto Matsumoto Improved * Long-Period Generators Based on Linear Recurrences Modulo 2 ACM * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper * are in wellrng-errata.txt.

                    * @see WELL Random number generator * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Well19937c extends AbstractWell { /** Serializable version identifier. */ private static final long serialVersionUID = -7203498180754925124L; /** Number of bits in the pool. */ private static final int K = 19937; /** First parameter of the algorithm. */ private static final int M1 = 70; /** Second parameter of the algorithm. */ private static final int M2 = 179; /** Third parameter of the algorithm. */ private static final int M3 = 449; /** Creates a new random number generator. *

                    The instance is initialized using the current time as the * seed.

                    */ public Well19937c() { super(K, M1, M2, M3); } /** Creates a new random number generator using a single int seed. * @param seed the initial seed (32 bits integer) */ public Well19937c(int seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using an int array seed. * @param seed the initial seed (32 bits integers array), if null * the seed of the generator will be related to the current time */ public Well19937c(int[] seed) { super(K, M1, M2, M3, seed); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed (64 bits integer) */ public Well19937c(long seed) { super(K, M1, M2, M3, seed); } /** {@inheritDoc} */ @Override protected int next(final int bits) { final int indexRm1 = iRm1[index]; final int indexRm2 = iRm2[index]; final int v0 = v[index]; final int vM1 = v[i1[index]]; final int vM2 = v[i2[index]]; final int vM3 = v[i3[index]]; final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]); final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27)); final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1)); final int z3 = z1 ^ z2; int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 >>> 21)); v[index] = z3; v[indexRm1] = z4; v[indexRm2] &= 0x80000000; index = indexRm1; // add Matsumoto-Kurita tempering // to get a maximally-equidistributed generator z4 = z4 ^ ((z4 << 7) & 0xe46e1700); z4 = z4 ^ ((z4 << 15) & 0x9b868000); return z4 >>> (32 - bits); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.j100644 1750 1750 3307 11532241245 32370 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.MatrixVisitorException; /** * Default implementation of the {@link RealMatrixChangingVisitor} interface. *

                    * This class is a convenience to create custom visitors without defining all * methods. This class provides default implementations that do nothing. *

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class DefaultRealMatrixChangingVisitor implements RealMatrixChangingVisitor { /** {@inheritDoc} */ public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { } /** {@inheritDoc} */ public double visit(int row, int column, double value) throws MatrixVisitorException { return value; } /** {@inheritDoc} */ public double end() { return 0; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/BigMatrixImpl.java100644 1750 1750 152405 11532241245 27240 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.math.BigDecimal; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implementation of {@link BigMatrix} using a BigDecimal[][] array to store entries * and * LU decompostion to support linear system * solution and inverse. *

                    * The LU decompostion is performed as needed, to support the following operations:

                      *
                    • solve
                    • *
                    • isSingular
                    • *
                    • getDeterminant
                    • *
                    • inverse

                    *

                    * Usage notes:
                    *

                    • * The LU decomposition is stored and reused on subsequent calls. If matrix * data are modified using any of the public setXxx methods, the saved * decomposition is discarded. If data are modified via references to the * underlying array obtained using getDataRef(), then the stored * LU decomposition will not be discarded. In this case, you need to * explicitly invoke LUDecompose() to recompute the decomposition * before using any of the methods above.
                    • *
                    • * As specified in the {@link BigMatrix} interface, matrix element indexing * is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.

                    * * @deprecated as of 2.0, replaced by {@link Array2DRowFieldMatrix} with a {@link * org.apache.commons.math.util.BigReal} parameter * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ @Deprecated public class BigMatrixImpl implements BigMatrix, Serializable { /** BigDecimal 0 */ static final BigDecimal ZERO = new BigDecimal(0); /** BigDecimal 1 */ static final BigDecimal ONE = new BigDecimal(1); /** Bound to determine effective singularity in LU decomposition */ private static final BigDecimal TOO_SMALL = new BigDecimal(10E-12); /** Serialization id */ private static final long serialVersionUID = -1011428905656140431L; /** Entries of the matrix */ protected BigDecimal data[][] = null; /** Entries of cached LU decomposition. * All updates to data (other than luDecompose()) *must* set this to null */ protected BigDecimal lu[][] = null; /** Permutation associated with LU decomposition */ protected int[] permutation = null; /** Parity of the permutation associated with the LU decomposition */ protected int parity = 1; /** Rounding mode for divisions **/ private int roundingMode = BigDecimal.ROUND_HALF_UP; /*** BigDecimal scale ***/ private int scale = 64; /** * Creates a matrix with no data */ public BigMatrixImpl() { } /** * Create a new BigMatrix with the supplied row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public BigMatrixImpl(int rowDimension, int columnDimension) { if (rowDimension < 1 ) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1); } if (columnDimension < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1); } data = new BigDecimal[rowDimension][columnDimension]; lu = null; } /** * Create a new BigMatrix using d as the underlying * data array. *

                    The input array is copied, not referenced. This constructor has * the same effect as calling {@link #BigMatrixImpl(BigDecimal[][], boolean)} * with the second argument set to true.

                    * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null */ public BigMatrixImpl(BigDecimal[][] d) { this.copyIn(d); lu = null; } /** * Create a new BigMatrix using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * BigMatrix and not used directly, the copyArray may be * set to false * @param d data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #BigMatrixImpl(BigDecimal[][]) */ public BigMatrixImpl(BigDecimal[][] d, boolean copyArray) { if (copyArray) { copyIn(d); } else { if (d == null) { throw new NullPointerException(); } final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; r++) { if (d[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length); } } data = d; } lu = null; } /** * Create a new BigMatrix using d as the underlying * data array. *

                    Since the underlying array will hold BigDecimal * instances, it will be created.

                    * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null */ public BigMatrixImpl(double[][] d) { final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int row = 1; row < nRows; row++) { if (d[row].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[row].length); } } this.copyIn(d); lu = null; } /** * Create a new BigMatrix using the values represented by the strings in * d as the underlying data array. * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null */ public BigMatrixImpl(String[][] d) { final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int row = 1; row < nRows; row++) { if (d[row].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[row].length); } } this.copyIn(d); lu = null; } /** * Create a new (column) BigMatrix using v as the * data for the unique column of the v.length x 1 matrix * created. *

                    * The input array is copied, not referenced.

                    * * @param v column vector holding data for new matrix */ public BigMatrixImpl(BigDecimal[] v) { final int nRows = v.length; data = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = v[row]; } } /** * Create a new BigMatrix which is a copy of this. * * @return the cloned matrix */ public BigMatrix copy() { return new BigMatrixImpl(this.copyOut(), false); } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BigMatrix add(BigMatrix m) throws IllegalArgumentException { try { return add((BigMatrixImpl) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkAdditionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].add(m.getEntry(row, col)); } } return new BigMatrixImpl(outData, false); } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BigMatrixImpl add(BigMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] mRow = m.data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].add(mRow[col]); } } return new BigMatrixImpl(outData, false); } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BigMatrix subtract(BigMatrix m) throws IllegalArgumentException { try { return subtract((BigMatrixImpl) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].subtract(getEntry(row, col)); } } return new BigMatrixImpl(outData, false); } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BigMatrixImpl subtract(BigMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] mRow = m.data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].subtract(mRow[col]); } } return new BigMatrixImpl(outData, false); } /** * Returns the result of adding d to each entry of this. * * @param d value to be added to each entry * @return d + this */ public BigMatrix scalarAdd(BigDecimal d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].add(d); } } return new BigMatrixImpl(outData, false); } /** * Returns the result of multiplying each entry of this by d * @param d value to multiply all entries by * @return d * this */ public BigMatrix scalarMultiply(BigDecimal d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].multiply(d); } } return new BigMatrixImpl(outData, false); } /** * Returns the result of postmultiplying this by m. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BigMatrix multiply(BigMatrix m) throws IllegalArgumentException { try { return multiply((BigMatrixImpl) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int nRows = this.getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = this.getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[nRows][nCols]; for (int row = 0; row < nRows; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < nCols; col++) { BigDecimal sum = ZERO; for (int i = 0; i < nSum; i++) { sum = sum.add(dataRow[i].multiply(m.getEntry(i, col))); } outDataRow[col] = sum; } } return new BigMatrixImpl(outData, false); } } /** * Returns the result of postmultiplying this by m. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BigMatrixImpl multiply(BigMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int nRows = this.getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = this.getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[nRows][nCols]; for (int row = 0; row < nRows; row++) { final BigDecimal[] dataRow = data[row]; final BigDecimal[] outDataRow = outData[row]; for (int col = 0; col < nCols; col++) { BigDecimal sum = ZERO; for (int i = 0; i < nSum; i++) { sum = sum.add(dataRow[i].multiply(m.data[i][col])); } outDataRow[col] = sum; } } return new BigMatrixImpl(outData, false); } /** * Returns the result premultiplying this by m. * @param m matrix to premultiply by * @return m * this * @throws IllegalArgumentException * if rowDimension(this) != columnDimension(m) */ public BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException { return m.multiply(this); } /** * Returns matrix entries as a two-dimensional array. *

                    * Makes a fresh copy of the underlying data.

                    * * @return 2-dimensional array of entries */ public BigDecimal[][] getData() { return copyOut(); } /** * Returns matrix entries as a two-dimensional array. *

                    * Makes a fresh copy of the underlying data converted to * double values.

                    * * @return 2-dimensional array of entries */ public double[][] getDataAsDoubleArray() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final double d[][] = new double[nRows][nCols]; for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { d[i][j] = data[i][j].doubleValue(); } } return d; } /** * Returns a reference to the underlying data array. *

                    * Does not make a fresh copy of the underlying data.

                    * * @return 2-dimensional array of entries */ public BigDecimal[][] getDataRef() { return data; } /*** * Gets the rounding mode for division operations * The default is {@link java.math.BigDecimal#ROUND_HALF_UP} * @see BigDecimal * @return the rounding mode. */ public int getRoundingMode() { return roundingMode; } /*** * Sets the rounding mode for decimal divisions. * @see BigDecimal * @param roundingMode rounding mode for decimal divisions */ public void setRoundingMode(int roundingMode) { this.roundingMode = roundingMode; } /*** * Sets the scale for division operations. * The default is 64 * @see BigDecimal * @return the scale */ public int getScale() { return scale; } /*** * Sets the scale for division operations. * @see BigDecimal * @param scale scale for division operations */ public void setScale(int scale) { this.scale = scale; } /** * Returns the * maximum absolute row sum norm of the matrix. * * @return norm */ public BigDecimal getNorm() { BigDecimal maxColSum = ZERO; for (int col = 0; col < this.getColumnDimension(); col++) { BigDecimal sum = ZERO; for (int row = 0; row < this.getRowDimension(); row++) { sum = sum.add(data[row][col].abs()); } maxColSum = maxColSum.max(sum); } return maxColSum; } /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index * @param startColumn Initial column index * @param endColumn Final column index * @return The subMatrix containing the data of the * specified rows and columns * @exception MatrixIndexException if row or column selections are not valid */ public BigMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, startRow); MatrixUtils.checkRowIndex(this, endRow); if (startRow > endRow) { throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW, startRow, endRow); } MatrixUtils.checkColumnIndex(this, startColumn); MatrixUtils.checkColumnIndex(this, endColumn); if (startColumn > endColumn) { throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN, startColumn, endColumn); } final BigDecimal[][] subMatrixData = new BigDecimal[endRow - startRow + 1][endColumn - startColumn + 1]; for (int i = startRow; i <= endRow; i++) { System.arraycopy(data[i], startColumn, subMatrixData[i - startRow], 0, endColumn - startColumn + 1); } return new BigMatrixImpl(subMatrixData, false); } /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices must be non-empty * @param selectedColumns Array of column indices must be non-empty * @return The subMatrix containing the data in the * specified rows and columns * @exception MatrixIndexException if supplied row or column index arrays * are not valid */ public BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException { if (selectedRows.length * selectedColumns.length == 0) { if (selectedRows.length == 0) { throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY); } throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY); } final BigDecimal[][] subMatrixData = new BigDecimal[selectedRows.length][selectedColumns.length]; try { for (int i = 0; i < selectedRows.length; i++) { final BigDecimal[] subI = subMatrixData[i]; final BigDecimal[] dataSelectedI = data[selectedRows[i]]; for (int j = 0; j < selectedColumns.length; j++) { subI[j] = dataSelectedI[selectedColumns[j]]; } } } catch (ArrayIndexOutOfBoundsException e) { // we redo the loop with checks enabled // in order to generate an appropriate message for (final int row : selectedRows) { MatrixUtils.checkRowIndex(this, row); } for (final int column : selectedColumns) { MatrixUtils.checkColumnIndex(this, column); } } return new BigMatrixImpl(subMatrixData, false); } /** * Replace the submatrix starting at row, column using data in * the input subMatrix array. Indexes are 0-based. *

                    * Example:
                    * Starting with

                         * 1  2  3  4
                         * 5  6  7  8
                         * 9  0  1  2
                         * 
                    * and subMatrix = {{3, 4} {5,6}}, invoking * setSubMatrix(subMatrix,1,1)) will result in
                         * 1  2  3  4
                         * 5  3  4  8
                         * 9  5  6  2
                         * 

                    * * @param subMatrix array containing the submatrix replacement data * @param row row coordinate of the top, left element to be replaced * @param column column coordinate of the top, left element to be replaced * @throws MatrixIndexException if subMatrix does not fit into this * matrix from element in (row, column) * @throws IllegalArgumentException if subMatrix is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if subMatrix is null * @since 1.1 */ public void setSubMatrix(BigDecimal[][] subMatrix, int row, int column) throws MatrixIndexException { final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; r++) { if (subMatrix[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[r].length); } } if (data == null) { if (row > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row); } if (column > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column); } data = new BigDecimal[nRows][nCols]; System.arraycopy(subMatrix, 0, data, 0, subMatrix.length); } else { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); MatrixUtils.checkRowIndex(this, nRows + row - 1); MatrixUtils.checkColumnIndex(this, nCols + column - 1); } for (int i = 0; i < nRows; i++) { System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols); } lu = null; } /** * Returns the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be fetched * @return row matrix * @throws MatrixIndexException if the specified row index is invalid */ public BigMatrix getRowMatrix(int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final int ncols = this.getColumnDimension(); final BigDecimal[][] out = new BigDecimal[1][ncols]; System.arraycopy(data[row], 0, out[0], 0, ncols); return new BigMatrixImpl(out, false); } /** * Returns the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be fetched * @return column matrix * @throws MatrixIndexException if the specified column index is invalid */ public BigMatrix getColumnMatrix(int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final int nRows = this.getRowDimension(); final BigDecimal[][] out = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { out[row][0] = data[row][column]; } return new BigMatrixImpl(out, false); } /** * Returns the entries in row number row as an array. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ public BigDecimal[] getRow(int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final int ncols = this.getColumnDimension(); final BigDecimal[] out = new BigDecimal[ncols]; System.arraycopy(data[row], 0, out, 0, ncols); return out; } /** * Returns the entries in row number row as an array * of double values. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ public double[] getRowAsDoubleArray(int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final int ncols = this.getColumnDimension(); final double[] out = new double[ncols]; for (int i=0;icol
                    as an array. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param col the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ public BigDecimal[] getColumn(int col) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, col); final int nRows = this.getRowDimension(); final BigDecimal[] out = new BigDecimal[nRows]; for (int i = 0; i < nRows; i++) { out[i] = data[i][col]; } return out; } /** * Returns the entries in column number col as an array * of double values. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param col the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ public double[] getColumnAsDoubleArray(int col) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, col); final int nrows = this.getRowDimension(); final double[] out = new double[nrows]; for (int i=0;i * Row and column indices start at 0 and must satisfy *
                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid */ public BigDecimal getEntry(int row, int column) throws MatrixIndexException { try { return data[row][column]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** * Returns the entry in the specified row and column as a double. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row * or column index is not valid */ public double getEntryAsDouble(int row, int column) throws MatrixIndexException { return getEntry(row,column).doubleValue(); } /** * Returns the transpose matrix. * * @return transpose matrix */ public BigMatrix transpose() { final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); final BigDecimal[][] outData = new BigDecimal[nCols][nRows]; for (int row = 0; row < nRows; row++) { final BigDecimal[] dataRow = data[row]; for (int col = 0; col < nCols; col++) { outData[col][row] = dataRow[col]; } } return new BigMatrixImpl(outData, false); } /** * Returns the inverse matrix if this matrix is invertible. * * @return inverse matrix * @throws InvalidMatrixException if this is not invertible */ public BigMatrix inverse() throws InvalidMatrixException { return solve(MatrixUtils.createBigIdentityMatrix(getRowDimension())); } /** * Returns the determinant of this matrix. * * @return determinant * @throws InvalidMatrixException if matrix is not square */ public BigDecimal getDeterminant() throws InvalidMatrixException { if (!isSquare()) { throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); } if (isSingular()) { // note: this has side effect of attempting LU decomp if lu == null return ZERO; } else { BigDecimal det = (parity == 1) ? ONE : ONE.negate(); for (int i = 0; i < getRowDimension(); i++) { det = det.multiply(lu[i][i]); } return det; } } /** * Is this a square matrix? * @return true if the matrix is square (rowDimension = columnDimension) */ public boolean isSquare() { return getColumnDimension() == getRowDimension(); } /** * Is this a singular matrix? * @return true if the matrix is singular */ public boolean isSingular() { if (lu == null) { try { luDecompose(); return false; } catch (InvalidMatrixException ex) { return true; } } else { // LU decomp must have been successfully performed return false; // so the matrix is not singular } } /** * Returns the number of rows in the matrix. * * @return rowDimension */ public int getRowDimension() { return data.length; } /** * Returns the number of columns in the matrix. * * @return columnDimension */ public int getColumnDimension() { return data[0].length; } /** * Returns the * trace of the matrix (the sum of the elements on the main diagonal). * * @return trace * * @throws IllegalArgumentException if this matrix is not square. */ public BigDecimal getTrace() throws IllegalArgumentException { if (!isSquare()) { throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); } BigDecimal trace = data[0][0]; for (int i = 1; i < this.getRowDimension(); i++) { trace = trace.add(data[i][i]); } return trace; } /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ public BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException { if (v.length != getColumnDimension()) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, getColumnDimension() ); } final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); final BigDecimal[] out = new BigDecimal[nRows]; for (int row = 0; row < nRows; row++) { BigDecimal sum = ZERO; for (int i = 0; i < nCols; i++) { sum = sum.add(data[row][i].multiply(v[i])); } out[row] = sum; } return out; } /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ public BigDecimal[] operate(double[] v) throws IllegalArgumentException { final BigDecimal bd[] = new BigDecimal[v.length]; for (int i = 0; i < bd.length; i++) { bd[i] = new BigDecimal(v[i]); } return operate(bd); } /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ public BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException { final int nRows = this.getRowDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows ); } final int nCols = this.getColumnDimension(); final BigDecimal[] out = new BigDecimal[nCols]; for (int col = 0; col < nCols; col++) { BigDecimal sum = ZERO; for (int i = 0; i < nRows; i++) { sum = sum.add(data[i][col].multiply(v[i])); } out[col] = sum; } return out; } /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of * b. * * @param b array of constants forming RHS of linear systems to * to solve * @return solution array * @throws IllegalArgumentException if this.rowDimension != row dimension * @throws InvalidMatrixException if this matrix is not square or is singular */ public BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException { final int nRows = this.getRowDimension(); if (b.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, nRows); } final BigMatrix bMatrix = new BigMatrixImpl(b); final BigDecimal[][] solution = ((BigMatrixImpl) (solve(bMatrix))).getDataRef(); final BigDecimal[] out = new BigDecimal[nRows]; for (int row = 0; row < nRows; row++) { out[row] = solution[row][0]; } return out; } /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of * b. * * @param b array of constants forming RHS of linear systems to * to solve * @return solution array * @throws IllegalArgumentException if this.rowDimension != row dimension * @throws InvalidMatrixException if this matrix is not square or is singular */ public BigDecimal[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { final BigDecimal bd[] = new BigDecimal[b.length]; for (int i = 0; i < bd.length; i++) { bd[i] = new BigDecimal(b[i]); } return solve(bd); } /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of * b. * * @param b matrix of constant vectors forming RHS of linear systems to * to solve * @return matrix of solution vectors * @throws IllegalArgumentException if this.rowDimension != row dimension * @throws InvalidMatrixException if this matrix is not square or is singular */ public BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException { if (b.getRowDimension() != getRowDimension()) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), getRowDimension(), "n"); } if (!isSquare()) { throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); } if (this.isSingular()) { // side effect: compute LU decomp throw new SingularMatrixException(); } final int nCol = this.getColumnDimension(); final int nColB = b.getColumnDimension(); final int nRowB = b.getRowDimension(); // Apply permutations to b final BigDecimal[][] bp = new BigDecimal[nRowB][nColB]; for (int row = 0; row < nRowB; row++) { final BigDecimal[] bpRow = bp[row]; for (int col = 0; col < nColB; col++) { bpRow[col] = b.getEntry(permutation[row], col); } } // Solve LY = b for (int col = 0; col < nCol; col++) { for (int i = col + 1; i < nCol; i++) { final BigDecimal[] bpI = bp[i]; final BigDecimal[] luI = lu[i]; for (int j = 0; j < nColB; j++) { bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col])); } } } // Solve UX = Y for (int col = nCol - 1; col >= 0; col--) { final BigDecimal[] bpCol = bp[col]; final BigDecimal luDiag = lu[col][col]; for (int j = 0; j < nColB; j++) { bpCol[j] = bpCol[j].divide(luDiag, scale, roundingMode); } for (int i = 0; i < col; i++) { final BigDecimal[] bpI = bp[i]; final BigDecimal[] luI = lu[i]; for (int j = 0; j < nColB; j++) { bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col])); } } } return new BigMatrixImpl(bp, false); } /** * Computes a new * * LU decompostion for this matrix, storing the result for use by other methods. *

                    * Implementation Note:
                    * Uses * Crout's algortithm, with partial pivoting.

                    *

                    * Usage Note:
                    * This method should rarely be invoked directly. Its only use is * to force recomputation of the LU decomposition when changes have been * made to the underlying data using direct array references. Changes * made using setXxx methods will trigger recomputation when needed * automatically.

                    * * @throws InvalidMatrixException if the matrix is non-square or singular. */ public void luDecompose() throws InvalidMatrixException { final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); if (nRows != nCols) { throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); } lu = this.getData(); // Initialize permutation array and parity permutation = new int[nRows]; for (int row = 0; row < nRows; row++) { permutation[row] = row; } parity = 1; // Loop over columns for (int col = 0; col < nCols; col++) { BigDecimal sum = ZERO; // upper for (int row = 0; row < col; row++) { final BigDecimal[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < row; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; } // lower int max = col; // permutation row BigDecimal largest = ZERO; for (int row = col; row < nRows; row++) { final BigDecimal[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < col; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; // maintain best permutation choice if (sum.abs().compareTo(largest) == 1) { largest = sum.abs(); max = row; } } // Singularity check if (lu[max][col].abs().compareTo(TOO_SMALL) <= 0) { lu = null; throw new SingularMatrixException(); } // Pivot if necessary if (max != col) { BigDecimal tmp = ZERO; for (int i = 0; i < nCols; i++) { tmp = lu[max][i]; lu[max][i] = lu[col][i]; lu[col][i] = tmp; } int temp = permutation[max]; permutation[max] = permutation[col]; permutation[col] = temp; parity = -parity; } // Divide the lower elements by the "winning" diagonal elt. final BigDecimal luDiag = lu[col][col]; for (int row = col + 1; row < nRows; row++) { final BigDecimal[] luRow = lu[row]; luRow[col] = luRow[col].divide(luDiag, scale, roundingMode); } } } /** * Get a string representation for this matrix. * @return a string representation for this matrix */ @Override public String toString() { StringBuilder res = new StringBuilder(); res.append("BigMatrixImpl{"); if (data != null) { for (int i = 0; i < data.length; i++) { if (i > 0) { res.append(","); } res.append("{"); for (int j = 0; j < data[0].length; j++) { if (j > 0) { res.append(","); } res.append(data[i][j]); } res.append("}"); } } res.append("}"); return res.toString(); } /** * Returns true iff object is a * BigMatrixImpl instance with the same dimensions as this * and all corresponding matrix entries are equal. BigDecimal.equals * is used to compare corresponding entries. * * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(Object object) { if (object == this ) { return true; } if (object instanceof BigMatrixImpl == false) { return false; } final BigMatrix m = (BigMatrix) object; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { return false; } for (int row = 0; row < nRows; row++) { final BigDecimal[] dataRow = data[row]; for (int col = 0; col < nCols; col++) { if (!dataRow[col].equals(m.getEntry(row, col))) { return false; } } } return true; } /** * Computes a hashcode for the matrix. * * @return hashcode for matrix */ @Override public int hashCode() { int ret = 7; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); ret = ret * 31 + nRows; ret = ret * 31 + nCols; for (int row = 0; row < nRows; row++) { final BigDecimal[] dataRow = data[row]; for (int col = 0; col < nCols; col++) { ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * dataRow[col].hashCode(); } } return ret; } //------------------------ Protected methods /** * Returns the LU decomposition as a BigMatrix. * Returns a fresh copy of the cached LU matrix if this has been computed; * otherwise the composition is computed and cached for use by other methods. * Since a copy is returned in either case, changes to the returned matrix do not * affect the LU decomposition property. *

                    * The matrix returned is a compact representation of the LU decomposition. * Elements below the main diagonal correspond to entries of the "L" matrix; * elements on and above the main diagonal correspond to entries of the "U" * matrix.

                    *

                    * Example:

                         *
                         *     Returned matrix                L                  U
                         *         2  3  1                   1  0  0            2  3  1
                         *         5  4  6                   5  1  0            0  4  6
                         *         1  7  8                   1  7  1            0  0  8
                         * 
                    * * The L and U matrices satisfy the matrix equation LU = permuteRows(this),
                    * where permuteRows reorders the rows of the matrix to follow the order determined * by the permutation property.

                    * * @return LU decomposition matrix * @throws InvalidMatrixException if the matrix is non-square or singular. */ protected BigMatrix getLUMatrix() throws InvalidMatrixException { if (lu == null) { luDecompose(); } return new BigMatrixImpl(lu); } /** * Returns the permutation associated with the lu decomposition. * The entries of the array represent a permutation of the numbers 0, ... , nRows - 1. *

                    * Example: * permutation = [1, 2, 0] means current 2nd row is first, current third row is second * and current first row is last.

                    *

                    * Returns a fresh copy of the array.

                    * * @return the permutation */ protected int[] getPermutation() { final int[] out = new int[permutation.length]; System.arraycopy(permutation, 0, out, 0, permutation.length); return out; } //------------------------ Private methods /** * Returns a fresh copy of the underlying data array. * * @return a copy of the underlying data array. */ private BigDecimal[][] copyOut() { final int nRows = this.getRowDimension(); final BigDecimal[][] out = new BigDecimal[nRows][this.getColumnDimension()]; // can't copy 2-d array in one shot, otherwise get row references for (int i = 0; i < nRows; i++) { System.arraycopy(data[i], 0, out[i], 0, data[i].length); } return out; } /** * Replaces data with a fresh copy of the input array. *

                    * Verifies that the input array is rectangular and non-empty.

                    * * @param in data to copy in * @throws IllegalArgumentException if input array is emtpy or not * rectangular * @throws NullPointerException if input array is null */ private void copyIn(BigDecimal[][] in) { setSubMatrix(in,0,0); } /** * Replaces data with a fresh copy of the input array. * * @param in data to copy in */ private void copyIn(double[][] in) { final int nRows = in.length; final int nCols = in[0].length; data = new BigDecimal[nRows][nCols]; for (int i = 0; i < nRows; i++) { final BigDecimal[] dataI = data[i]; final double[] inI = in[i]; for (int j = 0; j < nCols; j++) { dataI[j] = new BigDecimal(inI[j]); } } lu = null; } /** * Replaces data with BigDecimals represented by the strings in the input * array. * * @param in data to copy in */ private void copyIn(String[][] in) { final int nRows = in.length; final int nCols = in[0].length; data = new BigDecimal[nRows][nCols]; for (int i = 0; i < nRows; i++) { final BigDecimal[] dataI = data[i]; final String[] inI = in[i]; for (int j = 0; j < nCols; j++) { dataI[j] = new BigDecimal(inI[j]); } } lu = null; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java100644 1750 1750 71564 11532241245 27723 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * This class implements the {@link FieldVector} interface with a {@link FieldElement} array. * @param the type of the field elements * @version $Revision: 1003997 $ $Date: 2010-10-03 18:45:55 +0200 (dim. 03 oct. 2010) $ * @since 2.0 */ public class ArrayFieldVector> implements FieldVector, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 7648186910365927050L; /** Entries of the vector. */ protected T[] data; /** Field to which the elements belong. */ private final Field field; /** * Build a 0-length vector. *

                    Zero-length vectors may be used to initialized construction of vectors * by data gathering. We start with zero-length and use either the {@link * #ArrayFieldVector(ArrayFieldVector, ArrayFieldVector)} constructor * or one of the append methods ({@link #append(FieldElement[])}, * {@link #add(FieldVector)}, {@link #append(ArrayFieldVector)}) to gather data * into this vector.

                    * @param field field to which the elements belong */ public ArrayFieldVector(final Field field) { this(field, 0); } /** * Construct a (size)-length vector of zeros. * @param field field to which the elements belong * @param size size of the vector */ public ArrayFieldVector(Field field, int size) { this.field = field; data = buildArray(size); Arrays.fill(data, field.getZero()); } /** * Construct an (size)-length vector with preset values. * @param size size of the vector * @param preset fill the vector with this scalar value */ public ArrayFieldVector(int size, T preset) { this(preset.getField(), size); Arrays.fill(data, preset); } /** * Construct a vector from an array, copying the input array. *

                    * This constructor needs a non-empty {@code d} array to retrieve * the field from its first element. This implies it cannot build * 0 length vectors. To build vectors from any size, one should * use the {@link #ArrayFieldVector(Field, FieldElement[])} constructor. *

                    * @param d array of Ts. * @throws IllegalArgumentException if d is empty * @see #ArrayFieldVector(Field, FieldElement[]) */ public ArrayFieldVector(T[] d) throws IllegalArgumentException { try { field = d[0].getField(); data = d.clone(); } catch (ArrayIndexOutOfBoundsException e) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } } /** * Construct a vector from an array, copying the input array. * @param field field to which the elements belong * @param d array of Ts. * @see #ArrayFieldVector(FieldElement[]) */ public ArrayFieldVector(Field field, T[] d) { this.field = field; data = d.clone(); } /** * Create a new ArrayFieldVector using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * ArrayFieldVector and not used directly, the copyArray may be * set to false *

                    * This constructor needs a non-empty {@code d} array to retrieve * the field from its first element. This implies it cannot build * 0 length vectors. To build vectors from any size, one should * use the {@link #ArrayFieldVector(Field, FieldElement[], boolean)} constructor. *

                    * @param d data for new vector * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @throws IllegalArgumentException if d is empty * @throws NullPointerException if d is null * @see #ArrayFieldVector(FieldElement[]) * @see #ArrayFieldVector(Field, FieldElement[], boolean) */ public ArrayFieldVector(T[] d, boolean copyArray) throws NullPointerException, IllegalArgumentException { if (d.length == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } field = d[0].getField(); data = copyArray ? d.clone() : d; } /** * Create a new ArrayFieldVector using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * ArrayFieldVector and not used directly, the copyArray may be * set to false * @param field field to which the elements belong * @param d data for new vector * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @see #ArrayFieldVector(FieldElement[], boolean) */ public ArrayFieldVector(Field field, T[] d, boolean copyArray) { this.field = field; data = copyArray ? d.clone() : d; } /** * Construct a vector from part of a array. * @param d array of Ts. * @param pos position of first entry * @param size number of entries to copy */ public ArrayFieldVector(T[] d, int pos, int size) { if (d.length < pos + size) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY, pos, size, d.length); } field = d[0].getField(); data = buildArray(size); System.arraycopy(d, pos, data, 0, size); } /** * Construct a vector from another vector, using a deep copy. * @param v vector to copy */ public ArrayFieldVector(FieldVector v) { field = v.getField(); data = buildArray(v.getDimension()); for (int i = 0; i < data.length; ++i) { data[i] = v.getEntry(i); } } /** * Construct a vector from another vector, using a deep copy. * @param v vector to copy */ public ArrayFieldVector(ArrayFieldVector v) { field = v.getField(); data = v.data.clone(); } /** * Construct a vector from another vector. * @param v vector to copy * @param deep if true perform a deep copy otherwise perform a shallow copy */ public ArrayFieldVector(ArrayFieldVector v, boolean deep) { field = v.getField(); data = deep ? v.data.clone() : v.data; } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayFieldVector(ArrayFieldVector v1, ArrayFieldVector v2) { field = v1.getField(); data = buildArray(v1.data.length + v2.data.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length); System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayFieldVector(ArrayFieldVector v1, T[] v2) { field = v1.getField(); data = buildArray(v1.data.length + v2.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length); System.arraycopy(v2, 0, data, v1.data.length, v2.length); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayFieldVector(T[] v1, ArrayFieldVector v2) { field = v2.getField(); data = buildArray(v1.length + v2.data.length); System.arraycopy(v1, 0, data, 0, v1.length); System.arraycopy(v2.data, 0, data, v1.length, v2.data.length); } /** * Construct a vector by appending one vector to another vector. *

                    * This constructor needs at least one non-empty array to retrieve * the field from its first element. This implies it cannot build * 0 length vectors. To build vectors from any size, one should * use the {@link #ArrayFieldVector(Field, FieldElement[], FieldElement[])} constructor. *

                    * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) * @exception IllegalArgumentException if both vectors are empty * @see #ArrayFieldVector(Field, FieldElement[], FieldElement[]) */ public ArrayFieldVector(T[] v1, T[] v2) { try { data = buildArray(v1.length + v2.length); System.arraycopy(v1, 0, data, 0, v1.length); System.arraycopy(v2, 0, data, v1.length, v2.length); field = data[0].getField(); } catch (ArrayIndexOutOfBoundsException e) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } } /** * Construct a vector by appending one vector to another vector. * @param field field to which the elements belong * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) * @see #ArrayFieldVector(FieldElement[], FieldElement[]) */ public ArrayFieldVector(Field field, T[] v1, T[] v2) { if (v1.length + v2.length == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } data = buildArray(v1.length + v2.length); System.arraycopy(v1, 0, data, 0, v1.length); System.arraycopy(v2, 0, data, v1.length, v2.length); this.field = data[0].getField(); } /** Build an array of elements. * @param length size of the array to build * @return a new array */ @SuppressWarnings("unchecked") // field is of type T private T[] buildArray(final int length) { return (T[]) Array.newInstance(field.getZero().getClass(), length); } /** {@inheritDoc} */ public Field getField() { return field; } /** {@inheritDoc} */ public FieldVector copy() { return new ArrayFieldVector(this, true); } /** {@inheritDoc} */ public FieldVector add(FieldVector v) throws IllegalArgumentException { try { return add((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].add(v.getEntry(i)); } return new ArrayFieldVector(out); } } /** {@inheritDoc} */ public FieldVector add(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].add(v[i]); } return new ArrayFieldVector(out); } /** * Compute the sum of this and v. * @param v vector to be added * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayFieldVector add(ArrayFieldVector v) throws IllegalArgumentException { return (ArrayFieldVector) add(v.data); } /** {@inheritDoc} */ public FieldVector subtract(FieldVector v) throws IllegalArgumentException { try { return subtract((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].subtract(v.getEntry(i)); } return new ArrayFieldVector(out); } } /** {@inheritDoc} */ public FieldVector subtract(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].subtract(v[i]); } return new ArrayFieldVector(out); } /** * Compute this minus v. * @param v vector to be subtracted * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayFieldVector subtract(ArrayFieldVector v) throws IllegalArgumentException { return (ArrayFieldVector) subtract(v.data); } /** {@inheritDoc} */ public FieldVector mapAdd(T d) { T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].add(d); } return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector mapAddToSelf(T d) { for (int i = 0; i < data.length; i++) { data[i] = data[i].add(d); } return this; } /** {@inheritDoc} */ public FieldVector mapSubtract(T d) { T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].subtract(d); } return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector mapSubtractToSelf(T d) { for (int i = 0; i < data.length; i++) { data[i] = data[i].subtract(d); } return this; } /** {@inheritDoc} */ public FieldVector mapMultiply(T d) { T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].multiply(d); } return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector mapMultiplyToSelf(T d) { for (int i = 0; i < data.length; i++) { data[i] = data[i].multiply(d); } return this; } /** {@inheritDoc} */ public FieldVector mapDivide(T d) { T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].divide(d); } return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector mapDivideToSelf(T d) { for (int i = 0; i < data.length; i++) { data[i] = data[i].divide(d); } return this; } /** {@inheritDoc} */ public FieldVector mapInv() { T[] out = buildArray(data.length); final T one = field.getOne(); for (int i = 0; i < data.length; i++) { out[i] = one.divide(data[i]); } return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector mapInvToSelf() { final T one = field.getOne(); for (int i = 0; i < data.length; i++) { data[i] = one.divide(data[i]); } return this; } /** {@inheritDoc} */ public FieldVector ebeMultiply(FieldVector v) throws IllegalArgumentException { try { return ebeMultiply((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].multiply(v.getEntry(i)); } return new ArrayFieldVector(out); } } /** {@inheritDoc} */ public FieldVector ebeMultiply(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].multiply(v[i]); } return new ArrayFieldVector(out); } /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @exception IllegalArgumentException if v is not the same size as this */ public ArrayFieldVector ebeMultiply(ArrayFieldVector v) throws IllegalArgumentException { return (ArrayFieldVector) ebeMultiply(v.data); } /** {@inheritDoc} */ public FieldVector ebeDivide(FieldVector v) throws IllegalArgumentException { try { return ebeDivide((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].divide(v.getEntry(i)); } return new ArrayFieldVector(out); } } /** {@inheritDoc} */ public FieldVector ebeDivide(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T[] out = buildArray(data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].divide(v[i]); } return new ArrayFieldVector(out); } /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ public ArrayFieldVector ebeDivide(ArrayFieldVector v) throws IllegalArgumentException { return (ArrayFieldVector) ebeDivide(v.data); } /** {@inheritDoc} */ public T[] getData() { return data.clone(); } /** * Returns a reference to the underlying data array. *

                    Does not make a fresh copy of the underlying data.

                    * @return array of entries */ public T[] getDataRef() { return data; } /** {@inheritDoc} */ public T dotProduct(FieldVector v) throws IllegalArgumentException { try { return dotProduct((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); T dot = field.getZero(); for (int i = 0; i < data.length; i++) { dot = dot.add(data[i].multiply(v.getEntry(i))); } return dot; } } /** {@inheritDoc} */ public T dotProduct(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T dot = field.getZero(); for (int i = 0; i < data.length; i++) { dot = dot.add(data[i].multiply(v[i])); } return dot; } /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ public T dotProduct(ArrayFieldVector v) throws IllegalArgumentException { return dotProduct(v.data); } /** {@inheritDoc} */ public FieldVector projection(FieldVector v) { return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); } /** {@inheritDoc} */ public FieldVector projection(T[] v) { return projection(new ArrayFieldVector(v, false)); } /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayFieldVector projection(ArrayFieldVector v) { return (ArrayFieldVector) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); } /** {@inheritDoc} */ public FieldMatrix outerProduct(FieldVector v) throws IllegalArgumentException { try { return outerProduct((ArrayFieldVector) v); } catch (ClassCastException cce) { checkVectorDimensions(v); final int m = data.length; final FieldMatrix out = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < data.length; i++) { for (int j = 0; j < data.length; j++) { out.setEntry(i, j, data[i].multiply(v.getEntry(j))); } } return out; } } /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ public FieldMatrix outerProduct(ArrayFieldVector v) throws IllegalArgumentException { return outerProduct(v.data); } /** {@inheritDoc} */ public FieldMatrix outerProduct(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); final int m = data.length; final FieldMatrix out = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < data.length; i++) { for (int j = 0; j < data.length; j++) { out.setEntry(i, j, data[i].multiply(v[j])); } } return out; } /** {@inheritDoc} */ public T getEntry(int index) throws MatrixIndexException { return data[index]; } /** {@inheritDoc} */ public int getDimension() { return data.length; } /** {@inheritDoc} */ public FieldVector append(FieldVector v) { try { return append((ArrayFieldVector) v); } catch (ClassCastException cce) { return new ArrayFieldVector(this,new ArrayFieldVector(v)); } } /** * Construct a vector by appending a vector to this vector. * @param v vector to append to this one. * @return a new vector */ public ArrayFieldVector append(ArrayFieldVector v) { return new ArrayFieldVector(this, v); } /** {@inheritDoc} */ public FieldVector append(T in) { final T[] out = buildArray(data.length + 1); System.arraycopy(data, 0, out, 0, data.length); out[data.length] = in; return new ArrayFieldVector(out); } /** {@inheritDoc} */ public FieldVector append(T[] in) { return new ArrayFieldVector(this, in); } /** {@inheritDoc} */ public FieldVector getSubVector(int index, int n) { ArrayFieldVector out = new ArrayFieldVector(field, n); try { System.arraycopy(data, index, out.data, 0, n); } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + n - 1); } return out; } /** {@inheritDoc} */ public void setEntry(int index, T value) { try { data[index] = value; } catch (IndexOutOfBoundsException e) { checkIndex(index); } } /** {@inheritDoc} */ public void setSubVector(int index, FieldVector v) { try { try { set(index, (ArrayFieldVector) v); } catch (ClassCastException cce) { for (int i = index; i < index + v.getDimension(); ++i) { data[i] = v.getEntry(i-index); } } } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + v.getDimension() - 1); } } /** {@inheritDoc} */ public void setSubVector(int index, T[] v) { try { System.arraycopy(v, 0, data, index, v.length); } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + v.length - 1); } } /** * Set a set of consecutive elements. * * @param index index of first element to be set. * @param v vector containing the values to set. * @exception MatrixIndexException if the index is * inconsistent with vector size */ public void set(int index, ArrayFieldVector v) throws MatrixIndexException { setSubVector(index, v.data); } /** {@inheritDoc} */ public void set(T value) { Arrays.fill(data, value); } /** {@inheritDoc} */ public T[] toArray(){ return data.clone(); } /** * Check if instance and specified vectors have the same dimension. * @param v vector to compare instance with * @exception IllegalArgumentException if the vectors do not * have the same dimension */ protected void checkVectorDimensions(FieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); } /** * Check if instance dimension is equal to some expected value. * * @param n expected dimension. * @exception IllegalArgumentException if the dimension is * inconsistent with vector size */ protected void checkVectorDimensions(int n) throws IllegalArgumentException { if (data.length != n) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, data.length, n); } } /** * Test for the equality of two real vectors. *

                    * If all coordinates of two real vectors are exactly the same, and none are * Double.NaN, the two real vectors are considered to be equal. *

                    *

                    * NaN coordinates are considered to affect globally the vector * and be equals to each other - i.e, if either (or all) coordinates of the * real vector are equal to Double.NaN, the real vector is equal to * a vector with all Double.NaN coordinates. *

                    * * @param other Object to test for equality to this * @return true if two 3D vector objects are equal, false if * object is null, not an instance of Vector3D, or * not equal to this Vector3D instance * */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other == null) { return false; } try { @SuppressWarnings("unchecked") // May fail, but we ignore ClassCastException FieldVector rhs = (FieldVector) other; if (data.length != rhs.getDimension()) { return false; } for (int i = 0; i < data.length; ++i) { if (!data[i].equals(rhs.getEntry(i))) { return false; } } return true; } catch (ClassCastException ex) { // ignore exception return false; } } /** * Get a hashCode for the real vector. *

                    All NaN values have the same hash code.

                    * @return a hash code value for this object */ @Override public int hashCode() { int h = 3542; for (final T a : data) { h = h ^ a.hashCode(); } return h; } /** * Check if an index is valid. * @param index index to check * @exception MatrixIndexException if index is not valid */ private void checkIndex(final int index) throws MatrixIndexException { if (index < 0 || index >= getDimension()) { throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE, index, 0, getDimension() - 1); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealVector.java100644 1750 1750 100052 11532241245 26565 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Iterator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface defining a real-valued vector with basic algebraic operations. *

                    * vector element indexing is 0-based -- e.g., getEntry(0) * returns the first element of the vector. *

                    *

                    * The various mapXxx and mapXxxToSelf methods operate * on vectors element-wise, i.e. they perform the same operation (adding a scalar, * applying a function ...) on each element in turn. The mapXxx * versions create a new vector to hold the result and do not change the instance. * The mapXxxToSelf versions use the instance itself to store the * results, so the instance is changed by these methods. In both cases, the result * vector is returned by the methods, this allows to use the fluent API * style, like this: *

                    *
                     *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
                     * 
                    *

                    * Remark on the deprecated {@code mapXxx} and {@code mapXxxToSelf} methods: In * Commons-Math v3.0, the same functionality will be achieved by directly using the * {@link #map(UnivariateRealFunction)} and {@link #mapToSelf(UnivariateRealFunction)} * together with new function objects (not available in v2.2). *

                    * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public interface RealVector { /** * Acts as if it is implemented as: *
                         *  Entry e = null;
                         *  for(Iterator it = iterator(); it.hasNext(); e = it.next()) {
                         *      e.setValue(function.value(e.getValue()));
                         *  }
                         * 
                    * * @param function Function to apply to each entry. * @return this vector. * @throws FunctionEvaluationException if the function throws it. */ RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException; /** * Acts as if implemented as: *
                         *  return copy().map(function);
                         * 
                    * * @param function Function to apply to each entry. * @return a new vector. * @throws FunctionEvaluationException if the function throws it. */ RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException; /** Class representing a modifiable entry in the vector. */ public abstract class Entry { /** Index of the entry. */ private int index; /** * Get the value of the entry. * * @return the value of the entry. */ public abstract double getValue(); /** * Set the value of the entry. * * @param value New value for the entry. */ public abstract void setValue(double value); /** * Get the index of the entry. * * @return the index of the entry. */ public int getIndex() { return index; } /** * Set the index of the entry. * * @param index New index for the entry. */ public void setIndex(int index) { this.index = index; } } /** * Generic dense iterator. * It iterates in increasing order of the vector index. * * @return a dense iterator */ Iterator iterator(); /** * Specialized implementations may choose to not iterate over all * dimensions, either because those values are unset, or are equal * to defaultValue(), or are small enough to be ignored for the * purposes of iteration. * No guarantees are made about order of iteration. * In dense implementations, this method will often delegate to * {@link #iterator()}. * * @return a sparse iterator */ Iterator sparseIterator(); /** * Returns a (deep) copy of this vector. * * @return a vector copy. */ RealVector copy(); /** * Compute the sum of this vector and {@code v}. * * @param v Vector to be added. * @return {@code this} + {@code v}. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector add(RealVector v); /** * Compute the sum of this vector and {@code v}. * * @param v Vector to be added. * @return {@code this} + {@code v}. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector add(double[] v); /** * Subtract {@code v} from this vector. * * @param v Vector to be subtracted. * @return {@code this} - {@code v}. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector subtract(RealVector v); /** * Subtract {@code v} from this vector. * * @param v Vector to be subtracted. * @return {@code this} - {@code v}. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector subtract(double[] v); /** * Add a value to each entry. * * @param d Value to be added to each entry. * @return {@code this} + {@code d}. */ RealVector mapAdd(double d); /** * Add a value to each entry. * The instance is changed in-place. * * @param d Value to be added to each entry. * @return {@code this}. */ RealVector mapAddToSelf(double d); /** * Subtract a value from each entry. * * @param d Value to be subtracted. * @return {@code this} - {@code d}. */ RealVector mapSubtract(double d); /** * Subtract a value from each entry. * The instance is changed in-place. * * @param d Value to be subtracted. * @return {@code this}. */ RealVector mapSubtractToSelf(double d); /** * Multiply each entry. * * @param d Multiplication factor. * @return {@code this} * {@code d}. */ RealVector mapMultiply(double d); /** * Multiply each entry. * The instance is changed in-place. * * @param d Multiplication factor. * @return {@code this}. */ RealVector mapMultiplyToSelf(double d); /** * Divide each entry. * * @param d Value to divide by. * @return {@code this} / {@code d}. */ RealVector mapDivide(double d); /** * Divide each entry. * The instance is changed in-place. * * @param d Value to divide by. * @return {@code this}. */ RealVector mapDivideToSelf(double d); /** * Map a power operation to each entry. * * @param d Operator value. * @return a mapped copy of the vector. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapPow(double d); /** * Map a power operation to each entry. * The instance is changed in-place. * * @param d Operator value. * @return the mapped vector. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapPowToSelf(double d); /** * Map the {@link Math#exp(double)} function to each entry. * * @return a mapped copy of the vector. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapExp(); /** * Map {@link Math#exp(double)} operation to each entry. * The instance is changed in-place. * * @return the mapped vector. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapExpToSelf(); /** * Map the {@link Math#expm1(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapExpm1(); /** * Map the {@link Math#expm1(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapExpm1ToSelf(); /** * Map the {@link Math#log(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLog(); /** * Map the {@link Math#log(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLogToSelf(); /** * Map the {@link Math#log10(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLog10(); /** * Map the {@link Math#log10(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLog10ToSelf(); /** * Map the {@link Math#log1p(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLog1p(); /** * Map the {@link Math#log1p(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapLog1pToSelf(); /** * Map the {@link Math#cosh(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCosh(); /** * Map the {@link Math#cosh(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCoshToSelf(); /** * Map the {@link Math#sinh(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSinh(); /** * Map the {@link Math#sinh(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSinhToSelf(); /** * Map the {@link Math#tanh(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapTanh(); /** * Map the {@link Math#tanh(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapTanhToSelf(); /** * Map the {@link Math#cos(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCos(); /** * Map the {@link Math#cos(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCosToSelf(); /** * Map the {@link Math#sin(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSin(); /** * Map the {@link Math#sin(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSinToSelf(); /** * Map the {@link Math#tan(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapTan(); /** * Map the {@link Math#tan(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapTanToSelf(); /** * Map the {@link Math#acos(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAcos(); /** * Map the {@link Math#acos(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAcosToSelf(); /** * Map the {@link Math#asin(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAsin(); /** * Map the {@link Math#asin(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAsinToSelf(); /** * Map the {@link Math#atan(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAtan(); /** * Map the {@link Math#atan(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAtanToSelf(); /** * Map the 1/x function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapInv(); /** * Map the 1/x function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapInvToSelf(); /** * Map the {@link Math#abs(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAbs(); /** * Map the {@link Math#abs(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapAbsToSelf(); /** * Map the {@link Math#sqrt(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSqrt(); /** * Map the {@link Math#sqrt(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSqrtToSelf(); /** * Map the {@link Math#cbrt(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCbrt(); /** * Map the {@link Math#cbrt(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCbrtToSelf(); /** * Map the {@link Math#ceil(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCeil(); /** * Map the {@link Math#ceil(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapCeilToSelf(); /** * Map the {@link Math#floor(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapFloor(); /** * Map the {@link Math#floor(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapFloorToSelf(); /** * Map the {@link Math#rint(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapRint(); /** * Map the {@link Math#rint(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapRintToSelf(); /** * Map the {@link Math#signum(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSignum(); /** * Map the {@link Math#signum(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapSignumToSelf(); /** * Map the {@link Math#ulp(double)} function to each entry. * @return a vector containing the result of applying the function to each entry * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapUlp(); /** * Map the {@link Math#ulp(double)} function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated RealVector mapUlpToSelf(); /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector ebeMultiply(RealVector v); /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector ebeMultiply(double[] v); /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector ebeDivide(RealVector v); /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector ebeDivide(double[] v); /** * Returns vector entries as a double array. * @return double array of entries */ double[] getData(); /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ double dotProduct(RealVector v); /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ double dotProduct(double[] v); /** * Returns the L2 norm of the vector. *

                    The L2 norm is the root of the sum of * the squared elements.

                    * @return norm * @see #getL1Norm() * @see #getLInfNorm() * @see #getDistance(RealVector) */ double getNorm(); /** * Returns the L1 norm of the vector. *

                    The L1 norm is the sum of the absolute * values of elements.

                    * @return norm * @see #getNorm() * @see #getLInfNorm() * @see #getL1Distance(RealVector) */ double getL1Norm(); /** * Returns the L norm of the vector. *

                    The L norm is the max of the absolute * values of elements.

                    * @return norm * @see #getNorm() * @see #getL1Norm() * @see #getLInfDistance(RealVector) */ double getLInfNorm(); /** * Distance between two vectors. *

                    This method computes the distance consistent with the * L2 norm, i.e. the square root of the sum of * elements differences, or euclidian distance.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getL1Distance(RealVector) * @see #getLInfDistance(RealVector) * @see #getNorm() */ double getDistance(RealVector v); /** * Distance between two vectors. *

                    This method computes the distance consistent with the * L2 norm, i.e. the square root of the sum of * elements differences, or euclidian distance.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getL1Distance(double[]) * @see #getLInfDistance(double[]) * @see #getNorm() */ double getDistance(double[] v); /** * Distance between two vectors. *

                    This method computes the distance consistent with * L1 norm, i.e. the sum of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getDistance(RealVector) * @see #getLInfDistance(RealVector) * @see #getL1Norm() */ double getL1Distance(RealVector v); /** * Distance between two vectors. *

                    This method computes the distance consistent with * L1 norm, i.e. the sum of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getDistance(double[]) * @see #getLInfDistance(double[]) * @see #getL1Norm() */ double getL1Distance(double[] v); /** * Distance between two vectors. *

                    This method computes the distance consistent with * L norm, i.e. the max of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getDistance(RealVector) * @see #getL1Distance(RealVector) * @see #getLInfNorm() */ double getLInfDistance(RealVector v); /** * Distance between two vectors. *

                    This method computes the distance consistent with * L norm, i.e. the max of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. * @see #getDistance(double[]) * @see #getL1Distance(double[]) * @see #getLInfNorm() */ double getLInfDistance(double[] v); /** Creates a unit vector pointing in the direction of this vector. *

                    The instance is not changed by this method.

                    * @return a unit vector pointing in direction of this vector * @exception ArithmeticException if the norm is null */ RealVector unitVector(); /** Converts this vector into a unit vector. *

                    The instance itself is changed by this method.

                    * @throws ArithmeticException * if the norm is zero. */ void unitize(); /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector projection(RealVector v); /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealVector projection(double[] v); /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealMatrix outerProduct(RealVector v); /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @throws org.apache.commons.math.exception.DimensionMismatchException * if {@code v} is not the same size as this vector. */ RealMatrix outerProduct(double[] v); /** * Returns the entry in the specified index. * * @param index Index location of entry to be fetched. * @return the vector entry at {@code index}. * @throws org.apache.commons.math.exception.OutOfRangeException * if the index is not valid. * @see #setEntry(int, double) */ double getEntry(int index); /** * Set a single element. * @param index element index. * @param value new value for the element. * @throws org.apache.commons.math.exception.OutOfRangeException * if the index is not valid. * @see #getEntry(int) */ void setEntry(int index, double value); /** * Returns the size of the vector. * @return size */ int getDimension(); /** * Construct a vector by appending a vector to this vector. * @param v vector to append to this one. * @return a new vector */ RealVector append(RealVector v); /** * Construct a vector by appending a double to this vector. * @param d double to append. * @return a new vector */ RealVector append(double d); /** * Construct a vector by appending a double array to this vector. * @param a double array to append. * @return a new vector */ RealVector append(double[] a); /** * Get a subvector from consecutive elements. * @param index index of first element. * @param n number of elements to be retrieved. * @return a vector containing n elements. * @throws org.apache.commons.math.exception.OutOfRangeException * if the index is not valid. */ RealVector getSubVector(int index, int n); /** * Set a set of consecutive elements. * @param index index of first element to be set. * @param v vector containing the values to set. * @throws org.apache.commons.math.exception.OutOfRangeException * if the index is not valid. * @see #setSubVector(int, double[]) */ void setSubVector(int index, RealVector v); /** * Set a set of consecutive elements. * @param index index of first element to be set. * @param v vector containing the values to set. * @throws org.apache.commons.math.exception.OutOfRangeException * if the index is not valid. * @see #setSubVector(int, RealVector) */ void setSubVector(int index, double[] v); /** * Set all elements to a single value. * @param value single value to set for all elements */ void set(double value); /** * Convert the vector to a double array. *

                    The array is independent from vector data, it's elements * are copied.

                    * @return array containing a copy of vector elements */ double[] toArray(); /** * Check whether any coordinate of this vector is {@code NaN}. * @return {@code true} if any coordinate of this vector is {@code NaN}, * {@code false} otherwise. */ boolean isNaN(); /** * Check whether any coordinate of this vector is infinite and none are {@code NaN}. * * @return {@code true} if any coordinate of this vector is infinite and * none are {@code NaN}, {@code false} otherwise. */ boolean isInfinite(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealMatrixChangingVisitor.java100644 1750 1750 4425 11532241245 31555 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining a visitor for matrix entries. * * @see DefaultRealMatrixChangingVisitor * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface RealMatrixChangingVisitor { /** * Start visiting a matrix. *

                    This method is called once before any entry of the matrix is visited.

                    * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) */ void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn); /** * Visit one matrix entry. * @param row row index of the entry * @param column column index of the entry * @param value current value of the entry * @return the new value to be set for the entry * @throws MatrixVisitorException if something wrong occurs */ double visit(int row, int column, double value) throws MatrixVisitorException; /** * End visiting a matrix. *

                    This method is called once after all entries of the matrix have been visited.

                    * @return the value that the walkInXxxOrder must return */ double end(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/AbstractFieldMatrix.java100644 1750 1750 117172 11532241245 30426 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.lang.reflect.Array; import java.util.Arrays; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Basic implementation of {@link FieldMatrix} methods regardless of the underlying storage. *

                    All the methods implemented here use {@link #getEntry(int, int)} to access * matrix elements. Derived class can provide faster implementations.

                    * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public abstract class AbstractFieldMatrix> implements FieldMatrix { /** Field to which the elements belong. */ private final Field field; /** * Constructor for use with Serializable */ protected AbstractFieldMatrix() { field = null; } /** * Creates a matrix with no data * @param field field to which the elements belong */ protected AbstractFieldMatrix(final Field field) { this.field = field; } /** * Create a new FieldMatrix with the supplied row and column dimensions. * * @param field field to which the elements belong * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not positive */ protected AbstractFieldMatrix(final Field field, final int rowDimension, final int columnDimension) throws IllegalArgumentException { if (rowDimension < 1 ) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1); } if (columnDimension < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1); } this.field = field; } /** * Get the elements type from an array. * @param the type of the field elements * @param d data array * @return field to which array elements belong * @exception IllegalArgumentException if array is empty */ protected static > Field extractField(final T[][] d) throws IllegalArgumentException { if (d.length == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } if (d[0].length == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } return d[0][0].getField(); } /** * Get the elements type from an array. * @param the type of the field elements * @param d data array * @return field to which array elements belong * @exception IllegalArgumentException if array is empty */ protected static > Field extractField(final T[] d) throws IllegalArgumentException { if (d.length == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } return d[0].getField(); } /** Build an array of elements. *

                    * Complete arrays are filled with field.getZero() *

                    * @param the type of the field elements * @param field field to which array elements belong * @param rows number of rows * @param columns number of columns (may be negative to build partial * arrays in the same way new Field[rows][] works) * @return a new array */ @SuppressWarnings("unchecked") protected static > T[][] buildArray(final Field field, final int rows, final int columns) { if (columns < 0) { T[] dummyRow = (T[]) Array.newInstance(field.getZero().getClass(), 0); return (T[][]) Array.newInstance(dummyRow.getClass(), rows); } T[][] array = (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { rows, columns }); for (int i = 0; i < array.length; ++i) { Arrays.fill(array[i], field.getZero()); } return array; } /** Build an array of elements. *

                    * Arrays are filled with field.getZero() *

                    * @param the type of the field elements * @param field field to which array elements belong * @param length of the array * @return a new array */ protected static > T[] buildArray(final Field field, final int length) { @SuppressWarnings("unchecked") // OK because field must be correct class T[] array = (T[]) Array.newInstance(field.getZero().getClass(), length); Arrays.fill(array, field.getZero()); return array; } /** {@inheritDoc} */ public Field getField() { return field; } /** {@inheritDoc} */ public abstract FieldMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException; /** {@inheritDoc} */ public abstract FieldMatrix copy(); /** {@inheritDoc} */ public FieldMatrix add(FieldMatrix m) throws IllegalArgumentException { // safety check checkAdditionCompatible(m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final FieldMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col))); } } return out; } /** {@inheritDoc} */ public FieldMatrix subtract(final FieldMatrix m) throws IllegalArgumentException { // safety check checkSubtractionCompatible(m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final FieldMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col))); } } return out; } /** {@inheritDoc} */ public FieldMatrix scalarAdd(final T d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final FieldMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col).add(d)); } } return out; } /** {@inheritDoc} */ public FieldMatrix scalarMultiply(final T d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final FieldMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col).multiply(d)); } } return out; } /** {@inheritDoc} */ public FieldMatrix multiply(final FieldMatrix m) throws IllegalArgumentException { // safety check checkMultiplicationCompatible(m); final int nRows = getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = getColumnDimension(); final FieldMatrix out = createMatrix(nRows, nCols); for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { T sum = field.getZero(); for (int i = 0; i < nSum; ++i) { sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col))); } out.setEntry(row, col, sum); } } return out; } /** {@inheritDoc} */ public FieldMatrix preMultiply(final FieldMatrix m) throws IllegalArgumentException { return m.multiply(this); } /** {@inheritDoc} */ public T[][] getData() { final T[][] data = buildArray(field, getRowDimension(), getColumnDimension()); for (int i = 0; i < data.length; ++i) { final T[] dataI = data[i]; for (int j = 0; j < dataI.length; ++j) { dataI[j] = getEntry(i, j); } } return data; } /** {@inheritDoc} */ public FieldMatrix getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); final FieldMatrix subMatrix = createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); for (int i = startRow; i <= endRow; ++i) { for (int j = startColumn; j <= endColumn; ++j) { subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j)); } } return subMatrix; } /** {@inheritDoc} */ public FieldMatrix getSubMatrix(final int[] selectedRows, final int[] selectedColumns) throws MatrixIndexException { // safety checks checkSubMatrixIndex(selectedRows, selectedColumns); // copy entries final FieldMatrix subMatrix = createMatrix(selectedRows.length, selectedColumns.length); subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor(field.getZero()) { /** {@inheritDoc} */ @Override public T visit(final int row, final int column, final T value) { return getEntry(selectedRows[row], selectedColumns[column]); } }); return subMatrix; } /** {@inheritDoc} */ public void copySubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn, final T[][] destination) throws MatrixIndexException, IllegalArgumentException { // safety checks checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); final int rowsCount = endRow + 1 - startRow; final int columnsCount = endColumn + 1 - startColumn; if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, destination.length, destination[0].length, rowsCount, columnsCount); } // copy entries walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor(field.getZero()) { /** Initial row index. */ private int startRow; /** Initial column index. */ private int startColumn; /** {@inheritDoc} */ @Override public void start(final int rows, final int columns, final int startRow, final int endRow, final int startColumn, final int endColumn) { this.startRow = startRow; this.startColumn = startColumn; } /** {@inheritDoc} */ @Override public void visit(final int row, final int column, final T value) { destination[row - startRow][column - startColumn] = value; } }, startRow, endRow, startColumn, endColumn); } /** {@inheritDoc} */ public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination) throws MatrixIndexException, IllegalArgumentException { // safety checks checkSubMatrixIndex(selectedRows, selectedColumns); if ((destination.length < selectedRows.length) || (destination[0].length < selectedColumns.length)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, destination.length, destination[0].length, selectedRows.length, selectedColumns.length); } // copy entries for (int i = 0; i < selectedRows.length; i++) { final T[] destinationI = destination[i]; for (int j = 0; j < selectedColumns.length; j++) { destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); } } } /** {@inheritDoc} */ public void setSubMatrix(final T[][] subMatrix, final int row, final int column) throws MatrixIndexException { final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; ++r) { if (subMatrix[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[r].length); } } checkRowIndex(row); checkColumnIndex(column); checkRowIndex(nRows + row - 1); checkColumnIndex(nCols + column - 1); for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { setEntry(row + i, column + j, subMatrix[i][j]); } } } /** {@inheritDoc} */ public FieldMatrix getRowMatrix(final int row) throws MatrixIndexException { checkRowIndex(row); final int nCols = getColumnDimension(); final FieldMatrix out = createMatrix(1, nCols); for (int i = 0; i < nCols; ++i) { out.setEntry(0, i, getEntry(row, i)); } return out; } /** {@inheritDoc} */ public void setRowMatrix(final int row, final FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { checkRowIndex(row); final int nCols = getColumnDimension(); if ((matrix.getRowDimension() != 1) || (matrix.getColumnDimension() != nCols)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, matrix.getEntry(0, i)); } } /** {@inheritDoc} */ public FieldMatrix getColumnMatrix(final int column) throws MatrixIndexException { checkColumnIndex(column); final int nRows = getRowDimension(); final FieldMatrix out = createMatrix(nRows, 1); for (int i = 0; i < nRows; ++i) { out.setEntry(i, 0, getEntry(i, column)); } return out; } /** {@inheritDoc} */ public void setColumnMatrix(final int column, final FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { checkColumnIndex(column); final int nRows = getRowDimension(); if ((matrix.getRowDimension() != nRows) || (matrix.getColumnDimension() != 1)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, matrix.getEntry(i, 0)); } } /** {@inheritDoc} */ public FieldVector getRowVector(final int row) throws MatrixIndexException { return new ArrayFieldVector(getRow(row), false); } /** {@inheritDoc} */ public void setRowVector(final int row, final FieldVector vector) throws MatrixIndexException, InvalidMatrixException { checkRowIndex(row); final int nCols = getColumnDimension(); if (vector.getDimension() != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, vector.getDimension(), 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, vector.getEntry(i)); } } /** {@inheritDoc} */ public FieldVector getColumnVector(final int column) throws MatrixIndexException { return new ArrayFieldVector(getColumn(column), false); } /** {@inheritDoc} */ public void setColumnVector(final int column, final FieldVector vector) throws MatrixIndexException, InvalidMatrixException { checkColumnIndex(column); final int nRows = getRowDimension(); if (vector.getDimension() != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, vector.getDimension(), 1, nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, vector.getEntry(i)); } } /** {@inheritDoc} */ public T[] getRow(final int row) throws MatrixIndexException { checkRowIndex(row); final int nCols = getColumnDimension(); final T[] out = buildArray(field, nCols); for (int i = 0; i < nCols; ++i) { out[i] = getEntry(row, i); } return out; } /** {@inheritDoc} */ public void setRow(final int row, final T[] array) throws MatrixIndexException, InvalidMatrixException { checkRowIndex(row); final int nCols = getColumnDimension(); if (array.length != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, array.length, 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, array[i]); } } /** {@inheritDoc} */ public T[] getColumn(final int column) throws MatrixIndexException { checkColumnIndex(column); final int nRows = getRowDimension(); final T[] out = buildArray(field, nRows); for (int i = 0; i < nRows; ++i) { out[i] = getEntry(i, column); } return out; } /** {@inheritDoc} */ public void setColumn(final int column, final T[] array) throws MatrixIndexException, InvalidMatrixException { checkColumnIndex(column); final int nRows = getRowDimension(); if (array.length != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, array.length, 1, nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, array[i]); } } /** {@inheritDoc} */ public abstract T getEntry(int row, int column) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void setEntry(int row, int column, T value) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void addToEntry(int row, int column, T increment) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void multiplyEntry(int row, int column, T factor) throws MatrixIndexException; /** {@inheritDoc} */ public FieldMatrix transpose() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final FieldMatrix out = createMatrix(nCols, nRows); walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor(field.getZero()) { /** {@inheritDoc} */ @Override public void visit(final int row, final int column, final T value) { out.setEntry(column, row, value); } }); return out; } /** {@inheritDoc} */ public boolean isSquare() { return getColumnDimension() == getRowDimension(); } /** {@inheritDoc} */ public abstract int getRowDimension(); /** {@inheritDoc} */ public abstract int getColumnDimension(); /** {@inheritDoc} */ public T getTrace() throws NonSquareMatrixException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (nRows != nCols) { throw new NonSquareMatrixException(nRows, nCols); } T trace = field.getZero(); for (int i = 0; i < nRows; ++i) { trace = trace.add(getEntry(i, i)); } return trace; } /** {@inheritDoc} */ public T[] operate(final T[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols); } final T[] out = buildArray(field, nRows); for (int row = 0; row < nRows; ++row) { T sum = field.getZero(); for (int i = 0; i < nCols; ++i) { sum = sum.add(getEntry(row, i).multiply(v[i])); } out[row] = sum; } return out; } /** {@inheritDoc} */ public FieldVector operate(final FieldVector v) throws IllegalArgumentException { try { return new ArrayFieldVector(operate(((ArrayFieldVector) v).getDataRef()), false); } catch (ClassCastException cce) { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.getDimension() != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.getDimension(), nCols); } final T[] out = buildArray(field, nRows); for (int row = 0; row < nRows; ++row) { T sum = field.getZero(); for (int i = 0; i < nCols; ++i) { sum = sum.add(getEntry(row, i).multiply(v.getEntry(i))); } out[row] = sum; } return new ArrayFieldVector(out, false); } } /** {@inheritDoc} */ public T[] preMultiply(final T[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows); } final T[] out = buildArray(field, nCols); for (int col = 0; col < nCols; ++col) { T sum = field.getZero(); for (int i = 0; i < nRows; ++i) { sum = sum.add(getEntry(i, col).multiply(v[i])); } out[col] = sum; } return out; } /** {@inheritDoc} */ public FieldVector preMultiply(final FieldVector v) throws IllegalArgumentException { try { return new ArrayFieldVector(preMultiply(((ArrayFieldVector) v).getDataRef()), false); } catch (ClassCastException cce) { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.getDimension() != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.getDimension(), nRows); } final T[] out = buildArray(field, nCols); for (int col = 0; col < nCols; ++col) { T sum = field.getZero(); for (int i = 0; i < nRows; ++i) { sum = sum.add(getEntry(i, col).multiply(v.getEntry(i))); } out[col] = sum; } return new ArrayFieldVector(out); } } /** {@inheritDoc} */ public T walkInRowOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int row = 0; row < rows; ++row) { for (int column = 0; column < columns; ++column) { final T oldValue = getEntry(row, column); final T newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int row = 0; row < rows; ++row) { for (int column = 0; column < columns; ++column) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInRowOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int row = startRow; row <= endRow; ++row) { for (int column = startColumn; column <= endColumn; ++column) { final T oldValue = getEntry(row, column); final T newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int row = startRow; row <= endRow; ++row) { for (int column = startColumn; column <= endColumn; ++column) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInColumnOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int column = 0; column < columns; ++column) { for (int row = 0; row < rows; ++row) { final T oldValue = getEntry(row, column); final T newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInColumnOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int column = 0; column < columns; ++column) { for (int row = 0; row < rows; ++row) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInColumnOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int column = startColumn; column <= endColumn; ++column) { for (int row = startRow; row <= endRow; ++row) { final T oldValue = getEntry(row, column); final T newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInColumnOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int column = startColumn; column <= endColumn; ++column) { for (int row = startRow; row <= endRow; ++row) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public T walkInOptimizedOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { return walkInRowOrder(visitor); } /** {@inheritDoc} */ public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { return walkInRowOrder(visitor); } /** {@inheritDoc} */ public T walkInOptimizedOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); } /** {@inheritDoc} */ public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); } /** * Get a string representation for this matrix. * @return a string representation for this matrix */ @Override public String toString() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final StringBuilder res = new StringBuilder(); String fullClassName = getClass().getName(); String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); res.append(shortClassName).append("{"); for (int i = 0; i < nRows; ++i) { if (i > 0) { res.append(","); } res.append("{"); for (int j = 0; j < nCols; ++j) { if (j > 0) { res.append(","); } res.append(getEntry(i, j)); } res.append("}"); } res.append("}"); return res.toString(); } /** * Returns true iff object is a * FieldMatrix instance with the same dimensions as this * and all corresponding matrix entries are equal. * * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(final Object object) { if (object == this ) { return true; } if (object instanceof FieldMatrix == false) { return false; } FieldMatrix m = (FieldMatrix) object; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { return false; } for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { if (!getEntry(row, col).equals(m.getEntry(row, col))) { return false; } } } return true; } /** * Computes a hashcode for the matrix. * * @return hashcode for matrix */ @Override public int hashCode() { int ret = 322562; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); ret = ret * 31 + nRows; ret = ret * 31 + nCols; for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode(); } } return ret; } /** * Check if a row index is valid. * @param row row index to check * @exception MatrixIndexException if index is not valid */ protected void checkRowIndex(final int row) { if (row < 0 || row >= getRowDimension()) { throw new MatrixIndexException(LocalizedFormats.ROW_INDEX_OUT_OF_RANGE, row, 0, getRowDimension() - 1); } } /** * Check if a column index is valid. * @param column column index to check * @exception MatrixIndexException if index is not valid */ protected void checkColumnIndex(final int column) throws MatrixIndexException { if (column < 0 || column >= getColumnDimension()) { throw new MatrixIndexException(LocalizedFormats.COLUMN_INDEX_OUT_OF_RANGE, column, 0, getColumnDimension() - 1); } } /** * Check if submatrix ranges indices are valid. * Rows and columns are indicated counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixIndexException if the indices are not valid */ protected void checkSubMatrixIndex(final int startRow, final int endRow, final int startColumn, final int endColumn) { checkRowIndex(startRow); checkRowIndex(endRow); if (startRow > endRow) { throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW, startRow, endRow); } checkColumnIndex(startColumn); checkColumnIndex(endColumn); if (startColumn > endColumn) { throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN, startColumn, endColumn); } } /** * Check if submatrix ranges indices are valid. * Rows and columns are indicated counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @exception MatrixIndexException if row or column selections are not valid */ protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) { if (selectedRows.length * selectedColumns.length == 0) { if (selectedRows.length == 0) { throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY); } throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY); } for (final int row : selectedRows) { checkRowIndex(row); } for (final int column : selectedColumns) { checkColumnIndex(column); } } /** * Check if a matrix is addition compatible with the instance * @param m matrix to check * @exception IllegalArgumentException if matrix is not addition compatible with instance */ protected void checkAdditionCompatible(final FieldMatrix m) { if ((getRowDimension() != m.getRowDimension()) || (getColumnDimension() != m.getColumnDimension())) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_ADDITION_COMPATIBLE_MATRICES, getRowDimension(), getColumnDimension(), m.getRowDimension(), m.getColumnDimension()); } } /** * Check if a matrix is subtraction compatible with the instance * @param m matrix to check * @exception IllegalArgumentException if matrix is not subtraction compatible with instance */ protected void checkSubtractionCompatible(final FieldMatrix m) { if ((getRowDimension() != m.getRowDimension()) || (getColumnDimension() != m.getColumnDimension())) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_SUBTRACTION_COMPATIBLE_MATRICES, getRowDimension(), getColumnDimension(), m.getRowDimension(), m.getColumnDimension()); } } /** * Check if a matrix is multiplication compatible with the instance * @param m matrix to check * @exception IllegalArgumentException if matrix is not multiplication compatible with instance */ protected void checkMultiplicationCompatible(final FieldMatrix m) { if (getColumnDimension() != m.getRowDimension()) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_MULTIPLICATION_COMPATIBLE_MATRICES, getRowDimension(), getColumnDimension(), m.getRowDimension(), m.getColumnDimension()); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java100644 1750 1750 54056 11532241245 31121 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Calculates the eigen decomposition of a real symmetric * matrix. *

                    * The eigen decomposition of matrix A is a set of two matrices: V and D such * that A = V D VT. A, V and D are all m × m matrices. *

                    *

                    * As of 2.0, this class supports only symmetric matrices, and * hence computes only real realEigenvalues. This implies the D matrix returned * by {@link #getD()} is always diagonal and the imaginary values returned * {@link #getImagEigenvalue(int)} and {@link #getImagEigenvalues()} are always * null. *

                    *

                    * When called with a {@link RealMatrix} argument, this implementation only uses * the upper part of the matrix, the part below the diagonal is not accessed at * all. *

                    *

                    * This implementation is based on the paper by A. Drubrulle, R.S. Martin and * J.H. Wilkinson 'The Implicit QL Algorithm' in Wilksinson and Reinsch (1971) * Handbook for automatic computation, vol. 2, Linear algebra, Springer-Verlag, * New-York *

                    * @version $Revision: 1002040 $ $Date: 2010-09-28 09:18:31 +0200 (mar. 28 sept. 2010) $ * @since 2.0 */ public class EigenDecompositionImpl implements EigenDecomposition { /** Maximum number of iterations accepted in the implicit QL transformation */ private byte maxIter = 30; /** Main diagonal of the tridiagonal matrix. */ private double[] main; /** Secondary diagonal of the tridiagonal matrix. */ private double[] secondary; /** * Transformer to tridiagonal (may be null if matrix is already * tridiagonal). */ private TriDiagonalTransformer transformer; /** Real part of the realEigenvalues. */ private double[] realEigenvalues; /** Imaginary part of the realEigenvalues. */ private double[] imagEigenvalues; /** Eigenvectors. */ private ArrayRealVector[] eigenvectors; /** Cached value of V. */ private RealMatrix cachedV; /** Cached value of D. */ private RealMatrix cachedD; /** Cached value of Vt. */ private RealMatrix cachedVt; /** * Calculates the eigen decomposition of the given symmetric matrix. * @param matrix The symmetric matrix to decompose. * @param splitTolerance dummy parameter, present for backward compatibility only. * @exception InvalidMatrixException (wrapping a * {@link org.apache.commons.math.ConvergenceException} if algorithm * fails to converge */ public EigenDecompositionImpl(final RealMatrix matrix,final double splitTolerance) throws InvalidMatrixException { if (isSymmetric(matrix)) { transformToTridiagonal(matrix); findEigenVectors(transformer.getQ().getData()); } else { // as of 2.0, non-symmetric matrices (i.e. complex eigenvalues) are // NOT supported // see issue https://issues.apache.org/jira/browse/MATH-235 throw new InvalidMatrixException( LocalizedFormats.ASSYMETRIC_EIGEN_NOT_SUPPORTED); } } /** * Calculates the eigen decomposition of the symmetric tridiagonal * matrix. The Householder matrix is assumed to be the identity matrix. * @param main Main diagonal of the symmetric triadiagonal form * @param secondary Secondary of the tridiagonal form * @param splitTolerance dummy parameter, present for backward compatibility only. * @exception InvalidMatrixException (wrapping a * {@link org.apache.commons.math.ConvergenceException} if algorithm * fails to converge */ public EigenDecompositionImpl(final double[] main,final double[] secondary, final double splitTolerance) throws InvalidMatrixException { this.main = main.clone(); this.secondary = secondary.clone(); transformer = null; final int size=main.length; double[][] z = new double[size][size]; for (int i=0;i (FastMath.max(FastMath.abs(mij), FastMath.abs(mji)) * eps)) { return false; } } } return true; } /** {@inheritDoc} */ public RealMatrix getV() throws InvalidMatrixException { if (cachedV == null) { final int m = eigenvectors.length; cachedV = MatrixUtils.createRealMatrix(m, m); for (int k = 0; k < m; ++k) { cachedV.setColumnVector(k, eigenvectors[k]); } } // return the cached matrix return cachedV; } /** {@inheritDoc} */ public RealMatrix getD() throws InvalidMatrixException { if (cachedD == null) { // cache the matrix for subsequent calls cachedD = MatrixUtils.createRealDiagonalMatrix(realEigenvalues); } return cachedD; } /** {@inheritDoc} */ public RealMatrix getVT() throws InvalidMatrixException { if (cachedVt == null) { final int m = eigenvectors.length; cachedVt = MatrixUtils.createRealMatrix(m, m); for (int k = 0; k < m; ++k) { cachedVt.setRowVector(k, eigenvectors[k]); } } // return the cached matrix return cachedVt; } /** {@inheritDoc} */ public double[] getRealEigenvalues() throws InvalidMatrixException { return realEigenvalues.clone(); } /** {@inheritDoc} */ public double getRealEigenvalue(final int i) throws InvalidMatrixException, ArrayIndexOutOfBoundsException { return realEigenvalues[i]; } /** {@inheritDoc} */ public double[] getImagEigenvalues() throws InvalidMatrixException { return imagEigenvalues.clone(); } /** {@inheritDoc} */ public double getImagEigenvalue(final int i) throws InvalidMatrixException, ArrayIndexOutOfBoundsException { return imagEigenvalues[i]; } /** {@inheritDoc} */ public RealVector getEigenvector(final int i) throws InvalidMatrixException, ArrayIndexOutOfBoundsException { return eigenvectors[i].copy(); } /** * Return the determinant of the matrix * @return determinant of the matrix */ public double getDeterminant() { double determinant = 1; for (double lambda : realEigenvalues) { determinant *= lambda; } return determinant; } /** {@inheritDoc} */ public DecompositionSolver getSolver() { return new Solver(realEigenvalues, imagEigenvalues, eigenvectors); } /** Specialized solver. */ private static class Solver implements DecompositionSolver { /** Real part of the realEigenvalues. */ private double[] realEigenvalues; /** Imaginary part of the realEigenvalues. */ private double[] imagEigenvalues; /** Eigenvectors. */ private final ArrayRealVector[] eigenvectors; /** * Build a solver from decomposed matrix. * @param realEigenvalues * real parts of the eigenvalues * @param imagEigenvalues * imaginary parts of the eigenvalues * @param eigenvectors * eigenvectors */ private Solver(final double[] realEigenvalues, final double[] imagEigenvalues, final ArrayRealVector[] eigenvectors) { this.realEigenvalues = realEigenvalues; this.imagEigenvalues = imagEigenvalues; this.eigenvectors = eigenvectors; } /** * Solve the linear equation A × X = B for symmetric matrices A. *

                    * This method only find exact linear solutions, i.e. solutions for * which ||A × X - B|| is exactly 0. *

                    * @param b * right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match * @exception InvalidMatrixException * if decomposed matrix is singular */ public double[] solve(final double[] b) throws IllegalArgumentException, InvalidMatrixException { if (!isNonSingular()) { throw new SingularMatrixException(); } final int m = realEigenvalues.length; if (b.length != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m); } final double[] bp = new double[m]; for (int i = 0; i < m; ++i) { final ArrayRealVector v = eigenvectors[i]; final double[] vData = v.getDataRef(); final double s = v.dotProduct(b) / realEigenvalues[i]; for (int j = 0; j < m; ++j) { bp[j] += s * vData[j]; } } return bp; } /** * Solve the linear equation A × X = B for symmetric matrices A. *

                    * This method only find exact linear solutions, i.e. solutions for * which ||A × X - B|| is exactly 0. *

                    * @param b * right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match * @exception InvalidMatrixException * if decomposed matrix is singular */ public RealVector solve(final RealVector b) throws IllegalArgumentException, InvalidMatrixException { if (!isNonSingular()) { throw new SingularMatrixException(); } final int m = realEigenvalues.length; if (b.getDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b .getDimension(), m); } final double[] bp = new double[m]; for (int i = 0; i < m; ++i) { final ArrayRealVector v = eigenvectors[i]; final double[] vData = v.getDataRef(); final double s = v.dotProduct(b) / realEigenvalues[i]; for (int j = 0; j < m; ++j) { bp[j] += s * vData[j]; } } return new ArrayRealVector(bp, false); } /** * Solve the linear equation A × X = B for symmetric matrices A. *

                    * This method only find exact linear solutions, i.e. solutions for * which ||A × X - B|| is exactly 0. *

                    * @param b * right-hand side of the equation A × X = B * @return a matrix X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match * @exception InvalidMatrixException * if decomposed matrix is singular */ public RealMatrix solve(final RealMatrix b) throws IllegalArgumentException, InvalidMatrixException { if (!isNonSingular()) { throw new SingularMatrixException(); } final int m = realEigenvalues.length; if (b.getRowDimension() != m) { throw MathRuntimeException .createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), m, "n"); } final int nColB = b.getColumnDimension(); final double[][] bp = new double[m][nColB]; for (int k = 0; k < nColB; ++k) { for (int i = 0; i < m; ++i) { final ArrayRealVector v = eigenvectors[i]; final double[] vData = v.getDataRef(); double s = 0; for (int j = 0; j < m; ++j) { s += v.getEntry(j) * b.getEntry(j, k); } s /= realEigenvalues[i]; for (int j = 0; j < m; ++j) { bp[j][k] += s * vData[j]; } } } return MatrixUtils.createRealMatrix(bp); } /** * Check if the decomposed matrix is non-singular. * @return true if the decomposed matrix is non-singular */ public boolean isNonSingular() { for (int i = 0; i < realEigenvalues.length; ++i) { if ((realEigenvalues[i] == 0) && (imagEigenvalues[i] == 0)) { return false; } } return true; } /** * Get the inverse of the decomposed matrix. * @return inverse matrix * @throws InvalidMatrixException * if decomposed matrix is singular */ public RealMatrix getInverse() throws InvalidMatrixException { if (!isNonSingular()) { throw new SingularMatrixException(); } final int m = realEigenvalues.length; final double[][] invData = new double[m][m]; for (int i = 0; i < m; ++i) { final double[] invI = invData[i]; for (int j = 0; j < m; ++j) { double invIJ = 0; for (int k = 0; k < m; ++k) { final double[] vK = eigenvectors[k].getDataRef(); invIJ += vK[i] * vK[j] / realEigenvalues[k]; } invI[j] = invIJ; } } return MatrixUtils.createRealMatrix(invData); } } /** * Transform matrix to tridiagonal. * @param matrix * matrix to transform */ private void transformToTridiagonal(final RealMatrix matrix) { // transform the matrix to tridiagonal transformer = new TriDiagonalTransformer(matrix); main = transformer.getMainDiagonalRef(); secondary = transformer.getSecondaryDiagonalRef(); } /** * Find eigenvalues and eigenvectors (Dubrulle et al., 1971) * @param householderMatrix Householder matrix of the transformation * to tri-diagonal form. */ private void findEigenVectors(double[][] householderMatrix) { double[][]z = householderMatrix.clone(); final int n = main.length; realEigenvalues = new double[n]; imagEigenvalues = new double[n]; double[] e = new double[n]; for (int i = 0; i < n - 1; i++) { realEigenvalues[i] = main[i]; e[i] = secondary[i]; } realEigenvalues[n - 1] = main[n - 1]; e[n - 1] = 0.0; // Determine the largest main and secondary value in absolute term. double maxAbsoluteValue=0.0; for (int i = 0; i < n; i++) { if (FastMath.abs(realEigenvalues[i])>maxAbsoluteValue) { maxAbsoluteValue=FastMath.abs(realEigenvalues[i]); } if (FastMath.abs(e[i])>maxAbsoluteValue) { maxAbsoluteValue=FastMath.abs(e[i]); } } // Make null any main and secondary value too small to be significant if (maxAbsoluteValue!=0.0) { for (int i=0; i < n; i++) { if (FastMath.abs(realEigenvalues[i])<=MathUtils.EPSILON*maxAbsoluteValue) { realEigenvalues[i]=0.0; } if (FastMath.abs(e[i])<=MathUtils.EPSILON*maxAbsoluteValue) { e[i]=0.0; } } } for (int j = 0; j < n; j++) { int its = 0; int m; do { for (m = j; m < n - 1; m++) { double delta = FastMath.abs(realEigenvalues[m]) + FastMath.abs(realEigenvalues[m + 1]); if (FastMath.abs(e[m]) + delta == delta) { break; } } if (m != j) { if (its == maxIter) throw new InvalidMatrixException( new MaxIterationsExceededException(maxIter)); its++; double q = (realEigenvalues[j + 1] - realEigenvalues[j]) / (2 * e[j]); double t = FastMath.sqrt(1 + q * q); if (q < 0.0) { q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q - t); } else { q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q + t); } double u = 0.0; double s = 1.0; double c = 1.0; int i; for (i = m - 1; i >= j; i--) { double p = s * e[i]; double h = c * e[i]; if (FastMath.abs(p) >= FastMath.abs(q)) { c = q / p; t = FastMath.sqrt(c * c + 1.0); e[i + 1] = p * t; s = 1.0 / t; c = c * s; } else { s = p / q; t = FastMath.sqrt(s * s + 1.0); e[i + 1] = q * t; c = 1.0 / t; s = s * c; } if (e[i + 1] == 0.0) { realEigenvalues[i + 1] -= u; e[m] = 0.0; break; } q = realEigenvalues[i + 1] - u; t = (realEigenvalues[i] - q) * s + 2.0 * c * h; u = s * t; realEigenvalues[i + 1] = q + u; q = c * t - h; for (int ia = 0; ia < n; ia++) { p = z[ia][i + 1]; z[ia][i + 1] = s * z[ia][i] + c * p; z[ia][i] = c * z[ia][i] - s * p; } } if (t == 0.0 && i >= j) continue; realEigenvalues[j] -= u; e[j] = q; e[m] = 0.0; } } while (m != j); } //Sort the eigen values (and vectors) in increase order for (int i = 0; i < n; i++) { int k = i; double p = realEigenvalues[i]; for (int j = i + 1; j < n; j++) { if (realEigenvalues[j] > p) { k = j; p = realEigenvalues[j]; } } if (k != i) { realEigenvalues[k] = realEigenvalues[i]; realEigenvalues[i] = p; for (int j = 0; j < n; j++) { p = z[j][i]; z[j][i] = z[j][k]; z[j][k] = p; } } } // Determine the largest eigen value in absolute term. maxAbsoluteValue=0.0; for (int i = 0; i < n; i++) { if (FastMath.abs(realEigenvalues[i])>maxAbsoluteValue) { maxAbsoluteValue=FastMath.abs(realEigenvalues[i]); } } // Make null any eigen value too small to be significant if (maxAbsoluteValue!=0.0) { for (int i=0; i < n; i++) { if (FastMath.abs(realEigenvalues[i])The LUP-decomposition of a matrix A consists of three matrices * L, U and P that satisfy: PA = LU, L is lower triangular, and U is * upper triangular and P is a permutation matrix. All matrices are * m×m.

                    *

                    Since {@link FieldElement field elements} do not provide an ordering * operator, the permutation matrix is computed here only in order to avoid * a zero pivot element, no attempt is done to get the largest pivot element.

                    * * @param the type of the field elements * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class FieldLUDecompositionImpl> implements FieldLUDecomposition { /** Field to which the elements belong. */ private final Field field; /** Entries of LU decomposition. */ private T lu[][]; /** Pivot permutation associated with LU decomposition */ private int[] pivot; /** Parity of the permutation associated with the LU decomposition */ private boolean even; /** Singularity indicator. */ private boolean singular; /** Cached value of L. */ private FieldMatrix cachedL; /** Cached value of U. */ private FieldMatrix cachedU; /** Cached value of P. */ private FieldMatrix cachedP; /** * Calculates the LU-decomposition of the given matrix. * @param matrix The matrix to decompose. * @exception NonSquareMatrixException if matrix is not square */ public FieldLUDecompositionImpl(FieldMatrix matrix) throws NonSquareMatrixException { if (!matrix.isSquare()) { throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); } final int m = matrix.getColumnDimension(); field = matrix.getField(); lu = matrix.getData(); pivot = new int[m]; cachedL = null; cachedU = null; cachedP = null; // Initialize permutation array and parity for (int row = 0; row < m; row++) { pivot[row] = row; } even = true; singular = false; // Loop over columns for (int col = 0; col < m; col++) { T sum = field.getZero(); // upper for (int row = 0; row < col; row++) { final T[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < row; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; } // lower int nonZero = col; // permutation row for (int row = col; row < m; row++) { final T[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < col; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; if (lu[nonZero][col].equals(field.getZero())) { // try to select a better permutation choice ++nonZero; } } // Singularity check if (nonZero >= m) { singular = true; return; } // Pivot if necessary if (nonZero != col) { T tmp = field.getZero(); for (int i = 0; i < m; i++) { tmp = lu[nonZero][i]; lu[nonZero][i] = lu[col][i]; lu[col][i] = tmp; } int temp = pivot[nonZero]; pivot[nonZero] = pivot[col]; pivot[col] = temp; even = !even; } // Divide the lower elements by the "winning" diagonal elt. final T luDiag = lu[col][col]; for (int row = col + 1; row < m; row++) { final T[] luRow = lu[row]; luRow[col] = luRow[col].divide(luDiag); } } } /** {@inheritDoc} */ public FieldMatrix getL() { if ((cachedL == null) && !singular) { final int m = pivot.length; cachedL = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < m; ++i) { final T[] luI = lu[i]; for (int j = 0; j < i; ++j) { cachedL.setEntry(i, j, luI[j]); } cachedL.setEntry(i, i, field.getOne()); } } return cachedL; } /** {@inheritDoc} */ public FieldMatrix getU() { if ((cachedU == null) && !singular) { final int m = pivot.length; cachedU = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < m; ++i) { final T[] luI = lu[i]; for (int j = i; j < m; ++j) { cachedU.setEntry(i, j, luI[j]); } } } return cachedU; } /** {@inheritDoc} */ public FieldMatrix getP() { if ((cachedP == null) && !singular) { final int m = pivot.length; cachedP = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < m; ++i) { cachedP.setEntry(i, pivot[i], field.getOne()); } } return cachedP; } /** {@inheritDoc} */ public int[] getPivot() { return pivot.clone(); } /** {@inheritDoc} */ public T getDeterminant() { if (singular) { return field.getZero(); } else { final int m = pivot.length; T determinant = even ? field.getOne() : field.getZero().subtract(field.getOne()); for (int i = 0; i < m; i++) { determinant = determinant.multiply(lu[i][i]); } return determinant; } } /** {@inheritDoc} */ public FieldDecompositionSolver getSolver() { return new Solver(field, lu, pivot, singular); } /** Specialized solver. */ private static class Solver> implements FieldDecompositionSolver { /** Serializable version identifier. */ private static final long serialVersionUID = -6353105415121373022L; /** Field to which the elements belong. */ private final Field field; /** Entries of LU decomposition. */ private final T lu[][]; /** Pivot permutation associated with LU decomposition. */ private final int[] pivot; /** Singularity indicator. */ private final boolean singular; /** * Build a solver from decomposed matrix. * @param field field to which the matrix elements belong * @param lu entries of LU decomposition * @param pivot pivot permutation associated with LU decomposition * @param singular singularity indicator */ private Solver(final Field field, final T[][] lu, final int[] pivot, final boolean singular) { this.field = field; this.lu = lu; this.pivot = pivot; this.singular = singular; } /** {@inheritDoc} */ public boolean isNonSingular() { return !singular; } /** {@inheritDoc} */ public T[] solve(T[] b) throws IllegalArgumentException, InvalidMatrixException { final int m = pivot.length; if (b.length != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m); } if (singular) { throw new SingularMatrixException(); } @SuppressWarnings("unchecked") // field is of type T final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m); // Apply permutations to b for (int row = 0; row < m; row++) { bp[row] = b[pivot[row]]; } // Solve LY = b for (int col = 0; col < m; col++) { final T bpCol = bp[col]; for (int i = col + 1; i < m; i++) { bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { bp[col] = bp[col].divide(lu[col][col]); final T bpCol = bp[col]; for (int i = 0; i < col; i++) { bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); } } return bp; } /** {@inheritDoc} */ public FieldVector solve(FieldVector b) throws IllegalArgumentException, InvalidMatrixException { try { return solve((ArrayFieldVector) b); } catch (ClassCastException cce) { final int m = pivot.length; if (b.getDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.getDimension(), m); } if (singular) { throw new SingularMatrixException(); } @SuppressWarnings("unchecked") // field is of type T final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m); // Apply permutations to b for (int row = 0; row < m; row++) { bp[row] = b.getEntry(pivot[row]); } // Solve LY = b for (int col = 0; col < m; col++) { final T bpCol = bp[col]; for (int i = col + 1; i < m; i++) { bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { bp[col] = bp[col].divide(lu[col][col]); final T bpCol = bp[col]; for (int i = 0; i < col; i++) { bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); } } return new ArrayFieldVector(bp, false); } } /** Solve the linear equation A × X = B. *

                    The A matrix is implicit here. It is

                    * @param b right-hand side of the equation A × X = B * @return a vector X such that A × X = B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ public ArrayFieldVector solve(ArrayFieldVector b) throws IllegalArgumentException, InvalidMatrixException { return new ArrayFieldVector(solve(b.getDataRef()), false); } /** {@inheritDoc} */ public FieldMatrix solve(FieldMatrix b) throws IllegalArgumentException, InvalidMatrixException { final int m = pivot.length; if (b.getRowDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), m, "n"); } if (singular) { throw new SingularMatrixException(); } final int nColB = b.getColumnDimension(); // Apply permutations to b @SuppressWarnings("unchecked") // field is of type T final T[][] bp = (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { m, nColB }); for (int row = 0; row < m; row++) { final T[] bpRow = bp[row]; final int pRow = pivot[row]; for (int col = 0; col < nColB; col++) { bpRow[col] = b.getEntry(pRow, col); } } // Solve LY = b for (int col = 0; col < m; col++) { final T[] bpCol = bp[col]; for (int i = col + 1; i < m; i++) { final T[] bpI = bp[i]; final T luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol)); } } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { final T[] bpCol = bp[col]; final T luDiag = lu[col][col]; for (int j = 0; j < nColB; j++) { bpCol[j] = bpCol[j].divide(luDiag); } for (int i = 0; i < col; i++) { final T[] bpI = bp[i]; final T luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol)); } } } return new Array2DRowFieldMatrix(bp, false); } /** {@inheritDoc} */ public FieldMatrix getInverse() throws InvalidMatrixException { final int m = pivot.length; final T one = field.getOne(); FieldMatrix identity = new Array2DRowFieldMatrix(field, m, m); for (int i = 0; i < m; ++i) { identity.setEntry(i, i, one); } return solve(identity); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldVector.java100644 1750 1750 27342 11532241245 26717 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; /** * Interface defining a field-valued vector with basic algebraic operations. *

                    * vector element indexing is 0-based -- e.g., getEntry(0) * returns the first element of the vector. *

                    *

                    * The various mapXxx and mapXxxToSelf methods operate * on vectors element-wise, i.e. they perform the same operation (adding a scalar, * applying a function ...) on each element in turn. The mapXxx * versions create a new vector to hold the result and do not change the instance. * The mapXxxToSelf versions use the instance itself to store the * results, so the instance is changed by these methods. In both cases, the result * vector is returned by the methods, this allows to use the fluent API * style, like this: *

                    *
                     *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
                     * 
                    * * @param the type of the field elements * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public interface FieldVector> { /** * Get the type of field elements of the vector. * @return type of field elements of the vector */ Field getField(); /** * Returns a (deep) copy of this. * @return vector copy */ FieldVector copy(); /** * Compute the sum of this and v. * @param v vector to be added * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector add(FieldVector v) throws IllegalArgumentException; /** * Compute the sum of this and v. * @param v vector to be added * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector add(T[] v) throws IllegalArgumentException; /** * Compute this minus v. * @param v vector to be subtracted * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector subtract(FieldVector v) throws IllegalArgumentException; /** * Compute this minus v. * @param v vector to be subtracted * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector subtract(T[] v) throws IllegalArgumentException; /** * Map an addition operation to each entry. * @param d value to be added to each entry * @return this + d */ FieldVector mapAdd(T d); /** * Map an addition operation to each entry. *

                    The instance is changed by this method.

                    * @param d value to be added to each entry * @return for convenience, return this */ FieldVector mapAddToSelf(T d); /** * Map a subtraction operation to each entry. * @param d value to be subtracted to each entry * @return this - d */ FieldVector mapSubtract(T d); /** * Map a subtraction operation to each entry. *

                    The instance is changed by this method.

                    * @param d value to be subtracted to each entry * @return for convenience, return this */ FieldVector mapSubtractToSelf(T d); /** * Map a multiplication operation to each entry. * @param d value to multiply all entries by * @return this * d */ FieldVector mapMultiply(T d); /** * Map a multiplication operation to each entry. *

                    The instance is changed by this method.

                    * @param d value to multiply all entries by * @return for convenience, return this */ FieldVector mapMultiplyToSelf(T d); /** * Map a division operation to each entry. * @param d value to divide all entries by * @return this / d */ FieldVector mapDivide(T d); /** * Map a division operation to each entry. *

                    The instance is changed by this method.

                    * @param d value to divide all entries by * @return for convenience, return this */ FieldVector mapDivideToSelf(T d); /** * Map the 1/x function to each entry. * @return a vector containing the result of applying the function to each entry */ FieldVector mapInv(); /** * Map the 1/x function to each entry. *

                    The instance is changed by this method.

                    * @return for convenience, return this */ FieldVector mapInvToSelf(); /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ FieldVector ebeMultiply(FieldVector v) throws IllegalArgumentException; /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ FieldVector ebeMultiply(T[] v) throws IllegalArgumentException; /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ FieldVector ebeDivide(FieldVector v) throws IllegalArgumentException; /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ FieldVector ebeDivide(T[] v) throws IllegalArgumentException; /** * Returns vector entries as a T array. * @return T array of entries */ T[] getData(); /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ T dotProduct(FieldVector v) throws IllegalArgumentException; /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ T dotProduct(T[] v) throws IllegalArgumentException; /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector projection(FieldVector v) throws IllegalArgumentException; /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws IllegalArgumentException if v is not the same size as this */ FieldVector projection(T[] v) throws IllegalArgumentException; /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ FieldMatrix outerProduct(FieldVector v) throws IllegalArgumentException; /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ FieldMatrix outerProduct(T[] v) throws IllegalArgumentException; /** * Returns the entry in the specified index. *

                    * The index start at 0 and must be lesser than the size, * otherwise a {@link MatrixIndexException} is thrown. *

                    * @param index index location of entry to be fetched * @return vector entry at index * @throws MatrixIndexException if the index is not valid * @see #setEntry(int, FieldElement) */ T getEntry(int index) throws MatrixIndexException; /** * Set a single element. * @param index element index. * @param value new value for the element. * @exception MatrixIndexException if the index is * inconsistent with vector size * @see #getEntry(int) */ void setEntry(int index, T value) throws MatrixIndexException; /** * Returns the size of the vector. * @return size */ int getDimension(); /** * Construct a vector by appending a vector to this vector. * @param v vector to append to this one. * @return a new vector */ FieldVector append(FieldVector v); /** * Construct a vector by appending a T to this vector. * @param d T to append. * @return a new vector */ FieldVector append(T d); /** * Construct a vector by appending a T array to this vector. * @param a T array to append. * @return a new vector */ FieldVector append(T[] a); /** * Get a subvector from consecutive elements. * @param index index of first element. * @param n number of elements to be retrieved. * @return a vector containing n elements. * @exception MatrixIndexException if the index is * inconsistent with vector size */ FieldVector getSubVector(int index, int n) throws MatrixIndexException; /** * Set a set of consecutive elements. * @param index index of first element to be set. * @param v vector containing the values to set. * @exception MatrixIndexException if the index is * inconsistent with vector size * @see #setSubVector(int, FieldElement[]) */ void setSubVector(int index, FieldVector v) throws MatrixIndexException; /** * Set a set of consecutive elements. * @param index index of first element to be set. * @param v vector containing the values to set. * @exception MatrixIndexException if the index is * inconsistent with vector size * @see #setSubVector(int, FieldVector) */ void setSubVector(int index, T[] v) throws MatrixIndexException; /** * Set all elements to a single value. * @param value single value to set for all elements */ void set(T value); /** * Convert the vector to a T array. *

                    The array is independent from vector data, it's elements * are copied.

                    * @return array containing a copy of vector elements */ T[] toArray(); } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.100644 1750 1750 4061 11532241245 32354 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; import org.apache.commons.math.linear.MatrixVisitorException; /** * Default implementation of the {@link FieldMatrixChangingVisitor} interface. *

                    * This class is a convenience to create custom visitors without defining all * methods. This class provides default implementations that do nothing. *

                    * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class DefaultFieldMatrixChangingVisitor> implements FieldMatrixChangingVisitor { /** Zero element of the field. */ private final T zero; /** Build a new instance. * @param zero additive identity of the field */ public DefaultFieldMatrixChangingVisitor(final T zero) { this.zero = zero; } /** {@inheritDoc} */ public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { } /** {@inheritDoc} */ public T visit(int row, int column, T value) throws MatrixVisitorException { return value; } /** {@inheritDoc} */ public T end() { return zero; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java100644 1750 1750 65561 11532241245 30250 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Iterator; import java.util.NoSuchElementException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.MathUnsupportedOperationException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.analysis.BinaryFunction; import org.apache.commons.math.analysis.ComposableFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * This class provides default basic implementations for many methods in the * {@link RealVector} interface. * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.1 */ public abstract class AbstractRealVector implements RealVector { /** * Check if instance and specified vectors have the same dimension. * @param v vector to compare instance with * @exception DimensionMismatchException if the vectors do not * have the same dimension */ protected void checkVectorDimensions(RealVector v) { checkVectorDimensions(v.getDimension()); } /** * Check if instance dimension is equal to some expected value. * * @param n expected dimension. * @exception DimensionMismatchException if the dimension is * inconsistent with vector size */ protected void checkVectorDimensions(int n) throws DimensionMismatchException { int d = getDimension(); if (d != n) { throw new DimensionMismatchException(d, n); } } /** * Check if an index is valid. * @param index index to check * @exception MatrixIndexException if index is not valid */ protected void checkIndex(final int index) throws MatrixIndexException { if (index < 0 || index >= getDimension()) { throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE, index, 0, getDimension() - 1); } } /** {@inheritDoc} */ public void setSubVector(int index, RealVector v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.getDimension() - 1); setSubVector(index, v.getData()); } /** {@inheritDoc} */ public void setSubVector(int index, double[] v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.length - 1); for (int i = 0; i < v.length; i++) { setEntry(i + index, v[i]); } } /** {@inheritDoc} */ public RealVector add(double[] v) throws IllegalArgumentException { double[] result = v.clone(); Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { result[e.getIndex()] += e.getValue(); } return new ArrayRealVector(result, false); } /** {@inheritDoc} */ public RealVector add(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { double[] values = ((ArrayRealVector)v).getDataRef(); return add(values); } RealVector result = v.copy(); Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { final int index = e.getIndex(); result.setEntry(index, e.getValue() + result.getEntry(index)); } return result; } /** {@inheritDoc} */ public RealVector subtract(double[] v) throws IllegalArgumentException { double[] result = v.clone(); Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { final int index = e.getIndex(); result[index] = e.getValue() - result[index]; } return new ArrayRealVector(result, false); } /** {@inheritDoc} */ public RealVector subtract(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { double[] values = ((ArrayRealVector)v).getDataRef(); return add(values); } RealVector result = v.copy(); Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { final int index = e.getIndex(); v.setEntry(index, e.getValue() - result.getEntry(index)); } return result; } /** {@inheritDoc} */ public RealVector mapAdd(double d) { return copy().mapAddToSelf(d); } /** {@inheritDoc} */ public RealVector mapAddToSelf(double d) { if (d != 0) { try { return mapToSelf(BinaryFunction.ADD.fix1stArgument(d)); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } return this; } /** {@inheritDoc} */ public abstract AbstractRealVector copy(); /** {@inheritDoc} */ public double dotProduct(double[] v) throws IllegalArgumentException { return dotProduct(new ArrayRealVector(v, false)); } /** {@inheritDoc} */ public double dotProduct(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v); double d = 0; Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { d += e.getValue() * v.getEntry(e.getIndex()); } return d; } /** {@inheritDoc} */ public RealVector ebeDivide(double[] v) throws IllegalArgumentException { return ebeDivide(new ArrayRealVector(v, false)); } /** {@inheritDoc} */ public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { return ebeMultiply(new ArrayRealVector(v, false)); } /** {@inheritDoc} */ public double getDistance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v); double d = 0; Iterator it = iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { final double diff = e.getValue() - v.getEntry(e.getIndex()); d += diff * diff; } return FastMath.sqrt(d); } /** {@inheritDoc} */ public double getNorm() { double sum = 0; Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { final double value = e.getValue(); sum += value * value; } return FastMath.sqrt(sum); } /** {@inheritDoc} */ public double getL1Norm() { double norm = 0; Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { norm += FastMath.abs(e.getValue()); } return norm; } /** {@inheritDoc} */ public double getLInfNorm() { double norm = 0; Iterator it = sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { norm = FastMath.max(norm, FastMath.abs(e.getValue())); } return norm; } /** {@inheritDoc} */ public double getDistance(double[] v) throws IllegalArgumentException { return getDistance(new ArrayRealVector(v,false)); } /** {@inheritDoc} */ public double getL1Distance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v); double d = 0; Iterator it = iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex())); } return d; } /** {@inheritDoc} */ public double getL1Distance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double d = 0; Iterator it = iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { d += FastMath.abs(e.getValue() - v[e.getIndex()]); } return d; } /** {@inheritDoc} */ public double getLInfDistance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v); double d = 0; Iterator it = iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d); } return d; } /** {@inheritDoc} */ public double getLInfDistance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double d = 0; Iterator it = iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d); } return d; } /** Get the index of the minimum entry. * @return index of the minimum entry or -1 if vector length is 0 * or all entries are NaN */ public int getMinIndex() { int minIndex = -1; double minValue = Double.POSITIVE_INFINITY; Iterator iterator = iterator(); while (iterator.hasNext()) { final Entry entry = iterator.next(); if (entry.getValue() <= minValue) { minIndex = entry.getIndex(); minValue = entry.getValue(); } } return minIndex; } /** Get the value of the minimum entry. * @return value of the minimum entry or NaN if all entries are NaN */ public double getMinValue() { final int minIndex = getMinIndex(); return minIndex < 0 ? Double.NaN : getEntry(minIndex); } /** Get the index of the maximum entry. * @return index of the maximum entry or -1 if vector length is 0 * or all entries are NaN */ public int getMaxIndex() { int maxIndex = -1; double maxValue = Double.NEGATIVE_INFINITY; Iterator iterator = iterator(); while (iterator.hasNext()) { final Entry entry = iterator.next(); if (entry.getValue() >= maxValue) { maxIndex = entry.getIndex(); maxValue = entry.getValue(); } } return maxIndex; } /** Get the value of the maximum entry. * @return value of the maximum entry or NaN if all entries are NaN */ public double getMaxValue() { final int maxIndex = getMaxIndex(); return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); } /** {@inheritDoc} */ public RealVector mapAbs() { return copy().mapAbsToSelf(); } /** {@inheritDoc} */ public RealVector mapAbsToSelf() { try { return mapToSelf(ComposableFunction.ABS); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapAcos() { return copy().mapAcosToSelf(); } /** {@inheritDoc} */ public RealVector mapAcosToSelf() { try { return mapToSelf(ComposableFunction.ACOS); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapAsin() { return copy().mapAsinToSelf(); } /** {@inheritDoc} */ public RealVector mapAsinToSelf() { try { return mapToSelf(ComposableFunction.ASIN); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapAtan() { return copy().mapAtanToSelf(); } /** {@inheritDoc} */ public RealVector mapAtanToSelf() { try { return mapToSelf(ComposableFunction.ATAN); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapCbrt() { return copy().mapCbrtToSelf(); } /** {@inheritDoc} */ public RealVector mapCbrtToSelf() { try { return mapToSelf(ComposableFunction.CBRT); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapCeil() { return copy().mapCeilToSelf(); } /** {@inheritDoc} */ public RealVector mapCeilToSelf() { try { return mapToSelf(ComposableFunction.CEIL); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapCos() { return copy().mapCosToSelf(); } /** {@inheritDoc} */ public RealVector mapCosToSelf() { try { return mapToSelf(ComposableFunction.COS); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapCosh() { return copy().mapCoshToSelf(); } /** {@inheritDoc} */ public RealVector mapCoshToSelf() { try { return mapToSelf(ComposableFunction.COSH); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapDivide(double d) { return copy().mapDivideToSelf(d); } /** {@inheritDoc} */ public RealVector mapDivideToSelf(double d){ try { return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d)); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapExp() { return copy().mapExpToSelf(); } /** {@inheritDoc} */ public RealVector mapExpToSelf() { try { return mapToSelf(ComposableFunction.EXP); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapExpm1() { return copy().mapExpm1ToSelf(); } /** {@inheritDoc} */ public RealVector mapExpm1ToSelf() { try { return mapToSelf(ComposableFunction.EXPM1); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapFloor() { return copy().mapFloorToSelf(); } /** {@inheritDoc} */ public RealVector mapFloorToSelf() { try { return mapToSelf(ComposableFunction.FLOOR); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapInv() { return copy().mapInvToSelf(); } /** {@inheritDoc} */ public RealVector mapInvToSelf() { try { return mapToSelf(ComposableFunction.INVERT); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapLog() { return copy().mapLogToSelf(); } /** {@inheritDoc} */ public RealVector mapLogToSelf() { try { return mapToSelf(ComposableFunction.LOG); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapLog10() { return copy().mapLog10ToSelf(); } /** {@inheritDoc} */ public RealVector mapLog10ToSelf() { try { return mapToSelf(ComposableFunction.LOG10); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapLog1p() { return copy().mapLog1pToSelf(); } /** {@inheritDoc} */ public RealVector mapLog1pToSelf() { try { return mapToSelf(ComposableFunction.LOG1P); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapMultiply(double d) { return copy().mapMultiplyToSelf(d); } /** {@inheritDoc} */ public RealVector mapMultiplyToSelf(double d){ try { return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d)); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapPow(double d) { return copy().mapPowToSelf(d); } /** {@inheritDoc} */ public RealVector mapPowToSelf(double d){ try { return mapToSelf(BinaryFunction.POW.fix2ndArgument(d)); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapRint() { return copy().mapRintToSelf(); } /** {@inheritDoc} */ public RealVector mapRintToSelf() { try { return mapToSelf(ComposableFunction.RINT); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapSignum() { return copy().mapSignumToSelf(); } /** {@inheritDoc} */ public RealVector mapSignumToSelf() { try { return mapToSelf(ComposableFunction.SIGNUM); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapSin() { return copy().mapSinToSelf(); } /** {@inheritDoc} */ public RealVector mapSinToSelf() { try { return mapToSelf(ComposableFunction.SIN); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapSinh() { return copy().mapSinhToSelf(); } /** {@inheritDoc} */ public RealVector mapSinhToSelf() { try { return mapToSelf(ComposableFunction.SINH); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapSqrt() { return copy().mapSqrtToSelf(); } /** {@inheritDoc} */ public RealVector mapSqrtToSelf() { try { return mapToSelf(ComposableFunction.SQRT); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapSubtract(double d) { return copy().mapSubtractToSelf(d); } /** {@inheritDoc} */ public RealVector mapSubtractToSelf(double d){ return mapAddToSelf(-d); } /** {@inheritDoc} */ public RealVector mapTan() { return copy().mapTanToSelf(); } /** {@inheritDoc} */ public RealVector mapTanToSelf() { try { return mapToSelf(ComposableFunction.TAN); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapTanh() { return copy().mapTanhToSelf(); } /** {@inheritDoc} */ public RealVector mapTanhToSelf() { try { return mapToSelf(ComposableFunction.TANH); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealVector mapUlp() { return copy().mapUlpToSelf(); } /** {@inheritDoc} */ public RealVector mapUlpToSelf() { try { return mapToSelf(ComposableFunction.ULP); } catch (FunctionEvaluationException e) { throw new IllegalArgumentException(e); } } /** {@inheritDoc} */ public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { RealMatrix product; if (v instanceof SparseRealVector || this instanceof SparseRealVector) { product = new OpenMapRealMatrix(this.getDimension(), v.getDimension()); } else { product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension()); } Iterator thisIt = sparseIterator(); Entry thisE = null; while (thisIt.hasNext() && (thisE = thisIt.next()) != null) { Iterator otherIt = v.sparseIterator(); Entry otherE = null; while (otherIt.hasNext() && (otherE = otherIt.next()) != null) { product.setEntry(thisE.getIndex(), otherE.getIndex(), thisE.getValue() * otherE.getValue()); } } return product; } /** {@inheritDoc} */ public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { return outerProduct(new ArrayRealVector(v, false)); } /** {@inheritDoc} */ public RealVector projection(double[] v) throws IllegalArgumentException { return projection(new ArrayRealVector(v, false)); } /** {@inheritDoc} */ public void set(double value) { Iterator it = iterator(); Entry e = null; while (it.hasNext() && (e = it.next()) != null) { e.setValue(value); } } /** {@inheritDoc} */ public double[] toArray() { int dim = getDimension(); double[] values = new double[dim]; for (int i = 0; i < dim; i++) { values[i] = getEntry(i); } return values; } /** {@inheritDoc} */ public double[] getData() { return toArray(); } /** {@inheritDoc} */ public RealVector unitVector() { RealVector copy = copy(); copy.unitize(); return copy; } /** {@inheritDoc} */ public void unitize() { mapDivideToSelf(getNorm()); } /** {@inheritDoc} */ public Iterator sparseIterator() { return new SparseEntryIterator(); } /** {@inheritDoc} */ public Iterator iterator() { final int dim = getDimension(); return new Iterator() { /** Current index. */ private int i = 0; /** Current entry. */ private EntryImpl e = new EntryImpl(); /** {@inheritDoc} */ public boolean hasNext() { return i < dim; } /** {@inheritDoc} */ public Entry next() { e.setIndex(i++); return e; } /** {@inheritDoc} */ public void remove() { throw new MathUnsupportedOperationException(); } }; } /** {@inheritDoc} */ public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException { return copy().mapToSelf(function); } /** {@inheritDoc} */ public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException { Iterator it = (function.value(0) == 0) ? sparseIterator() : iterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { e.setValue(function.value(e.getValue())); } return this; } /** An entry in the vector. */ protected class EntryImpl extends Entry { /** Simple constructor. */ public EntryImpl() { setIndex(0); } /** {@inheritDoc} */ @Override public double getValue() { return getEntry(getIndex()); } /** {@inheritDoc} */ @Override public void setValue(double newValue) { setEntry(getIndex(), newValue); } } /** * This class should rare be used, but is here to provide * a default implementation of sparseIterator(), which is implemented * by walking over the entries, skipping those whose values are the default one. * * Concrete subclasses which are SparseVector implementations should * make their own sparse iterator, not use this one. * * This implementation might be useful for ArrayRealVector, when expensive * operations which preserve the default value are to be done on the entries, * and the fraction of non-default values is small (i.e. someone took a * SparseVector, and passed it into the copy-constructor of ArrayRealVector) */ protected class SparseEntryIterator implements Iterator { /** Dimension of the vector. */ private final int dim; /** last entry returned by {@link #next()} */ private EntryImpl current; /** Next entry for {@link #next()} to return. */ private EntryImpl next; /** Simple constructor. */ protected SparseEntryIterator() { dim = getDimension(); current = new EntryImpl(); next = new EntryImpl(); if (next.getValue() == 0) { advance(next); } } /** Advance an entry up to the next nonzero one. * @param e entry to advance */ protected void advance(EntryImpl e) { if (e == null) { return; } do { e.setIndex(e.getIndex() + 1); } while (e.getIndex() < dim && e.getValue() == 0); if (e.getIndex() >= dim) { e.setIndex(-1); } } /** {@inheritDoc} */ public boolean hasNext() { return next.getIndex() >= 0; } /** {@inheritDoc} */ public Entry next() { int index = next.getIndex(); if (index < 0) { throw new NoSuchElementException(); } current.setIndex(index); advance(next); return current; } /** {@inheritDoc} */ public void remove() { throw new MathUnsupportedOperationException(); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java100644 1750 1750 7343 11532241245 30477 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * Interface handling decomposition algorithms that can solve A × X = B. *

                    Decomposition algorithms decompose an A matrix has a product of several specific * matrices from which they can solve A × X = B in least squares sense: they find X * such that ||A × X - B|| is minimal.

                    *

                    Some solvers like {@link LUDecomposition} can only find the solution for * square matrices and when the solution is an exact linear solution, i.e. when * ||A × X - B|| is exactly 0. Other solvers can also find solutions * with non-square matrix A and with non-null minimal norm. If an exact linear * solution exists it is also the minimal norm solution.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface DecompositionSolver { /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ double[] solve(final double[] b) throws IllegalArgumentException, InvalidMatrixException; /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ RealVector solve(final RealVector b) throws IllegalArgumentException, InvalidMatrixException; /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a matrix X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ RealMatrix solve(final RealMatrix b) throws IllegalArgumentException, InvalidMatrixException; /** * Check if the decomposed matrix is non-singular. * @return true if the decomposed matrix is non-singular */ boolean isNonSingular(); /** Get the inverse (or pseudo-inverse) of the decomposed matrix. * @return inverse matrix * @throws InvalidMatrixException if decomposed matrix is singular */ RealMatrix getInverse() throws InvalidMatrixException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.java100644 1750 1750 4443 11532241245 32323 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining a visitor for matrix entries. * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface FieldMatrixPreservingVisitor> { /** * Start visiting a matrix. *

                    This method is called once before any entry of the matrix is visited.

                    * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) */ void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn); /** * Visit one matrix entry. * @param row row index of the entry * @param column column index of the entry * @param value current value of the entry * @throws MatrixVisitorException if something wrong occurs */ void visit(int row, int column, T value) throws MatrixVisitorException; /** * End visiting a matrix. *

                    This method is called once after all entries of the matrix have been visited.

                    * @return the value that the walkInXxxOrder must return */ T end(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SparseFieldMatrix.java100644 1750 1750 13707 11532241245 30077 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.util.OpenIntToFieldHashMap; /** * Sparse matrix implementation based on an open addressed map. * * @param the type of the field elements * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public class SparseFieldMatrix> extends AbstractFieldMatrix { /** * Serial id */ private static final long serialVersionUID = 9078068119297757342L; /** Storage for (sparse) matrix elements. */ private final OpenIntToFieldHashMap entries; /** * row dimension */ private final int rows; /** * column dimension */ private final int columns; /** * Creates a matrix with no data. * @param field field to which the elements belong */ public SparseFieldMatrix(final Field field) { super(field); rows = 0; columns= 0; entries = new OpenIntToFieldHashMap(field); } /** * Create a new SparseFieldMatrix with the supplied row and column dimensions. * * @param field field to which the elements belong * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not positive */ public SparseFieldMatrix(final Field field, final int rowDimension, final int columnDimension) throws IllegalArgumentException { super(field, rowDimension, columnDimension); this.rows = rowDimension; this.columns = columnDimension; entries = new OpenIntToFieldHashMap(field); } /** * Copy constructor. * @param other The instance to copy */ public SparseFieldMatrix(SparseFieldMatrix other) { super(other.getField(), other.getRowDimension(), other.getColumnDimension()); rows = other.getRowDimension(); columns = other.getColumnDimension(); entries = new OpenIntToFieldHashMap(other.entries); } /** * Generic copy constructor. * @param other The instance to copy */ public SparseFieldMatrix(FieldMatrix other){ super(other.getField(), other.getRowDimension(), other.getColumnDimension()); rows = other.getRowDimension(); columns = other.getColumnDimension(); entries = new OpenIntToFieldHashMap(getField()); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { setEntry(i, j, other.getEntry(i, j)); } } } /** {@inheritDoc} */ @Override public void addToEntry(int row, int column, T increment) throws MatrixIndexException { checkRowIndex(row); checkColumnIndex(column); final int key = computeKey(row, column); final T value = entries.get(key).add(increment); if (getField().getZero().equals(value)) { entries.remove(key); } else { entries.put(key, value); } } /** {@inheritDoc} */ @Override public FieldMatrix copy() { return new SparseFieldMatrix(this); } /** {@inheritDoc} */ @Override public FieldMatrix createMatrix(int rowDimension, int columnDimension) throws IllegalArgumentException { return new SparseFieldMatrix(getField(), rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public int getColumnDimension() { return columns; } /** {@inheritDoc} */ @Override public T getEntry(int row, int column) throws MatrixIndexException { checkRowIndex(row); checkColumnIndex(column); return entries.get(computeKey(row, column)); } /** {@inheritDoc} */ @Override public int getRowDimension() { return rows; } /** {@inheritDoc} */ @Override public void multiplyEntry(int row, int column, T factor) throws MatrixIndexException { checkRowIndex(row); checkColumnIndex(column); final int key = computeKey(row, column); final T value = entries.get(key).multiply(factor); if (getField().getZero().equals(value)) { entries.remove(key); } else { entries.put(key, value); } } /** {@inheritDoc} */ @Override public void setEntry(int row, int column, T value) throws MatrixIndexException { checkRowIndex(row); checkColumnIndex(column); if (getField().getZero().equals(value)) { entries.remove(computeKey(row, column)); } else { entries.put(computeKey(row, column), value); } } /** * Compute the key to access a matrix element * @param row row index of the matrix element * @param column column index of the matrix element * @return key within the map to access the matrix element */ private int computeKey(int row, int column) { return row * columns + column; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/TriDiagonalTransformer.java100644 1750 1750 22603 11532241245 31124 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import org.apache.commons.math.util.FastMath; /** * Class transforming a symmetrical matrix to tridiagonal shape. *

                    A symmetrical m × m matrix A can be written as the product of three matrices: * A = Q × T × QT with Q an orthogonal matrix and T a symmetrical * tridiagonal matrix. Both Q and T are m × m matrices.

                    *

                    This implementation only uses the upper part of the matrix, the part below the * diagonal is not accessed at all.

                    *

                    Transformation to tridiagonal shape is often not a goal by itself, but it is * an intermediate step in more general decomposition algorithms like {@link * EigenDecomposition eigen decomposition}. This class is therefore intended for internal * use by the library and is not public. As a consequence of this explicitly limited scope, * many methods directly returns references to internal arrays, not copies.

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ class TriDiagonalTransformer { /** Householder vectors. */ private final double householderVectors[][]; /** Main diagonal. */ private final double[] main; /** Secondary diagonal. */ private final double[] secondary; /** Cached value of Q. */ private RealMatrix cachedQ; /** Cached value of Qt. */ private RealMatrix cachedQt; /** Cached value of T. */ private RealMatrix cachedT; /** * Build the transformation to tridiagonal shape of a symmetrical matrix. *

                    The specified matrix is assumed to be symmetrical without any check. * Only the upper triangular part of the matrix is used.

                    * @param matrix the symmetrical matrix to transform. * @exception InvalidMatrixException if matrix is not square */ public TriDiagonalTransformer(RealMatrix matrix) throws InvalidMatrixException { if (!matrix.isSquare()) { throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); } final int m = matrix.getRowDimension(); householderVectors = matrix.getData(); main = new double[m]; secondary = new double[m - 1]; cachedQ = null; cachedQt = null; cachedT = null; // transform matrix transform(); } /** * Returns the matrix Q of the transform. *

                    Q is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the Q matrix */ public RealMatrix getQ() { if (cachedQ == null) { cachedQ = getQT().transpose(); } return cachedQ; } /** * Returns the transpose of the matrix Q of the transform. *

                    Q is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the Q matrix */ public RealMatrix getQT() { if (cachedQt == null) { final int m = householderVectors.length; cachedQt = MatrixUtils.createRealMatrix(m, m); // build up first part of the matrix by applying Householder transforms for (int k = m - 1; k >= 1; --k) { final double[] hK = householderVectors[k - 1]; final double inv = 1.0 / (secondary[k - 1] * hK[k]); cachedQt.setEntry(k, k, 1); if (hK[k] != 0.0) { double beta = 1.0 / secondary[k - 1]; cachedQt.setEntry(k, k, 1 + beta * hK[k]); for (int i = k + 1; i < m; ++i) { cachedQt.setEntry(k, i, beta * hK[i]); } for (int j = k + 1; j < m; ++j) { beta = 0; for (int i = k + 1; i < m; ++i) { beta += cachedQt.getEntry(j, i) * hK[i]; } beta *= inv; cachedQt.setEntry(j, k, beta * hK[k]); for (int i = k + 1; i < m; ++i) { cachedQt.addToEntry(j, i, beta * hK[i]); } } } } cachedQt.setEntry(0, 0, 1); } // return the cached matrix return cachedQt; } /** * Returns the tridiagonal matrix T of the transform. * @return the T matrix */ public RealMatrix getT() { if (cachedT == null) { final int m = main.length; cachedT = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < m; ++i) { cachedT.setEntry(i, i, main[i]); if (i > 0) { cachedT.setEntry(i, i - 1, secondary[i - 1]); } if (i < main.length - 1) { cachedT.setEntry(i, i + 1, secondary[i]); } } } // return the cached matrix return cachedT; } /** * Get the Householder vectors of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the main diagonal elements of the B matrix */ double[][] getHouseholderVectorsRef() { return householderVectors; } /** * Get the main diagonal elements of the matrix T of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the main diagonal elements of the T matrix */ double[] getMainDiagonalRef() { return main; } /** * Get the secondary diagonal elements of the matrix T of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the secondary diagonal elements of the T matrix */ double[] getSecondaryDiagonalRef() { return secondary; } /** * Transform original matrix to tridiagonal form. *

                    Transformation is done using Householder transforms.

                    */ private void transform() { final int m = householderVectors.length; final double[] z = new double[m]; for (int k = 0; k < m - 1; k++) { //zero-out a row and a column simultaneously final double[] hK = householderVectors[k]; main[k] = hK[k]; double xNormSqr = 0; for (int j = k + 1; j < m; ++j) { final double c = hK[j]; xNormSqr += c * c; } final double a = (hK[k + 1] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); secondary[k] = a; if (a != 0.0) { // apply Householder transform from left and right simultaneously hK[k + 1] -= a; final double beta = -1 / (a * hK[k + 1]); // compute a = beta A v, where v is the Householder vector // this loop is written in such a way // 1) only the upper triangular part of the matrix is accessed // 2) access is cache-friendly for a matrix stored in rows Arrays.fill(z, k + 1, m, 0); for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; final double hKI = hK[i]; double zI = hI[i] * hKI; for (int j = i + 1; j < m; ++j) { final double hIJ = hI[j]; zI += hIJ * hK[j]; z[j] += hIJ * hKI; } z[i] = beta * (z[i] + zI); } // compute gamma = beta vT z / 2 double gamma = 0; for (int i = k + 1; i < m; ++i) { gamma += z[i] * hK[i]; } gamma *= beta / 2; // compute z = z - gamma v for (int i = k + 1; i < m; ++i) { z[i] -= gamma * hK[i]; } // update matrix: A = A - v zT - z vT // only the upper triangular part of the matrix is updated for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; for (int j = i; j < m; ++j) { hI[j] -= hK[i] * z[j] + z[i] * hK[j]; } } } } main[m - 1] = householderVectors[m - 1][m - 1]; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/Array2DRowFieldMatrix.java100644 1750 1750 53445 11532241245 30601 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implementation of FieldMatrix using a {@link FieldElement}[][] array to store entries. *

                    * As specified in the {@link FieldMatrix} interface, matrix element indexing * is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix. *

                    * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class Array2DRowFieldMatrix> extends AbstractFieldMatrix implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 7260756672015356458L; /** Entries of the matrix */ protected T[][] data; /** * Creates a matrix with no data * @param field field to which the elements belong */ public Array2DRowFieldMatrix(final Field field) { super(field); } /** * Create a new FieldMatrix with the supplied row and column dimensions. * * @param field field to which the elements belong * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public Array2DRowFieldMatrix(final Field field, final int rowDimension, final int columnDimension) throws IllegalArgumentException { super(field, rowDimension, columnDimension); data = buildArray(field, rowDimension, columnDimension); } /** * Create a new FieldMatrix using the input array as the underlying * data array. *

                    The input array is copied, not referenced. This constructor has * the same effect as calling {@link #Array2DRowFieldMatrix(FieldElement[][], boolean)} * with the second argument set to true.

                    * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #Array2DRowFieldMatrix(FieldElement[][], boolean) */ public Array2DRowFieldMatrix(final T[][] d) throws IllegalArgumentException, NullPointerException { super(extractField(d)); copyIn(d); } /** * Create a new FieldMatrix using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * FieldMatrix and not used directly, the copyArray may be * set to false * @param d data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #Array2DRowFieldMatrix(FieldElement[][]) */ public Array2DRowFieldMatrix(final T[][] d, final boolean copyArray) throws IllegalArgumentException, NullPointerException { super(extractField(d)); if (copyArray) { copyIn(d); } else { if (d == null) { throw new NullPointerException(); } final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; r++) { if (d[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length); } } data = d; } } /** * Create a new (column) FieldMatrix using v as the * data for the unique column of the v.length x 1 matrix * created. *

                    The input array is copied, not referenced.

                    * * @param v column vector holding data for new matrix */ public Array2DRowFieldMatrix(final T[] v) { super(extractField(v)); final int nRows = v.length; data = buildArray(getField(), nRows, 1); for (int row = 0; row < nRows; row++) { data[row][0] = v[row]; } } /** {@inheritDoc} */ @Override public FieldMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { return new Array2DRowFieldMatrix(getField(), rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public FieldMatrix copy() { return new Array2DRowFieldMatrix(copyOut(), false); } /** {@inheritDoc} */ @Override public FieldMatrix add(final FieldMatrix m) throws IllegalArgumentException { try { return add((Array2DRowFieldMatrix) m); } catch (ClassCastException cce) { return super.add(m); } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public Array2DRowFieldMatrix add(final Array2DRowFieldMatrix m) throws IllegalArgumentException { // safety check checkAdditionCompatible(m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final T[][] outData = buildArray(getField(), rowCount, columnCount); for (int row = 0; row < rowCount; row++) { final T[] dataRow = data[row]; final T[] mRow = m.data[row]; final T[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].add(mRow[col]); } } return new Array2DRowFieldMatrix(outData, false); } /** {@inheritDoc} */ @Override public FieldMatrix subtract(final FieldMatrix m) throws IllegalArgumentException { try { return subtract((Array2DRowFieldMatrix) m); } catch (ClassCastException cce) { return super.subtract(m); } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public Array2DRowFieldMatrix subtract(final Array2DRowFieldMatrix m) throws IllegalArgumentException { // safety check checkSubtractionCompatible(m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final T[][] outData = buildArray(getField(), rowCount, columnCount); for (int row = 0; row < rowCount; row++) { final T[] dataRow = data[row]; final T[] mRow = m.data[row]; final T[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col].subtract(mRow[col]); } } return new Array2DRowFieldMatrix(outData, false); } /** {@inheritDoc} */ @Override public FieldMatrix multiply(final FieldMatrix m) throws IllegalArgumentException { try { return multiply((Array2DRowFieldMatrix) m); } catch (ClassCastException cce) { return super.multiply(m); } } /** * Returns the result of postmultiplying this by m. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public Array2DRowFieldMatrix multiply(final Array2DRowFieldMatrix m) throws IllegalArgumentException { // safety check checkMultiplicationCompatible(m); final int nRows = this.getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = this.getColumnDimension(); final T[][] outData = buildArray(getField(), nRows, nCols); for (int row = 0; row < nRows; row++) { final T[] dataRow = data[row]; final T[] outDataRow = outData[row]; for (int col = 0; col < nCols; col++) { T sum = getField().getZero(); for (int i = 0; i < nSum; i++) { sum = sum.add(dataRow[i].multiply(m.data[i][col])); } outDataRow[col] = sum; } } return new Array2DRowFieldMatrix(outData, false); } /** {@inheritDoc} */ @Override public T[][] getData() { return copyOut(); } /** * Returns a reference to the underlying data array. *

                    * Does not make a fresh copy of the underlying data.

                    * * @return 2-dimensional array of entries */ public T[][] getDataRef() { return data; } /** {@inheritDoc} */ @Override public void setSubMatrix(final T[][] subMatrix, final int row, final int column) throws MatrixIndexException { if (data == null) { if (row > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row); } if (column > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column); } final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_COLUMN); } data = buildArray(getField(), subMatrix.length, nCols); for (int i = 0; i < data.length; ++i) { if (subMatrix[i].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[i].length); } System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); } } else { super.setSubMatrix(subMatrix, row, column); } } /** {@inheritDoc} */ @Override public T getEntry(final int row, final int column) throws MatrixIndexException { try { return data[row][column]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void setEntry(final int row, final int column, final T value) throws MatrixIndexException { try { data[row][column] = value; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void addToEntry(final int row, final int column, final T increment) throws MatrixIndexException { try { data[row][column] = data[row][column].add(increment); } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void multiplyEntry(final int row, final int column, final T factor) throws MatrixIndexException { try { data[row][column] = data[row][column].multiply(factor); } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public int getRowDimension() { return (data == null) ? 0 : data.length; } /** {@inheritDoc} */ @Override public int getColumnDimension() { return ((data == null) || (data[0] == null)) ? 0 : data[0].length; } /** {@inheritDoc} */ @Override public T[] operate(final T[] v) throws IllegalArgumentException { final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); if (v.length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols); } final T[] out = buildArray(getField(), nRows); for (int row = 0; row < nRows; row++) { final T[] dataRow = data[row]; T sum = getField().getZero(); for (int i = 0; i < nCols; i++) { sum = sum.add(dataRow[i].multiply(v[i])); } out[row] = sum; } return out; } /** {@inheritDoc} */ @Override public T[] preMultiply(final T[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows); } final T[] out = buildArray(getField(), nCols); for (int col = 0; col < nCols; ++col) { T sum = getField().getZero(); for (int i = 0; i < nRows; ++i) { sum = sum.add(data[i][col].multiply(v[i])); } out[col] = sum; } return out; } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final T[] rowI = data[i]; for (int j = 0; j < columns; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final T[] rowI = data[i]; for (int j = 0; j < columns; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final T[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final T[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInColumnOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { final T[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInColumnOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInColumnOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { final T[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInColumnOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** * Returns a fresh copy of the underlying data array. * * @return a copy of the underlying data array. */ private T[][] copyOut() { final int nRows = this.getRowDimension(); final T[][] out = buildArray(getField(), nRows, getColumnDimension()); // can't copy 2-d array in one shot, otherwise get row references for (int i = 0; i < nRows; i++) { System.arraycopy(data[i], 0, out[i], 0, data[i].length); } return out; } /** * Replaces data with a fresh copy of the input array. *

                    * Verifies that the input array is rectangular and non-empty.

                    * * @param in data to copy in * @throws IllegalArgumentException if input array is empty or not * rectangular * @throws NullPointerException if input array is null */ private void copyIn(final T[][] in) { setSubMatrix(in, 0, 0); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealMatrixPreservingVisitor.java100644 1750 1750 4342 11532241245 32161 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining a visitor for matrix entries. * * @see DefaultRealMatrixPreservingVisitor * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface RealMatrixPreservingVisitor { /** * Start visiting a matrix. *

                    This method is called once before any entry of the matrix is visited.

                    * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) */ void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn); /** * Visit one matrix entry. * @param row row index of the entry * @param column column index of the entry * @param value current value of the entry * @throws MatrixVisitorException if something wrong occurs */ void visit(int row, int column, double value) throws MatrixVisitorException; /** * End visiting a matrix. *

                    This method is called once after all entries of the matrix have been visited.

                    * @return the value that the walkInXxxOrder must return */ double end(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldLUDecomposition.java100644 1750 1750 7243 11532241245 30510 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; /** * An interface to classes that implement an algorithm to calculate the * LU-decomposition of a real matrix. *

                    The LU-decomposition of matrix A is a set of three matrices: P, L and U * such that P×A = L×U. P is a rows permutation matrix that is used * to rearrange the rows of A before so that it can be decomposed. L is a lower * triangular matrix with unit diagonal terms and U is an upper triangular matrix.

                    *

                    This interface is based on the class with similar name from the * JAMA library.

                    *
                      *
                    • a {@link #getP() getP} method has been added,
                    • *
                    • the det method has been renamed as {@link #getDeterminant() * getDeterminant},
                    • *
                    • the getDoublePivot method has been removed (but the int based * {@link #getPivot() getPivot} method has been kept),
                    • *
                    • the solve and isNonSingular methods have been replaced * by a {@link #getSolver() getSolver} method and the equivalent methods provided by * the returned {@link DecompositionSolver}.
                    • *
                    * * @param the type of the field elements * @see MathWorld * @see Wikipedia * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $ * @since 2.0 */ public interface FieldLUDecomposition> { /** * Returns the matrix L of the decomposition. *

                    L is an lower-triangular matrix

                    * @return the L matrix (or null if decomposed matrix is singular) */ FieldMatrix getL(); /** * Returns the matrix U of the decomposition. *

                    U is an upper-triangular matrix

                    * @return the U matrix (or null if decomposed matrix is singular) */ FieldMatrix getU(); /** * Returns the P rows permutation matrix. *

                    P is a sparse matrix with exactly one element set to 1.0 in * each row and each column, all other elements being set to 0.0.

                    *

                    The positions of the 1 elements are given by the {@link #getPivot() * pivot permutation vector}.

                    * @return the P rows permutation matrix (or null if decomposed matrix is singular) * @see #getPivot() */ FieldMatrix getP(); /** * Returns the pivot permutation vector. * @return the pivot permutation vector * @see #getP() */ int[] getPivot(); /** * Return the determinant of the matrix * @return determinant of the matrix */ T getDeterminant(); /** * Get a solver for finding the A × X = B solution in exact linear sense. * @return a solver */ FieldDecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SingularValueDecomposition.java100644 1750 1750 13331 11532241245 32020 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * An interface to classes that implement an algorithm to calculate the * Singular Value Decomposition of a real matrix. *

                    * The Singular Value Decomposition of matrix A is a set of three matrices: U, * Σ and V such that A = U × Σ × VT. Let A be * a m × n matrix, then U is a m × p orthogonal matrix, Σ is a * p × p diagonal matrix with positive or null elements, V is a p × * n orthogonal matrix (hence VT is also orthogonal) where * p=min(m,n). *

                    *

                    This interface is similar to the class with similar name from the * JAMA library, with the * following changes:

                    *
                      *
                    • the norm2 method which has been renamed as {@link #getNorm() * getNorm},
                    • *
                    • the cond method which has been renamed as {@link * #getConditionNumber() getConditionNumber},
                    • *
                    • the rank method which has been renamed as {@link #getRank() * getRank},
                    • *
                    • a {@link #getUT() getUT} method has been added,
                    • *
                    • a {@link #getVT() getVT} method has been added,
                    • *
                    • a {@link #getSolver() getSolver} method has been added,
                    • *
                    • a {@link #getCovariance(double) getCovariance} method has been added.
                    • *
                    * @see MathWorld * @see Wikipedia * @version $Revision: 928081 $ $Date: 2010-03-26 23:36:38 +0100 (ven. 26 mars 2010) $ * @since 2.0 */ public interface SingularValueDecomposition { /** * Returns the matrix U of the decomposition. *

                    U is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the U matrix * @see #getUT() */ RealMatrix getU(); /** * Returns the transpose of the matrix U of the decomposition. *

                    U is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the U matrix (or null if decomposed matrix is singular) * @see #getU() */ RealMatrix getUT(); /** * Returns the diagonal matrix Σ of the decomposition. *

                    Σ is a diagonal matrix. The singular values are provided in * non-increasing order, for compatibility with Jama.

                    * @return the Σ matrix */ RealMatrix getS(); /** * Returns the diagonal elements of the matrix Σ of the decomposition. *

                    The singular values are provided in non-increasing order, for * compatibility with Jama.

                    * @return the diagonal elements of the Σ matrix */ double[] getSingularValues(); /** * Returns the matrix V of the decomposition. *

                    V is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the V matrix (or null if decomposed matrix is singular) * @see #getVT() */ RealMatrix getV(); /** * Returns the transpose of the matrix V of the decomposition. *

                    V is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the V matrix (or null if decomposed matrix is singular) * @see #getV() */ RealMatrix getVT(); /** * Returns the n × n covariance matrix. *

                    The covariance matrix is V × J × VT * where J is the diagonal matrix of the inverse of the squares of * the singular values.

                    * @param minSingularValue value below which singular values are ignored * (a 0 or negative value implies all singular value will be used) * @return covariance matrix * @exception IllegalArgumentException if minSingularValue is larger than * the largest singular value, meaning all singular values are ignored */ RealMatrix getCovariance(double minSingularValue) throws IllegalArgumentException; /** * Returns the L2 norm of the matrix. *

                    The L2 norm is max(|A × u|2 / * |u|2), where |.|2 denotes the vectorial 2-norm * (i.e. the traditional euclidian norm).

                    * @return norm */ double getNorm(); /** * Return the condition number of the matrix. * @return condition number of the matrix */ double getConditionNumber(); /** * Return the effective numerical matrix rank. *

                    The effective numerical rank is the number of non-negligible * singular values. The threshold used to identify non-negligible * terms is max(m,n) × ulp(s1) where ulp(s1) * is the least significant bit of the largest singular value.

                    * @return effective numerical matrix rank */ int getRank(); /** * Get a solver for finding the A × X = B solution in least square sense. * @return a solver */ DecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/InvalidMatrixException.java100644 1750 1750 4627 11532241245 31124 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * Thrown when a system attempts an operation on a matrix, and * that matrix does not satisfy the preconditions for the * aforementioned operation. * @version $Revision: 1073253 $ $Date: 2011-02-22 09:40:05 +0100 (mar. 22 févr. 2011) $ */ public class InvalidMatrixException extends MathRuntimeException { /** Serializable version identifier. */ private static final long serialVersionUID = -2068020346562029801L; /** * Construct an exception with the given message. * @param pattern format specifier * @param arguments format arguments * @since 2.0 * @deprecated since 2.2 replaced by {@link #InvalidMatrixException(Localizable, Object...)} */ @Deprecated public InvalidMatrixException(final String pattern, final Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Construct an exception with the given message. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public InvalidMatrixException(final Localizable pattern, final Object ... arguments) { super(pattern, arguments); } /** * Construct an exception with the given message. * @param cause the exception or error that caused this exception * to be thrown. * @since 2.0 */ public InvalidMatrixException(final Throwable cause) { super(cause); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java100644 1750 1750 71166 11532241245 30042 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.OpenIntToDoubleHashMap; import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator; import org.apache.commons.math.util.FastMath; /** * This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store. * @version $Revision: 1073262 $ $Date: 2011-02-22 10:02:25 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public class OpenMapRealVector extends AbstractRealVector implements SparseRealVector, Serializable { /** Default Tolerance for having a value considered zero. */ public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12; /** Serializable version identifier. */ private static final long serialVersionUID = 8772222695580707260L; /** Entries of the vector. */ private final OpenIntToDoubleHashMap entries; /** Dimension of the vector. */ private final int virtualSize; /** Tolerance for having a value considered zero. */ private final double epsilon; /** * Build a 0-length vector. *

                    Zero-length vectors may be used to initialized construction of vectors * by data gathering. We start with zero-length and use either the {@link * #OpenMapRealVector(OpenMapRealVector, int)} constructor * or one of the append method ({@link #append(double)}, {@link * #append(double[])}, {@link #append(RealVector)}) to gather data * into this vector.

                    */ public OpenMapRealVector() { this(0, DEFAULT_ZERO_TOLERANCE); } /** * Construct a (dimension)-length vector of zeros. * @param dimension size of the vector */ public OpenMapRealVector(int dimension) { this(dimension, DEFAULT_ZERO_TOLERANCE); } /** * Construct a (dimension)-length vector of zeros, specifying zero tolerance. * @param dimension Size of the vector * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(int dimension, double epsilon) { virtualSize = dimension; entries = new OpenIntToDoubleHashMap(0.0); this.epsilon = epsilon; } /** * Build a resized vector, for use with append. * @param v The original vector * @param resize The amount to resize it */ protected OpenMapRealVector(OpenMapRealVector v, int resize) { virtualSize = v.getDimension() + resize; entries = new OpenIntToDoubleHashMap(v.entries); epsilon = v.epsilon; } /** * Build a vector with known the sparseness (for advanced use only). * @param dimension The size of the vector * @param expectedSize The expected number of non-zero entries */ public OpenMapRealVector(int dimension, int expectedSize) { this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE); } /** * Build a vector with known the sparseness and zero tolerance setting (for advanced use only). * @param dimension The size of the vector * @param expectedSize The expected number of non-zero entries * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(int dimension, int expectedSize, double epsilon) { virtualSize = dimension; entries = new OpenIntToDoubleHashMap(expectedSize, 0.0); this.epsilon = epsilon; } /** * Create from a double array. * Only non-zero entries will be stored * @param values The set of values to create from */ public OpenMapRealVector(double[] values) { this(values, DEFAULT_ZERO_TOLERANCE); } /** * Create from a double array, specifying zero tolerance. * Only non-zero entries will be stored * @param values The set of values to create from * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(double[] values, double epsilon) { virtualSize = values.length; entries = new OpenIntToDoubleHashMap(0.0); this.epsilon = epsilon; for (int key = 0; key < values.length; key++) { double value = values[key]; if (!isDefaultValue(value)) { entries.put(key, value); } } } /** * Create from a Double array. * Only non-zero entries will be stored * @param values The set of values to create from */ public OpenMapRealVector(Double[] values) { this(values, DEFAULT_ZERO_TOLERANCE); } /** * Create from a Double array. * Only non-zero entries will be stored * @param values The set of values to create from * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(Double[] values, double epsilon) { virtualSize = values.length; entries = new OpenIntToDoubleHashMap(0.0); this.epsilon = epsilon; for (int key = 0; key < values.length; key++) { double value = values[key].doubleValue(); if (!isDefaultValue(value)) { entries.put(key, value); } } } /** * Copy constructor. * @param v The instance to copy from */ public OpenMapRealVector(OpenMapRealVector v) { virtualSize = v.getDimension(); entries = new OpenIntToDoubleHashMap(v.getEntries()); epsilon = v.epsilon; } /** * Generic copy constructor. * @param v The instance to copy from */ public OpenMapRealVector(RealVector v) { virtualSize = v.getDimension(); entries = new OpenIntToDoubleHashMap(0.0); epsilon = DEFAULT_ZERO_TOLERANCE; for (int key = 0; key < virtualSize; key++) { double value = v.getEntry(key); if (!isDefaultValue(value)) { entries.put(key, value); } } } /** * Get the entries of this instance. * @return entries of this instance */ private OpenIntToDoubleHashMap getEntries() { return entries; } /** * Determine if this value is within epsilon of zero. * @param value The value to test * @return true if this value is within epsilon to zero, false otherwise * @since 2.1 */ protected boolean isDefaultValue(double value) { return FastMath.abs(value) < epsilon; } /** {@inheritDoc} */ @Override public RealVector add(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); if (v instanceof OpenMapRealVector) { return add((OpenMapRealVector) v); } else { return super.add(v); } } /** * Optimized method to add two OpenMapRealVectors. Copies the larger vector, iterates over the smaller. * @param v Vector to add with * @return The sum of this with v * @throws IllegalArgumentException If the dimensions don't match */ public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{ checkVectorDimensions(v.getDimension()); boolean copyThis = entries.size() > v.entries.size(); OpenMapRealVector res = copyThis ? this.copy() : v.copy(); Iterator iter = copyThis ? v.entries.iterator() : entries.iterator(); OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries; while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (randomAccess.containsKey(key)) { res.setEntry(key, randomAccess.get(key) + iter.value()); } else { res.setEntry(key, iter.value()); } } return res; } /** * Optimized method to append a OpenMapRealVector. * @param v vector to append * @return The result of appending v to self */ public OpenMapRealVector append(OpenMapRealVector v) { OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension()); Iterator iter = v.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key() + virtualSize, iter.value()); } return res; } /** {@inheritDoc} */ public OpenMapRealVector append(RealVector v) { if (v instanceof OpenMapRealVector) { return append((OpenMapRealVector) v); } return append(v.getData()); } /** {@inheritDoc} */ public OpenMapRealVector append(double d) { OpenMapRealVector res = new OpenMapRealVector(this, 1); res.setEntry(virtualSize, d); return res; } /** {@inheritDoc} */ public OpenMapRealVector append(double[] a) { OpenMapRealVector res = new OpenMapRealVector(this, a.length); for (int i = 0; i < a.length; i++) { res.setEntry(i + virtualSize, a[i]); } return res; } /** * {@inheritDoc} * @since 2.1 */ @Override public OpenMapRealVector copy() { return new OpenMapRealVector(this); } /** * Optimized method to compute the dot product with an OpenMapRealVector. * Iterates over the smaller of the two. * @param v The vector to compute the dot product with * @return The dot product of this and v * @throws IllegalArgumentException If the dimensions don't match */ public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); boolean thisIsSmaller = entries.size() < v.entries.size(); Iterator iter = thisIsSmaller ? entries.iterator() : v.entries.iterator(); OpenIntToDoubleHashMap larger = thisIsSmaller ? v.entries : entries; double d = 0; while(iter.hasNext()) { iter.advance(); d += iter.value() * larger.get(iter.key()); } return d; } /** {@inheritDoc} */ @Override public double dotProduct(RealVector v) throws IllegalArgumentException { if(v instanceof OpenMapRealVector) { return dotProduct((OpenMapRealVector)v); } else { return super.dotProduct(v); } } /** {@inheritDoc} */ public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); OpenMapRealVector res = new OpenMapRealVector(this); Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key())); } return res; } /** {@inheritDoc} */ @Override public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); OpenMapRealVector res = new OpenMapRealVector(this); Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value() / v[iter.key()]); } return res; } /** {@inheritDoc} */ public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); OpenMapRealVector res = new OpenMapRealVector(this); Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key())); } return res; } /** {@inheritDoc} */ @Override public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); OpenMapRealVector res = new OpenMapRealVector(this); Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value() * v[iter.key()]); } return res; } /** {@inheritDoc} */ public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException { checkIndex(index); checkIndex(index + n - 1); OpenMapRealVector res = new OpenMapRealVector(n); int end = index + n; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (key >= index && key < end) { res.setEntry(key - index, iter.value()); } } return res; } /** {@inheritDoc} */ @Override public double[] getData() { double[] res = new double[virtualSize]; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); res[iter.key()] = iter.value(); } return res; } /** {@inheritDoc} */ public int getDimension() { return virtualSize; } /** * Optimized method to compute distance. * @param v The vector to compute distance to * @return The distance from this and v * @throws IllegalArgumentException If the dimensions don't match */ public double getDistance(OpenMapRealVector v) throws IllegalArgumentException { Iterator iter = entries.iterator(); double res = 0; while (iter.hasNext()) { iter.advance(); int key = iter.key(); double delta; delta = iter.value() - v.getEntry(key); res += delta * delta; } iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (!entries.containsKey(key)) { final double value = iter.value(); res += value * value; } } return FastMath.sqrt(res); } /** {@inheritDoc} */ @Override public double getDistance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); if (v instanceof OpenMapRealVector) { return getDistance((OpenMapRealVector) v); } return getDistance(v.getData()); } /** {@inheritDoc} */ @Override public double getDistance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double res = 0; for (int i = 0; i < v.length; i++) { double delta = entries.get(i) - v[i]; res += delta * delta; } return FastMath.sqrt(res); } /** {@inheritDoc} */ public double getEntry(int index) throws MatrixIndexException { checkIndex(index); return entries.get(index); } /** * Distance between two vectors. *

                    This method computes the distance consistent with * L1 norm, i.e. the sum of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. */ public double getL1Distance(OpenMapRealVector v) { double max = 0; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); double delta = FastMath.abs(iter.value() - v.getEntry(iter.key())); max += delta; } iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (!entries.containsKey(key)) { double delta = FastMath.abs(iter.value()); max += FastMath.abs(delta); } } return max; } /** {@inheritDoc} */ @Override public double getL1Distance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); if (v instanceof OpenMapRealVector) { return getL1Distance((OpenMapRealVector) v); } return getL1Distance(v.getData()); } /** {@inheritDoc} */ @Override public double getL1Distance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double max = 0; for (int i = 0; i < v.length; i++) { double delta = FastMath.abs(getEntry(i) - v[i]); max += delta; } return max; } /** * Optimized method to compute LInfDistance. * @param v The vector to compute from * @return the LInfDistance */ private double getLInfDistance(OpenMapRealVector v) { double max = 0; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); double delta = FastMath.abs(iter.value() - v.getEntry(iter.key())); if (delta > max) { max = delta; } } iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (!entries.containsKey(key)) { if (iter.value() > max) { max = iter.value(); } } } return max; } /** {@inheritDoc} */ @Override public double getLInfDistance(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); if (v instanceof OpenMapRealVector) { return getLInfDistance((OpenMapRealVector) v); } return getLInfDistance(v.getData()); } /** {@inheritDoc} */ @Override public double getLInfDistance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double max = 0; for (int i = 0; i < v.length; i++) { double delta = FastMath.abs(getEntry(i) - v[i]); if (delta > max) { max = delta; } } return max; } /** {@inheritDoc} */ public boolean isInfinite() { boolean infiniteFound = false; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); final double value = iter.value(); if (Double.isNaN(value)) { return false; } if (Double.isInfinite(value)) { infiniteFound = true; } } return infiniteFound; } /** {@inheritDoc} */ public boolean isNaN() { Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); if (Double.isNaN(iter.value())) { return true; } } return false; } /** {@inheritDoc} */ @Override public OpenMapRealVector mapAdd(double d) { return copy().mapAddToSelf(d); } /** {@inheritDoc} */ @Override public OpenMapRealVector mapAddToSelf(double d) { for (int i = 0; i < virtualSize; i++) { setEntry(i, getEntry(i) + d); } return this; } /** {@inheritDoc} */ @Override public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize); Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); int row = iter.key(); double value = iter.value(); for (int col = 0; col < virtualSize; col++) { res.setEntry(row, col, value * v[col]); } } return res; } /** {@inheritDoc} */ public RealVector projection(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); } /** {@inheritDoc} */ @Override public OpenMapRealVector projection(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); return (OpenMapRealVector) projection(new OpenMapRealVector(v)); } /** {@inheritDoc} */ public void setEntry(int index, double value) throws MatrixIndexException { checkIndex(index); if (!isDefaultValue(value)) { entries.put(index, value); } else if (entries.containsKey(index)) { entries.remove(index); } } /** {@inheritDoc} */ @Override public void setSubVector(int index, RealVector v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.getDimension() - 1); setSubVector(index, v.getData()); } /** {@inheritDoc} */ @Override public void setSubVector(int index, double[] v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.length - 1); for (int i = 0; i < v.length; i++) { setEntry(i + index, v[i]); } } /** {@inheritDoc} */ @Override public void set(double value) { for (int i = 0; i < virtualSize; i++) { setEntry(i, value); } } /** * Optimized method to subtract OpenMapRealVectors. * @param v The vector to subtract from this * @return The difference of this and v * @throws IllegalArgumentException If the dimensions don't match */ public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{ checkVectorDimensions(v.getDimension()); OpenMapRealVector res = copy(); Iterator iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (entries.containsKey(key)) { res.setEntry(key, entries.get(key) - iter.value()); } else { res.setEntry(key, -iter.value()); } } return res; } /** {@inheritDoc} */ @Override public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); if (v instanceof OpenMapRealVector) { return subtract((OpenMapRealVector) v); } return subtract(v.getData()); } /** {@inheritDoc} */ @Override public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); OpenMapRealVector res = new OpenMapRealVector(this); for (int i = 0; i < v.length; i++) { if (entries.containsKey(i)) { res.setEntry(i, entries.get(i) - v[i]); } else { res.setEntry(i, -v[i]); } } return res; } /** {@inheritDoc} */ @Override public OpenMapRealVector unitVector() { OpenMapRealVector res = copy(); res.unitize(); return res; } /** {@inheritDoc} */ @Override public void unitize() { double norm = getNorm(); if (isDefaultValue(norm)) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR); } Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); entries.put(iter.key(), iter.value() / norm); } } /** {@inheritDoc} */ @Override public double[] toArray() { return getData(); } /** {@inheritDoc} *

                    Implementation Note: This works on exact values, and as a result * it is possible for {@code a.subtract(b)} to be the zero vector, while * {@code a.hashCode() != b.hashCode()}.

                    */ @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(epsilon); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + virtualSize; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); temp = Double.doubleToLongBits(iter.value()); result = prime * result + (int) (temp ^ (temp >>32)); } return result; } /** *

                    Implementation Note: This performs an exact comparison, and as a result * it is possible for {@code a.subtract(b}} to be the zero vector, while * {@code a.equals(b) == false}.

                    * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof OpenMapRealVector)) { return false; } OpenMapRealVector other = (OpenMapRealVector) obj; if (virtualSize != other.virtualSize) { return false; } if (Double.doubleToLongBits(epsilon) != Double.doubleToLongBits(other.epsilon)) { return false; } Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); double test = other.getEntry(iter.key()); if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) { return false; } } iter = other.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); double test = iter.value(); if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) { return false; } } return true; } /** * * @return the percentage of none zero elements as a decimal percent. * @deprecated as of 2.2 replaced by the correctly spelled {@link #getSparsity()} */ @Deprecated public double getSparcity() { return getSparsity(); } /** * * @return the percentage of none zero elements as a decimal percent. * @since 2.2 */ public double getSparsity() { return (double)entries.size()/(double)getDimension(); } /** {@inheritDoc} */ @Override public java.util.Iterator sparseIterator() { return new OpenMapSparseIterator(); } /** * Implementation of Entry optimized for OpenMap. *

                    This implementation does not allow arbitrary calls to setIndex * since the order that entries are returned is undefined. */ protected class OpenMapEntry extends Entry { /** Iterator pointing to the entry. */ private final Iterator iter; /** Build an entry from an iterator point to an element. * @param iter iterator pointing to the entry */ protected OpenMapEntry(Iterator iter) { this.iter = iter; } /** {@inheritDoc} */ @Override public double getValue() { return iter.value(); } /** {@inheritDoc} */ @Override public void setValue(double value) { entries.put(iter.key(), value); } /** {@inheritDoc} */ @Override public int getIndex() { return iter.key(); } } /** * Iterator class to do iteration over just the non-zero elements. *

                    This implementation is fail-fast, so cannot be used to modify any zero element. * */ protected class OpenMapSparseIterator implements java.util.Iterator { /** Underlying iterator. */ private final Iterator iter; /** Current entry. */ private final Entry current; /** Simple constructor. */ protected OpenMapSparseIterator() { iter = entries.iterator(); current = new OpenMapEntry(iter); } /** {@inheritDoc} */ public boolean hasNext() { return iter.hasNext(); } /** {@inheritDoc} */ public Entry next() { iter.advance(); return current; } /** {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException("Not supported"); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/QRDecomposition.java100644 1750 1750 5252 11532241245 27544 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * An interface to classes that implement an algorithm to calculate the * QR-decomposition of a real matrix. *

                    This interface is based on the class with similar name from the * JAMA library, with the * following changes:

                    *
                      *
                    • a {@link #getQT() getQT} method has been added,
                    • *
                    • the solve and isFullRank methods have been replaced * by a {@link #getSolver() getSolver} method and the equivalent methods provided by * the returned {@link DecompositionSolver}.
                    • *
                    * * @see MathWorld * @see Wikipedia * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $ * @since 1.2 */ public interface QRDecomposition { /** * Returns the matrix R of the decomposition. *

                    R is an upper-triangular matrix

                    * @return the R matrix */ RealMatrix getR(); /** * Returns the matrix Q of the decomposition. *

                    Q is an orthogonal matrix

                    * @return the Q matrix */ RealMatrix getQ(); /** * Returns the transpose of the matrix Q of the decomposition. *

                    Q is an orthogonal matrix

                    * @return the Q matrix */ RealMatrix getQT(); /** * Returns the Householder reflector vectors. *

                    H is a lower trapezoidal matrix whose columns represent * each successive Householder reflector vector. This matrix is used * to compute Q.

                    * @return a matrix containing the Householder reflector vectors */ RealMatrix getH(); /** * Get a solver for finding the A × X = B solution in least square sense. * @return a solver */ DecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/EigenDecomposition.java100644 1750 1750 12610 11532241245 30265 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * An interface to classes that implement an algorithm to calculate the * eigen decomposition of a real matrix. *

                    The eigen decomposition of matrix A is a set of two matrices: * V and D such that A = V × D × VT. * A, V and D are all m × m matrices.

                    *

                    This interface is similar in spirit to the EigenvalueDecomposition * class from the JAMA * library, with the following changes:

                    *
                      *
                    • a {@link #getVT() getVt} method has been added,
                    • *
                    • two {@link #getRealEigenvalue(int) getRealEigenvalue} and {@link #getImagEigenvalue(int) * getImagEigenvalue} methods to pick up a single eigenvalue have been added,
                    • *
                    • a {@link #getEigenvector(int) getEigenvector} method to pick up a single * eigenvector has been added,
                    • *
                    • a {@link #getDeterminant() getDeterminant} method has been added.
                    • *
                    • a {@link #getSolver() getSolver} method has been added.
                    • *
                    * @see MathWorld * @see Wikipedia * @version $Revision: 997726 $ $Date: 2010-09-16 14:39:51 +0200 (jeu. 16 sept. 2010) $ * @since 2.0 */ public interface EigenDecomposition { /** * Returns the matrix V of the decomposition. *

                    V is an orthogonal matrix, i.e. its transpose is also its inverse.

                    *

                    The columns of V are the eigenvectors of the original matrix.

                    *

                    No assumption is made about the orientation of the system axes formed * by the columns of V (e.g. in a 3-dimension space, V can form a left- * or right-handed system).

                    * @return the V matrix */ RealMatrix getV(); /** * Returns the block diagonal matrix D of the decomposition. *

                    D is a block diagonal matrix.

                    *

                    Real eigenvalues are on the diagonal while complex values are on * 2x2 blocks { {real +imaginary}, {-imaginary, real} }.

                    * @return the D matrix * @see #getRealEigenvalues() * @see #getImagEigenvalues() */ RealMatrix getD(); /** * Returns the transpose of the matrix V of the decomposition. *

                    V is an orthogonal matrix, i.e. its transpose is also its inverse.

                    *

                    The columns of V are the eigenvectors of the original matrix.

                    *

                    No assumption is made about the orientation of the system axes formed * by the columns of V (e.g. in a 3-dimension space, V can form a left- * or right-handed system).

                    * @return the transpose of the V matrix */ RealMatrix getVT(); /** * Returns a copy of the real parts of the eigenvalues of the original matrix. * @return a copy of the real parts of the eigenvalues of the original matrix * @see #getD() * @see #getRealEigenvalue(int) * @see #getImagEigenvalues() */ double[] getRealEigenvalues(); /** * Returns the real part of the ith eigenvalue of the original matrix. * @param i index of the eigenvalue (counting from 0) * @return real part of the ith eigenvalue of the original matrix * @see #getD() * @see #getRealEigenvalues() * @see #getImagEigenvalue(int) */ double getRealEigenvalue(int i); /** * Returns a copy of the imaginary parts of the eigenvalues of the original matrix. * @return a copy of the imaginary parts of the eigenvalues of the original matrix * @see #getD() * @see #getImagEigenvalue(int) * @see #getRealEigenvalues() */ double[] getImagEigenvalues(); /** * Returns the imaginary part of the ith eigenvalue of the original matrix. * @param i index of the eigenvalue (counting from 0) * @return imaginary part of the ith eigenvalue of the original matrix * @see #getD() * @see #getImagEigenvalues() * @see #getRealEigenvalue(int) */ double getImagEigenvalue(int i); /** * Returns a copy of the ith eigenvector of the original matrix. * @param i index of the eigenvector (counting from 0) * @return copy of the ith eigenvector of the original matrix * @see #getD() */ RealVector getEigenvector(int i); /** * Return the determinant of the matrix * @return determinant of the matrix */ double getDeterminant(); /** * Get a solver for finding the A × X = B solution in exact linear sense. * @return a solver */ DecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java100644 1750 1750 33334 11532241245 30406 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Calculates the LUP-decomposition of a square matrix. *

                    The LUP-decomposition of a matrix A consists of three matrices * L, U and P that satisfy: PA = LU, L is lower triangular, and U is * upper triangular and P is a permutation matrix. All matrices are * m×m.

                    *

                    As shown by the presence of the P matrix, this decomposition is * implemented using partial pivoting.

                    * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class LUDecompositionImpl implements LUDecomposition { /** Default bound to determine effective singularity in LU decomposition */ private static final double DEFAULT_TOO_SMALL = 10E-12; /** Entries of LU decomposition. */ private double lu[][]; /** Pivot permutation associated with LU decomposition */ private int[] pivot; /** Parity of the permutation associated with the LU decomposition */ private boolean even; /** Singularity indicator. */ private boolean singular; /** Cached value of L. */ private RealMatrix cachedL; /** Cached value of U. */ private RealMatrix cachedU; /** Cached value of P. */ private RealMatrix cachedP; /** * Calculates the LU-decomposition of the given matrix. * @param matrix The matrix to decompose. * @exception InvalidMatrixException if matrix is not square */ public LUDecompositionImpl(RealMatrix matrix) throws InvalidMatrixException { this(matrix, DEFAULT_TOO_SMALL); } /** * Calculates the LU-decomposition of the given matrix. * @param matrix The matrix to decompose. * @param singularityThreshold threshold (based on partial row norm) * under which a matrix is considered singular * @exception NonSquareMatrixException if matrix is not square */ public LUDecompositionImpl(RealMatrix matrix, double singularityThreshold) throws NonSquareMatrixException { if (!matrix.isSquare()) { throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); } final int m = matrix.getColumnDimension(); lu = matrix.getData(); pivot = new int[m]; cachedL = null; cachedU = null; cachedP = null; // Initialize permutation array and parity for (int row = 0; row < m; row++) { pivot[row] = row; } even = true; singular = false; // Loop over columns for (int col = 0; col < m; col++) { double sum = 0; // upper for (int row = 0; row < col; row++) { final double[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < row; i++) { sum -= luRow[i] * lu[i][col]; } luRow[col] = sum; } // lower int max = col; // permutation row double largest = Double.NEGATIVE_INFINITY; for (int row = col; row < m; row++) { final double[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < col; i++) { sum -= luRow[i] * lu[i][col]; } luRow[col] = sum; // maintain best permutation choice if (FastMath.abs(sum) > largest) { largest = FastMath.abs(sum); max = row; } } // Singularity check if (FastMath.abs(lu[max][col]) < singularityThreshold) { singular = true; return; } // Pivot if necessary if (max != col) { double tmp = 0; final double[] luMax = lu[max]; final double[] luCol = lu[col]; for (int i = 0; i < m; i++) { tmp = luMax[i]; luMax[i] = luCol[i]; luCol[i] = tmp; } int temp = pivot[max]; pivot[max] = pivot[col]; pivot[col] = temp; even = !even; } // Divide the lower elements by the "winning" diagonal elt. final double luDiag = lu[col][col]; for (int row = col + 1; row < m; row++) { lu[row][col] /= luDiag; } } } /** {@inheritDoc} */ public RealMatrix getL() { if ((cachedL == null) && !singular) { final int m = pivot.length; cachedL = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < m; ++i) { final double[] luI = lu[i]; for (int j = 0; j < i; ++j) { cachedL.setEntry(i, j, luI[j]); } cachedL.setEntry(i, i, 1.0); } } return cachedL; } /** {@inheritDoc} */ public RealMatrix getU() { if ((cachedU == null) && !singular) { final int m = pivot.length; cachedU = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < m; ++i) { final double[] luI = lu[i]; for (int j = i; j < m; ++j) { cachedU.setEntry(i, j, luI[j]); } } } return cachedU; } /** {@inheritDoc} */ public RealMatrix getP() { if ((cachedP == null) && !singular) { final int m = pivot.length; cachedP = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < m; ++i) { cachedP.setEntry(i, pivot[i], 1.0); } } return cachedP; } /** {@inheritDoc} */ public int[] getPivot() { return pivot.clone(); } /** {@inheritDoc} */ public double getDeterminant() { if (singular) { return 0; } else { final int m = pivot.length; double determinant = even ? 1 : -1; for (int i = 0; i < m; i++) { determinant *= lu[i][i]; } return determinant; } } /** {@inheritDoc} */ public DecompositionSolver getSolver() { return new Solver(lu, pivot, singular); } /** Specialized solver. */ private static class Solver implements DecompositionSolver { /** Entries of LU decomposition. */ private final double lu[][]; /** Pivot permutation associated with LU decomposition. */ private final int[] pivot; /** Singularity indicator. */ private final boolean singular; /** * Build a solver from decomposed matrix. * @param lu entries of LU decomposition * @param pivot pivot permutation associated with LU decomposition * @param singular singularity indicator */ private Solver(final double[][] lu, final int[] pivot, final boolean singular) { this.lu = lu; this.pivot = pivot; this.singular = singular; } /** {@inheritDoc} */ public boolean isNonSingular() { return !singular; } /** {@inheritDoc} */ public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { final int m = pivot.length; if (b.length != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m); } if (singular) { throw new SingularMatrixException(); } final double[] bp = new double[m]; // Apply permutations to b for (int row = 0; row < m; row++) { bp[row] = b[pivot[row]]; } // Solve LY = b for (int col = 0; col < m; col++) { final double bpCol = bp[col]; for (int i = col + 1; i < m; i++) { bp[i] -= bpCol * lu[i][col]; } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { bp[col] /= lu[col][col]; final double bpCol = bp[col]; for (int i = 0; i < col; i++) { bp[i] -= bpCol * lu[i][col]; } } return bp; } /** {@inheritDoc} */ public RealVector solve(RealVector b) throws IllegalArgumentException, InvalidMatrixException { try { return solve((ArrayRealVector) b); } catch (ClassCastException cce) { final int m = pivot.length; if (b.getDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.getDimension(), m); } if (singular) { throw new SingularMatrixException(); } final double[] bp = new double[m]; // Apply permutations to b for (int row = 0; row < m; row++) { bp[row] = b.getEntry(pivot[row]); } // Solve LY = b for (int col = 0; col < m; col++) { final double bpCol = bp[col]; for (int i = col + 1; i < m; i++) { bp[i] -= bpCol * lu[i][col]; } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { bp[col] /= lu[col][col]; final double bpCol = bp[col]; for (int i = 0; i < col; i++) { bp[i] -= bpCol * lu[i][col]; } } return new ArrayRealVector(bp, false); } } /** Solve the linear equation A × X = B. *

                    The A matrix is implicit here. It is

                    * @param b right-hand side of the equation A × X = B * @return a vector X such that A × X = B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ public ArrayRealVector solve(ArrayRealVector b) throws IllegalArgumentException, InvalidMatrixException { return new ArrayRealVector(solve(b.getDataRef()), false); } /** {@inheritDoc} */ public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException { final int m = pivot.length; if (b.getRowDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), m, "n"); } if (singular) { throw new SingularMatrixException(); } final int nColB = b.getColumnDimension(); // Apply permutations to b final double[][] bp = new double[m][nColB]; for (int row = 0; row < m; row++) { final double[] bpRow = bp[row]; final int pRow = pivot[row]; for (int col = 0; col < nColB; col++) { bpRow[col] = b.getEntry(pRow, col); } } // Solve LY = b for (int col = 0; col < m; col++) { final double[] bpCol = bp[col]; for (int i = col + 1; i < m; i++) { final double[] bpI = bp[i]; final double luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { bpI[j] -= bpCol[j] * luICol; } } } // Solve UX = Y for (int col = m - 1; col >= 0; col--) { final double[] bpCol = bp[col]; final double luDiag = lu[col][col]; for (int j = 0; j < nColB; j++) { bpCol[j] /= luDiag; } for (int i = 0; i < col; i++) { final double[] bpI = bp[i]; final double luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { bpI[j] -= bpCol[j] * luICol; } } } return new Array2DRowRealMatrix(bp, false); } /** {@inheritDoc} */ public RealMatrix getInverse() throws InvalidMatrixException { return solve(MatrixUtils.createRealIdentityMatrix(pivot.length)); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/BigMatrix.java100644 1750 1750 26462 11532241245 26401 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.math.BigDecimal; /** * Interface defining a real-valued matrix with basic algebraic operations, using * BigDecimal representations for the entries. *

                    * Matrix element indexing is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.

                    * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @deprecated as of 2.0, replaced by {@link FieldMatrix} with a {@link * org.apache.commons.math.util.BigReal} parameter */ @Deprecated public interface BigMatrix extends AnyMatrix { /** * Returns a (deep) copy of this. * * @return matrix copy */ BigMatrix copy(); /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @exception IllegalArgumentException if m is not the same size as this */ BigMatrix add(BigMatrix m) throws IllegalArgumentException; /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @exception IllegalArgumentException if m is not the same size as this */ BigMatrix subtract(BigMatrix m) throws IllegalArgumentException; /** * Returns the result of adding d to each entry of this. * * @param d value to be added to each entry * @return d + this */ BigMatrix scalarAdd(BigDecimal d); /** * Returns the result multiplying each entry of this by d. * * @param d value to multiply all entries by * @return d * this */ BigMatrix scalarMultiply(BigDecimal d); /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ BigMatrix multiply(BigMatrix m) throws IllegalArgumentException; /** * Returns the result premultiplying this by m. * @param m matrix to premultiply by * @return m * this * @throws IllegalArgumentException * if rowDimension(this) != columnDimension(m) */ BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException; /** * Returns matrix entries as a two-dimensional array. * * @return 2-dimensional array of entries */ BigDecimal[][] getData(); /** * Returns matrix entries as a two-dimensional array. * * @return 2-dimensional array of entries */ double [][] getDataAsDoubleArray(); /*** * Gets the rounding mode * @return the rounding mode */ int getRoundingMode(); /** * Returns the * maximum absolute row sum norm of the matrix. * * @return norm */ BigDecimal getNorm(); /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index * @param startColumn Initial column index * @param endColumn Final column index * @return The subMatrix containing the data of the * specified rows and columns * @exception MatrixIndexException if the indices are not valid */ BigMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException; /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @return The subMatrix containing the data in the * specified rows and columns * @exception MatrixIndexException if row or column selections are not valid */ BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException; /** * Returns the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be fetched * @return row matrix * @throws MatrixIndexException if the specified row index is invalid */ BigMatrix getRowMatrix(int row) throws MatrixIndexException; /** * Returns the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be fetched * @return column matrix * @throws MatrixIndexException if the specified column index is invalid */ BigMatrix getColumnMatrix(int column) throws MatrixIndexException; /** * Returns the entries in row number row as an array. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ BigDecimal[] getRow(int row) throws MatrixIndexException; /** * Returns the entries in row number row as an array * of double values. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ double [] getRowAsDoubleArray(int row) throws MatrixIndexException; /** * Returns the entries in column number col as an array. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param col the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ BigDecimal[] getColumn(int col) throws MatrixIndexException; /** * Returns the entries in column number col as an array * of double values. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param col the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ double [] getColumnAsDoubleArray(int col) throws MatrixIndexException; /** * Returns the entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid */ BigDecimal getEntry(int row, int column) throws MatrixIndexException; /** * Returns the entry in the specified row and column as a double. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid */ double getEntryAsDouble(int row, int column) throws MatrixIndexException; /** * Returns the transpose of this matrix. * * @return transpose matrix */ BigMatrix transpose(); /** * Returns the inverse of this matrix. * * @return inverse matrix * @throws org.apache.commons.math.linear.InvalidMatrixException if * this is not invertible */ BigMatrix inverse() throws InvalidMatrixException; /** * Returns the determinant of this matrix. * * @return determinant *@throws org.apache.commons.math.linear.InvalidMatrixException if * matrix is not square */ BigDecimal getDeterminant() throws InvalidMatrixException; /** * Returns the * trace of the matrix (the sum of the elements on the main diagonal). * * @return trace */ BigDecimal getTrace(); /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException; /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException; /** * Returns the solution vector for a linear system with coefficient * matrix = this and constant vector = b. * * @param b constant vector * @return vector of solution values to AX = b, where A is *this * @throws IllegalArgumentException if this.rowDimension != b.length * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular */ BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException; /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of * b. * * @param b matrix of constant vectors forming RHS of linear systems to * to solve * @return matrix of solution vectors * @throws IllegalArgumentException if this.rowDimension != row dimension * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular */ BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/OpenMapRealMatrix.java100644 1750 1750 22734 11532241245 30041 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.util.OpenIntToDoubleHashMap; /** * Sparse matrix implementation based on an open addressed map. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public class OpenMapRealMatrix extends AbstractRealMatrix implements SparseRealMatrix, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -5962461716457143437L; /** Number of rows of the matrix. */ private final int rows; /** Number of columns of the matrix. */ private final int columns; /** Storage for (sparse) matrix elements. */ private final OpenIntToDoubleHashMap entries; /** * Build a sparse matrix with the supplied row and column dimensions. * @param rowDimension number of rows of the matrix * @param columnDimension number of columns of the matrix */ public OpenMapRealMatrix(int rowDimension, int columnDimension) { super(rowDimension, columnDimension); this.rows = rowDimension; this.columns = columnDimension; this.entries = new OpenIntToDoubleHashMap(0.0); } /** * Build a matrix by copying another one. * @param matrix matrix to copy */ public OpenMapRealMatrix(OpenMapRealMatrix matrix) { this.rows = matrix.rows; this.columns = matrix.columns; this.entries = new OpenIntToDoubleHashMap(matrix.entries); } /** {@inheritDoc} */ @Override public OpenMapRealMatrix copy() { return new OpenMapRealMatrix(this); } /** {@inheritDoc} */ @Override public OpenMapRealMatrix createMatrix(int rowDimension, int columnDimension) throws IllegalArgumentException { return new OpenMapRealMatrix(rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public int getColumnDimension() { return columns; } /** {@inheritDoc} */ @Override public OpenMapRealMatrix add(final RealMatrix m) throws IllegalArgumentException { try { return add((OpenMapRealMatrix) m); } catch (ClassCastException cce) { return (OpenMapRealMatrix) super.add(m); } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public OpenMapRealMatrix add(OpenMapRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final OpenMapRealMatrix out = new OpenMapRealMatrix(this); for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) { iterator.advance(); final int row = iterator.key() / columns; final int col = iterator.key() - row * columns; out.setEntry(row, col, getEntry(row, col) + iterator.value()); } return out; } /** {@inheritDoc} */ @Override public OpenMapRealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { try { return subtract((OpenMapRealMatrix) m); } catch (ClassCastException cce) { return (OpenMapRealMatrix) super.subtract(m); } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this - m * @throws IllegalArgumentException if m is not the same size as this */ public OpenMapRealMatrix subtract(OpenMapRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final OpenMapRealMatrix out = new OpenMapRealMatrix(this); for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) { iterator.advance(); final int row = iterator.key() / columns; final int col = iterator.key() - row * columns; out.setEntry(row, col, getEntry(row, col) - iterator.value()); } return out; } /** {@inheritDoc} */ @Override public RealMatrix multiply(final RealMatrix m) throws IllegalArgumentException { try { return multiply((OpenMapRealMatrix) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int outCols = m.getColumnDimension(); final BlockRealMatrix out = new BlockRealMatrix(rows, outCols); for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { iterator.advance(); final double value = iterator.value(); final int key = iterator.key(); final int i = key / columns; final int k = key % columns; for (int j = 0; j < outCols; ++j) { out.addToEntry(i, j, value * m.getEntry(k, j)); } } return out; } } /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public OpenMapRealMatrix multiply(OpenMapRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int outCols = m.getColumnDimension(); OpenMapRealMatrix out = new OpenMapRealMatrix(rows, outCols); for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { iterator.advance(); final double value = iterator.value(); final int key = iterator.key(); final int i = key / columns; final int k = key % columns; for (int j = 0; j < outCols; ++j) { final int rightKey = m.computeKey(k, j); if (m.entries.containsKey(rightKey)) { final int outKey = out.computeKey(i, j); final double outValue = out.entries.get(outKey) + value * m.entries.get(rightKey); if (outValue == 0.0) { out.entries.remove(outKey); } else { out.entries.put(outKey, outValue); } } } } return out; } /** {@inheritDoc} */ @Override public double getEntry(int row, int column) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); return entries.get(computeKey(row, column)); } /** {@inheritDoc} */ @Override public int getRowDimension() { return rows; } /** {@inheritDoc} */ @Override public void setEntry(int row, int column, double value) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); if (value == 0.0) { entries.remove(computeKey(row, column)); } else { entries.put(computeKey(row, column), value); } } /** {@inheritDoc} */ @Override public void addToEntry(int row, int column, double increment) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); final int key = computeKey(row, column); final double value = entries.get(key) + increment; if (value == 0.0) { entries.remove(key); } else { entries.put(key, value); } } /** {@inheritDoc} */ @Override public void multiplyEntry(int row, int column, double factor) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); final int key = computeKey(row, column); final double value = entries.get(key) * factor; if (value == 0.0) { entries.remove(key); } else { entries.put(key, value); } } /** * Compute the key to access a matrix element * @param row row index of the matrix element * @param column column index of the matrix element * @return key within the map to access the matrix element */ private int computeKey(int row, int column) { return row * columns + column; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldMatrixChangingVisitor.java100644 1750 1750 4523 11532241245 31714 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining a visitor for matrix entries. * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface FieldMatrixChangingVisitor> { /** * Start visiting a matrix. *

                    This method is called once before any entry of the matrix is visited.

                    * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) */ void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn); /** * Visit one matrix entry. * @param row row index of the entry * @param column column index of the entry * @param value current value of the entry * @return the new value to be set for the entry * @throws MatrixVisitorException if something wrong occurs */ T visit(int row, int column, T value) throws MatrixVisitorException; /** * End visiting a matrix. *

                    This method is called once after all entries of the matrix have been visited.

                    * @return the value that the walkInXxxOrder must return */ T end(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SparseFieldVector.java100644 1750 1750 52071 11532241245 30072 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.lang.reflect.Array; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.OpenIntToFieldHashMap; /** * This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store. * @param the type of the field elements * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class SparseFieldVector> implements FieldVector, Serializable { /** * Serial version id */ private static final long serialVersionUID = 7841233292190413362L; /** Field to which the elements belong. */ private final Field field; /** Entries of the vector. */ private final OpenIntToFieldHashMap entries; /** Dimension of the vector. */ private final int virtualSize; /** * Build a 0-length vector. *

                    Zero-length vectors may be used to initialize construction of vectors * by data gathering. We start with zero-length and use either the {@link * #SparseFieldVector(SparseFieldVector, int)} constructor * or one of the append method ({@link #append(FieldElement)}, * {@link #append(FieldElement[])}, {@link #append(FieldVector)}, * {@link #append(SparseFieldVector)}) to gather data into this vector.

                    * @param field field to which the elements belong */ public SparseFieldVector(Field field) { this(field, 0); } /** * Construct a (dimension)-length vector of zeros. * @param field field to which the elements belong * @param dimension Size of the vector */ public SparseFieldVector(Field field, int dimension) { this.field = field; virtualSize = dimension; entries = new OpenIntToFieldHashMap(field); } /** * Build a resized vector, for use with append. * @param v The original vector * @param resize The amount to resize it */ protected SparseFieldVector(SparseFieldVector v, int resize) { field = v.field; virtualSize = v.getDimension() + resize; entries = new OpenIntToFieldHashMap(v.entries); } /** * Build a vector with known the sparseness (for advanced use only). * @param field field to which the elements belong * @param dimension The size of the vector * @param expectedSize The expected number of non-zero entries */ public SparseFieldVector(Field field, int dimension, int expectedSize) { this.field = field; virtualSize = dimension; entries = new OpenIntToFieldHashMap(field,expectedSize); } /** * Create from a Field array. * Only non-zero entries will be stored * @param field field to which the elements belong * @param values The set of values to create from */ public SparseFieldVector(Field field, T[] values) { this.field = field; virtualSize = values.length; entries = new OpenIntToFieldHashMap(field); for (int key = 0; key < values.length; key++) { T value = values[key]; entries.put(key, value); } } /** * Copy constructor. * @param v The instance to copy from */ public SparseFieldVector(SparseFieldVector v) { field = v.field; virtualSize = v.getDimension(); entries = new OpenIntToFieldHashMap(v.getEntries()); } /** * Get the entries of this instance. * @return entries of this instance */ private OpenIntToFieldHashMap getEntries() { return entries; } /** * Optimized method to add sparse vectors. * @param v vector to add * @return The sum of this and v * @throws IllegalArgumentException If the dimensions don't match */ public FieldVector add(SparseFieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); SparseFieldVector res = (SparseFieldVector)copy(); OpenIntToFieldHashMap.Iterator iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); T value = iter.value(); if (entries.containsKey(key)) { res.setEntry(key, entries.get(key).add(value)); } else { res.setEntry(key, value); } } return res; } /** {@inheritDoc} */ public FieldVector add(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); SparseFieldVector res = new SparseFieldVector(field,getDimension()); for (int i = 0; i < v.length; i++) { res.setEntry(i, v[i].add(getEntry(i))); } return res; } /** * Construct a vector by appending a vector to this vector. * @param v vector to append to this one. * @return a new vector */ public FieldVector append(SparseFieldVector v) { SparseFieldVector res = new SparseFieldVector(this, v.getDimension()); OpenIntToFieldHashMap.Iterator iter = v.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key() + virtualSize, iter.value()); } return res; } /** {@inheritDoc} */ public FieldVector append(FieldVector v) { if (v instanceof SparseFieldVector) { return append((SparseFieldVector) v); } else { return append(v.toArray()); } } /** {@inheritDoc} */ public FieldVector append(T d) { FieldVector res = new SparseFieldVector(this, 1); res.setEntry(virtualSize, d); return res; } /** {@inheritDoc} */ public FieldVector append(T[] a) { FieldVector res = new SparseFieldVector(this, a.length); for (int i = 0; i < a.length; i++) { res.setEntry(i + virtualSize, a[i]); } return res; } /** {@inheritDoc} */ public FieldVector copy() { return new SparseFieldVector(this); } /** {@inheritDoc} */ public T dotProduct(FieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); T res = field.getZero(); OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); res = res.add(v.getEntry(iter.key()).multiply(iter.value())); } return res; } /** {@inheritDoc} */ public T dotProduct(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); T res = field.getZero(); OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { int idx = iter.key(); T value = field.getZero(); if (idx < v.length) { value = v[idx]; } res = res.add(value.multiply(iter.value())); } return res; } /** {@inheritDoc} */ public FieldVector ebeDivide(FieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); SparseFieldVector res = new SparseFieldVector(this); OpenIntToFieldHashMap.Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key()))); } return res; } /** {@inheritDoc} */ public FieldVector ebeDivide(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); SparseFieldVector res = new SparseFieldVector(this); OpenIntToFieldHashMap.Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value().divide(v[iter.key()])); } return res; } /** {@inheritDoc} */ public FieldVector ebeMultiply(FieldVector v)throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); SparseFieldVector res = new SparseFieldVector(this); OpenIntToFieldHashMap.Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key()))); } return res; } /** {@inheritDoc} */ public FieldVector ebeMultiply(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); SparseFieldVector res = new SparseFieldVector(this); OpenIntToFieldHashMap.Iterator iter = res.entries.iterator(); while (iter.hasNext()) { iter.advance(); res.setEntry(iter.key(), iter.value().multiply(v[iter.key()])); } return res; } /** {@inheritDoc} */ public T[] getData() { T[] res = buildArray(virtualSize); OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); res[iter.key()] = iter.value(); } return res; } /** {@inheritDoc} */ public int getDimension() { return virtualSize; } /** {@inheritDoc} */ public T getEntry(int index) throws MatrixIndexException { checkIndex(index); return entries.get(index); } /** {@inheritDoc} */ public Field getField() { return field; } /** {@inheritDoc} */ public FieldVector getSubVector(int index, int n) throws MatrixIndexException { checkIndex(index); checkIndex(index + n - 1); SparseFieldVector res = new SparseFieldVector(field,n); int end = index + n; OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (key >= index && key < end) { res.setEntry(key - index, iter.value()); } } return res; } /** {@inheritDoc} */ public FieldVector mapAdd(T d) { return copy().mapAddToSelf(d); } /** {@inheritDoc} */ public FieldVector mapAddToSelf(T d) { for (int i = 0; i < virtualSize; i++) { setEntry(i, getEntry(i).add(d)); } return this; } /** {@inheritDoc} */ public FieldVector mapDivide(T d) { return copy().mapDivideToSelf(d); } /** {@inheritDoc} */ public FieldVector mapDivideToSelf(T d) { OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); entries.put(iter.key(), iter.value().divide(d)); } return this; } /** {@inheritDoc} */ public FieldVector mapInv() { return copy().mapInvToSelf(); } /** {@inheritDoc} */ public FieldVector mapInvToSelf() { for (int i = 0; i < virtualSize; i++) { setEntry(i, field.getOne().divide(getEntry(i))); } return this; } /** {@inheritDoc} */ public FieldVector mapMultiply(T d) { return copy().mapMultiplyToSelf(d); } /** {@inheritDoc} */ public FieldVector mapMultiplyToSelf(T d) { OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); entries.put(iter.key(), iter.value().multiply(d)); } return this; } /** {@inheritDoc} */ public FieldVector mapSubtract(T d) { return copy().mapSubtractToSelf(d); } /** {@inheritDoc} */ public FieldVector mapSubtractToSelf(T d) { return mapAddToSelf(field.getZero().subtract(d)); } /** * Optimized method to compute outer product when both vectors are sparse. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @throws IllegalArgumentException if v is not the same size as {@code this} */ public FieldMatrix outerProduct(SparseFieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); SparseFieldMatrix res = new SparseFieldMatrix(field, virtualSize, virtualSize); OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); OpenIntToFieldHashMap.Iterator iter2 = v.entries.iterator(); while (iter2.hasNext()) { iter2.advance(); res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value())); } } return res; } /** {@inheritDoc} */ public FieldMatrix outerProduct(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); FieldMatrix res = new SparseFieldMatrix(field, virtualSize, virtualSize); OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); int row = iter.key(); FieldElementvalue = iter.value(); for (int col = 0; col < virtualSize; col++) { res.setEntry(row, col, value.multiply(v[col])); } } return res; } /** {@inheritDoc} */ public FieldMatrix outerProduct(FieldVector v) throws IllegalArgumentException { if(v instanceof SparseFieldVector) return outerProduct((SparseFieldVector)v); else return outerProduct(v.toArray()); } /** {@inheritDoc} */ public FieldVector projection(FieldVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); } /** {@inheritDoc} */ public FieldVector projection(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); return projection(new SparseFieldVector(field,v)); } /** {@inheritDoc} */ public void set(T value) { for (int i = 0; i < virtualSize; i++) { setEntry(i, value); } } /** {@inheritDoc} */ public void setEntry(int index, T value) throws MatrixIndexException { checkIndex(index); entries.put(index, value); } /** {@inheritDoc} */ public void setSubVector(int index, FieldVector v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.getDimension() - 1); setSubVector(index, v.getData()); } /** {@inheritDoc} */ public void setSubVector(int index, T[] v) throws MatrixIndexException { checkIndex(index); checkIndex(index + v.length - 1); for (int i = 0; i < v.length; i++) { setEntry(i + index, v[i]); } } /** * Optimized method to subtract SparseRealVectors. * @param v The vector to subtract from this * @return The difference of this and v * @throws IllegalArgumentException If the dimensions don't match */ public SparseFieldVector subtract(SparseFieldVector v) throws IllegalArgumentException{ checkVectorDimensions(v.getDimension()); SparseFieldVector res = (SparseFieldVector)copy(); OpenIntToFieldHashMap.Iterator iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (entries.containsKey(key)) { res.setEntry(key, entries.get(key).subtract(iter.value())); } else { res.setEntry(key, field.getZero().subtract(iter.value())); } } return res; } /** {@inheritDoc} */ public FieldVector subtract(FieldVector v) throws IllegalArgumentException { if(v instanceof SparseFieldVector) return subtract((SparseFieldVector)v); else return subtract(v.toArray()); } /** {@inheritDoc} */ public FieldVector subtract(T[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); SparseFieldVector res = new SparseFieldVector(this); for (int i = 0; i < v.length; i++) { if (entries.containsKey(i)) { res.setEntry(i, entries.get(i).subtract(v[i])); } else { res.setEntry(i, field.getZero().subtract(v[i])); } } return res; } /** {@inheritDoc} */ public T[] toArray() { return getData(); } /** * Check if an index is valid. * * @param index * index to check * @exception MatrixIndexException * if index is not valid */ private void checkIndex(final int index) throws MatrixIndexException { if (index < 0 || index >= getDimension()) { throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE, index, 0, getDimension() - 1); } } /** * Check if instance dimension is equal to some expected value. * * @param n * expected dimension. * @exception IllegalArgumentException * if the dimension is inconsistent with vector size */ protected void checkVectorDimensions(int n) throws IllegalArgumentException { if (getDimension() != n) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, getDimension(), n); } } /** {@inheritDoc} */ public FieldVector add(FieldVector v) throws IllegalArgumentException { if (v instanceof SparseFieldVector) { return add((SparseFieldVector)v); } else { return add(v.toArray()); } } /** Build an array of elements. * @param length size of the array to build * @return a new array */ @SuppressWarnings("unchecked") // field is type T private T[] buildArray(final int length) { return (T[]) Array.newInstance(field.getZero().getClass(), length); } /** {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((field == null) ? 0 : field.hashCode()); result = prime * result + virtualSize; OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); int temp = iter.value().hashCode(); result = prime * result + temp; } return result; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof SparseFieldVector)) { return false; } @SuppressWarnings("unchecked") // OK, because "else if" check below ensures that // other must be the same type as this SparseFieldVector other = (SparseFieldVector) obj; if (field == null) { if (other.field != null) { return false; } } else if (!field.equals(other.field)) { return false; } if (virtualSize != other.virtualSize) { return false; } OpenIntToFieldHashMap.Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); T test = other.getEntry(iter.key()); if (!test.equals(iter.value())) { return false; } } iter = other.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); T test = iter.value(); if (!test.equals(getEntry(iter.key()))) { return false; } } return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/Array2DRowRealMatrix.java100644 1750 1750 54077 11532241245 30443 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implementation of RealMatrix using a double[][] array to store entries and * * LU decomposition to support linear system * solution and inverse. *

                    * The LU decomposition is performed as needed, to support the following operations:

                      *
                    • solve
                    • *
                    • isSingular
                    • *
                    • getDeterminant
                    • *
                    • inverse

                    *

                    * Usage notes:
                    *

                    • * The LU decomposition is cached and reused on subsequent calls. * If data are modified via references to the underlying array obtained using * getDataRef(), then the stored LU decomposition will not be * discarded. In this case, you need to explicitly invoke * LUDecompose() to recompute the decomposition * before using any of the methods above.
                    • *
                    • * As specified in the {@link RealMatrix} interface, matrix element indexing * is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.
                    *

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1067294169172445528L; /** Entries of the matrix */ protected double data[][]; /** * Creates a matrix with no data */ public Array2DRowRealMatrix() { } /** * Create a new RealMatrix with the supplied row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public Array2DRowRealMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { super(rowDimension, columnDimension); data = new double[rowDimension][columnDimension]; } /** * Create a new RealMatrix using the input array as the underlying * data array. *

                    The input array is copied, not referenced. This constructor has * the same effect as calling {@link #Array2DRowRealMatrix(double[][], boolean)} * with the second argument set to true.

                    * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #Array2DRowRealMatrix(double[][], boolean) */ public Array2DRowRealMatrix(final double[][] d) throws IllegalArgumentException, NullPointerException { copyIn(d); } /** * Create a new RealMatrix using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * RealMatrix and not used directly, the copyArray may be * set to false * @param d data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #Array2DRowRealMatrix(double[][]) */ public Array2DRowRealMatrix(final double[][] d, final boolean copyArray) throws IllegalArgumentException, NullPointerException { if (copyArray) { copyIn(d); } else { if (d == null) { throw new NullPointerException(); } final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; r++) { if (d[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length); } } data = d; } } /** * Create a new (column) RealMatrix using v as the * data for the unique column of the v.length x 1 matrix * created. *

                    The input array is copied, not referenced.

                    * * @param v column vector holding data for new matrix */ public Array2DRowRealMatrix(final double[] v) { final int nRows = v.length; data = new double[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = v[row]; } } /** {@inheritDoc} */ @Override public RealMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { return new Array2DRowRealMatrix(rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public RealMatrix copy() { return new Array2DRowRealMatrix(copyOut(), false); } /** {@inheritDoc} */ @Override public RealMatrix add(final RealMatrix m) throws IllegalArgumentException { try { return add((Array2DRowRealMatrix) m); } catch (ClassCastException cce) { return super.add(m); } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public Array2DRowRealMatrix add(final Array2DRowRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final double[] dataRow = data[row]; final double[] mRow = m.data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col] + mRow[col]; } } return new Array2DRowRealMatrix(outData, false); } /** {@inheritDoc} */ @Override public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { try { return subtract((Array2DRowRealMatrix) m); } catch (ClassCastException cce) { return super.subtract(m); } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final double[] dataRow = data[row]; final double[] mRow = m.data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col] - mRow[col]; } } return new Array2DRowRealMatrix(outData, false); } /** {@inheritDoc} */ @Override public RealMatrix multiply(final RealMatrix m) throws IllegalArgumentException { try { return multiply((Array2DRowRealMatrix) m); } catch (ClassCastException cce) { return super.multiply(m); } } /** * Returns the result of postmultiplying this by m. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int nRows = this.getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = this.getColumnDimension(); final double[][] outData = new double[nRows][nCols]; for (int row = 0; row < nRows; row++) { final double[] dataRow = data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < nCols; col++) { double sum = 0; for (int i = 0; i < nSum; i++) { sum += dataRow[i] * m.data[i][col]; } outDataRow[col] = sum; } } return new Array2DRowRealMatrix(outData, false); } /** {@inheritDoc} */ @Override public double[][] getData() { return copyOut(); } /** * Returns a reference to the underlying data array. *

                    * Does not make a fresh copy of the underlying data.

                    * * @return 2-dimensional array of entries */ public double[][] getDataRef() { return data; } /** {@inheritDoc} */ @Override public void setSubMatrix(final double[][] subMatrix, final int row, final int column) throws MatrixIndexException { if (data == null) { if (row > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row); } if (column > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column); } final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.AT_LEAST_ONE_COLUMN); } data = new double[subMatrix.length][nCols]; for (int i = 0; i < data.length; ++i) { if (subMatrix[i].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[i].length); } System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); } } else { super.setSubMatrix(subMatrix, row, column); } } /** {@inheritDoc} */ @Override public double getEntry(final int row, final int column) throws MatrixIndexException { try { return data[row][column]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void setEntry(final int row, final int column, final double value) throws MatrixIndexException { try { data[row][column] = value; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void addToEntry(final int row, final int column, final double increment) throws MatrixIndexException { try { data[row][column] += increment; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void multiplyEntry(final int row, final int column, final double factor) throws MatrixIndexException { try { data[row][column] *= factor; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public int getRowDimension() { return (data == null) ? 0 : data.length; } /** {@inheritDoc} */ @Override public int getColumnDimension() { return ((data == null) || (data[0] == null)) ? 0 : data[0].length; } /** {@inheritDoc} */ @Override public double[] operate(final double[] v) throws IllegalArgumentException { final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); if (v.length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols); } final double[] out = new double[nRows]; for (int row = 0; row < nRows; row++) { final double[] dataRow = data[row]; double sum = 0; for (int i = 0; i < nCols; i++) { sum += dataRow[i] * v[i]; } out[row] = sum; } return out; } /** {@inheritDoc} */ @Override public double[] preMultiply(final double[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows); } final double[] out = new double[nCols]; for (int col = 0; col < nCols; ++col) { double sum = 0; for (int i = 0; i < nRows; ++i) { sum += data[i][col] * v[i]; } out[col] = sum; } return out; } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; for (int j = 0; j < columns; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; for (int j = 0; j < columns; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** * Returns a fresh copy of the underlying data array. * * @return a copy of the underlying data array. */ private double[][] copyOut() { final int nRows = this.getRowDimension(); final double[][] out = new double[nRows][this.getColumnDimension()]; // can't copy 2-d array in one shot, otherwise get row references for (int i = 0; i < nRows; i++) { System.arraycopy(data[i], 0, out[i], 0, data[i].length); } return out; } /** * Replaces data with a fresh copy of the input array. *

                    * Verifies that the input array is rectangular and non-empty.

                    * * @param in data to copy in * @throws IllegalArgumentException if input array is empty or not * rectangular * @throws NullPointerException if input array is null */ private void copyIn(final double[][] in) { setSubMatrix(in, 0, 0); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/BlockFieldMatrix.java100644 1750 1750 206072 11532241245 27713 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Cache-friendly implementation of FieldMatrix using a flat arrays to store * square blocks of the matrix. *

                    * This implementation is specially designed to be cache-friendly. Square blocks are * stored as small arrays and allow efficient traversal of data both in row major direction * and columns major direction, one block at a time. This greatly increases performances * for algorithms that use crossed directions loops like multiplication or transposition. *

                    *

                    * The size of square blocks is a static parameter. It may be tuned according to the cache * size of the target computer processor. As a rule of thumbs, it should be the largest * value that allows three blocks to be simultaneously cached (this is necessary for example * for matrix multiplication). The default value is to use 36x36 blocks. *

                    *

                    * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square * blocks are flattened in row major order in single dimension arrays which are therefore * {@link #BLOCK_SIZE}2 elements long for regular blocks. The blocks are themselves * organized in row major order. *

                    *

                    * As an example, for a block size of 36x36, a 100x60 matrix would be stored in 6 blocks. * Block 0 would be a Field[1296] array holding the upper left 36x36 square, block 1 would be * a Field[1296] array holding the upper center 36x36 square, block 2 would be a Field[1008] * array holding the upper right 36x28 rectangle, block 3 would be a Field[864] array holding * the lower left 24x36 rectangle, block 4 would be a Field[864] array holding the lower center * 24x36 rectangle and block 5 would be a Field[672] array holding the lower right 24x28 * rectangle. *

                    *

                    * The layout complexity overhead versus simple mapping of matrices to java * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads * to up to 3-fold improvements for matrices of moderate to large size. *

                    * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class BlockFieldMatrix> extends AbstractFieldMatrix implements Serializable { /** Block size. */ public static final int BLOCK_SIZE = 36; /** Serializable version identifier */ private static final long serialVersionUID = -4602336630143123183L; /** Blocks of matrix entries. */ private final T blocks[][]; /** Number of rows of the matrix. */ private final int rows; /** Number of columns of the matrix. */ private final int columns; /** Number of block rows of the matrix. */ private final int blockRows; /** Number of block columns of the matrix. */ private final int blockColumns; /** * Create a new matrix with the supplied row and column dimensions. * * @param field field to which the elements belong * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public BlockFieldMatrix(final Field field, final int rows, final int columns) throws IllegalArgumentException { super(field, rows, columns); this.rows = rows; this.columns = columns; // number of blocks blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; // allocate storage blocks, taking care of smaller ones at right and bottom blocks = createBlocksLayout(field, rows, columns); } /** * Create a new dense matrix copying entries from raw layout data. *

                    The input array must already be in raw layout.

                    *

                    Calling this constructor is equivalent to call: *

                    matrix = new BlockFieldMatrix(getField(), rawData.length, rawData[0].length,
                         *                                   toBlocksLayout(rawData), false);
                    *

                    * @param rawData data for new matrix, in raw layout * * @exception IllegalArgumentException if blockData shape is * inconsistent with block layout * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) */ public BlockFieldMatrix(final T[][] rawData) throws IllegalArgumentException { this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false); } /** * Create a new dense matrix copying entries from block layout data. *

                    The input array must already be in blocks layout.

                    * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @param blockData data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * * @exception IllegalArgumentException if blockData shape is * inconsistent with block layout * @see #createBlocksLayout(Field, int, int) * @see #toBlocksLayout(FieldElement[][]) * @see #BlockFieldMatrix(FieldElement[][]) */ public BlockFieldMatrix(final int rows, final int columns, final T[][] blockData, final boolean copyArray) throws IllegalArgumentException { super(extractField(blockData), rows, columns); this.rows = rows; this.columns = columns; // number of blocks blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; if (copyArray) { // allocate storage blocks, taking care of smaller ones at right and bottom blocks = buildArray(getField(), blockRows * blockColumns, -1); } else { // reference existing array blocks = blockData; } int index = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) { if (blockData[index].length != iHeight * blockWidth(jBlock)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.WRONG_BLOCK_LENGTH, blockData[index].length, iHeight * blockWidth(jBlock)); } if (copyArray) { blocks[index] = blockData[index].clone(); } } } } /** * Convert a data array from raw layout to blocks layout. *

                    * Raw layout is the straightforward layout where element at row i and * column j is in array element rawData[i][j]. Blocks layout * is the layout used in {@link BlockFieldMatrix} instances, where the matrix * is split in square blocks (except at right and bottom side where blocks may * be rectangular to fit matrix size) and each block is stored in a flattened * one-dimensional array. *

                    *

                    * This method creates an array in blocks layout from an input array in raw layout. * It can be used to provide the array argument of the {@link * #BlockFieldMatrix(int, int, FieldElement[][], boolean)} * constructor. *

                    * @param the type of the field elements * @param rawData data array in raw layout * @return a new data array containing the same entries but in blocks layout * @exception IllegalArgumentException if rawData is not rectangular * (not all rows have the same length) * @see #createBlocksLayout(Field, int, int) * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) */ public static > T[][] toBlocksLayout(final T[][] rawData) throws IllegalArgumentException { final int rows = rawData.length; final int columns = rawData[0].length; final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; // safety checks for (int i = 0; i < rawData.length; ++i) { final int length = rawData[i].length; if (length != columns) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, columns, length); } } // convert array final Field field = extractField(rawData); final T[][] blocks = buildArray(field, blockRows * blockColumns, -1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int iHeight = pEnd - pStart; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final int jWidth = qEnd - qStart; // allocate new block final T[] block = buildArray(field, iHeight * jWidth); blocks[blockIndex] = block; // copy data int index = 0; for (int p = pStart; p < pEnd; ++p) { System.arraycopy(rawData[p], qStart, block, index, jWidth); index += jWidth; } ++blockIndex; } } return blocks; } /** * Create a data array in blocks layout. *

                    * This method can be used to create the array argument of the {@link * #BlockFieldMatrix(int, int, FieldElement[][], boolean)} * constructor. *

                    * @param the type of the field elements * @param field field to which the elements belong * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @return a new data array in blocks layout * @see #toBlocksLayout(FieldElement[][]) * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) */ public static > T[][] createBlocksLayout(final Field field, final int rows, final int columns) { final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; final T[][] blocks = buildArray(field, blockRows * blockColumns, -1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int iHeight = pEnd - pStart; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final int jWidth = qEnd - qStart; blocks[blockIndex] = buildArray(field, iHeight * jWidth); ++blockIndex; } } return blocks; } /** {@inheritDoc} */ @Override public FieldMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { return new BlockFieldMatrix(getField(), rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public FieldMatrix copy() { // create an empty matrix BlockFieldMatrix copied = new BlockFieldMatrix(getField(), rows, columns); // copy the blocks for (int i = 0; i < blocks.length; ++i) { System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length); } return copied; } /** {@inheritDoc} */ @Override public FieldMatrix add(final FieldMatrix m) throws IllegalArgumentException { try { return add((BlockFieldMatrix) m); } catch (ClassCastException cce) { // safety check checkAdditionCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform addition block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { // perform addition on the current block final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[k].add(m.getEntry(p, q)); ++k; } } // go to next block ++blockIndex; } } return out; } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BlockFieldMatrix add(final BlockFieldMatrix m) throws IllegalArgumentException { // safety check checkAdditionCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform addition block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; final T[] mBlock = m.blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k].add(mBlock[k]); } } return out; } /** {@inheritDoc} */ @Override public FieldMatrix subtract(final FieldMatrix m) throws IllegalArgumentException { try { return subtract((BlockFieldMatrix) m); } catch (ClassCastException cce) { // safety check checkSubtractionCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform subtraction block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { // perform subtraction on the current block final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[k].subtract(m.getEntry(p, q)); ++k; } } // go to next block ++blockIndex; } } return out; } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this - m * @throws IllegalArgumentException if m is not the same size as this */ public BlockFieldMatrix subtract(final BlockFieldMatrix m) throws IllegalArgumentException { // safety check checkSubtractionCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; final T[] mBlock = m.blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k].subtract(mBlock[k]); } } return out; } /** {@inheritDoc} */ @Override public FieldMatrix scalarAdd(final T d) throws IllegalArgumentException { final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k].add(d); } } return out; } /** {@inheritDoc} */ @Override public FieldMatrix scalarMultiply(final T d) throws IllegalArgumentException { final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k].multiply(d); } } return out; } /** {@inheritDoc} */ @Override public FieldMatrix multiply(final FieldMatrix m) throws IllegalArgumentException { try { return multiply((BlockFieldMatrix) m); } catch (ClassCastException cce) { // safety check checkMultiplicationCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, m.getColumnDimension()); final T zero = getField().getZero(); // perform multiplication block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, m.getColumnDimension()); // select current block final T[] outBlock = out.blocks[blockIndex]; // perform multiplication on current block for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { final int kWidth = blockWidth(kBlock); final T[] tBlock = blocks[iBlock * blockColumns + kBlock]; final int rStart = kBlock * BLOCK_SIZE; int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lStart = (p - pStart) * kWidth; final int lEnd = lStart + kWidth; for (int q = qStart; q < qEnd; ++q) { T sum = zero; int r = rStart; for (int l = lStart; l < lEnd; ++l) { sum = sum.add(tBlock[l].multiply(m.getEntry(r, q))); ++r; } outBlock[k] = outBlock[k].add(sum); ++k; } } } // go to next block ++blockIndex; } } return out; } } /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BlockFieldMatrix multiply(BlockFieldMatrix m) throws IllegalArgumentException { // safety check checkMultiplicationCompatible(m); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, m.columns); final T zero = getField().getZero(); // perform multiplication block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int jWidth = out.blockWidth(jBlock); final int jWidth2 = jWidth + jWidth; final int jWidth3 = jWidth2 + jWidth; final int jWidth4 = jWidth3 + jWidth; // select current block final T[] outBlock = out.blocks[blockIndex]; // perform multiplication on current block for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { final int kWidth = blockWidth(kBlock); final T[] tBlock = blocks[iBlock * blockColumns + kBlock]; final T[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock]; int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lStart = (p - pStart) * kWidth; final int lEnd = lStart + kWidth; for (int nStart = 0; nStart < jWidth; ++nStart) { T sum = zero; int l = lStart; int n = nStart; while (l < lEnd - 3) { sum = sum. add(tBlock[l].multiply(mBlock[n])). add(tBlock[l + 1].multiply(mBlock[n + jWidth])). add(tBlock[l + 2].multiply(mBlock[n + jWidth2])). add(tBlock[l + 3].multiply(mBlock[n + jWidth3])); l += 4; n += jWidth4; } while (l < lEnd) { sum = sum.add(tBlock[l++].multiply(mBlock[n])); n += jWidth; } outBlock[k] = outBlock[k].add(sum); ++k; } } } // go to next block ++blockIndex; } } return out; } /** {@inheritDoc} */ @Override public T[][] getData() { final T[][] data = buildArray(getField(), getRowDimension(), getColumnDimension()); final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); int regularPos = 0; int lastPos = 0; for (int p = pStart; p < pEnd; ++p) { final T[] dataP = data[p]; int blockIndex = iBlock * blockColumns; int dataPos = 0; for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) { System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE); dataPos += BLOCK_SIZE; } System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns); regularPos += BLOCK_SIZE; lastPos += lastColumns; } } return data; } /** {@inheritDoc} */ @Override public FieldMatrix getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException { // safety checks checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); // create the output matrix final BlockFieldMatrix out = new BlockFieldMatrix(getField(), endRow - startRow + 1, endColumn - startColumn + 1); // compute blocks shifts final int blockStartRow = startRow / BLOCK_SIZE; final int rowsShift = startRow % BLOCK_SIZE; final int blockStartColumn = startColumn / BLOCK_SIZE; final int columnsShift = startColumn % BLOCK_SIZE; // perform extraction block-wise, to ensure good cache behavior int pBlock = blockStartRow; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int iHeight = out.blockHeight(iBlock); int qBlock = blockStartColumn; for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int jWidth = out.blockWidth(jBlock); // handle one block of the output matrix final int outIndex = iBlock * out.blockColumns + jBlock; final T[] outBlock = out.blocks[outIndex]; final int index = pBlock * blockColumns + qBlock; final int width = blockWidth(qBlock); final int heightExcess = iHeight + rowsShift - BLOCK_SIZE; final int widthExcess = jWidth + columnsShift - BLOCK_SIZE; if (heightExcess > 0) { // the submatrix block spans on two blocks rows from the original matrix if (widthExcess > 0) { // the submatrix block spans on two blocks columns from the original matrix final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, BLOCK_SIZE, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, BLOCK_SIZE, outBlock, jWidth, iHeight - heightExcess, 0); copyBlockPart(blocks[index + blockColumns + 1], width2, 0, heightExcess, 0, widthExcess, outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess); } else { // the submatrix block spans on one block column from the original matrix copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, jWidth + columnsShift, outBlock, jWidth, iHeight - heightExcess, 0); } } else { // the submatrix block spans on one block row from the original matrix if (widthExcess > 0) { // the submatrix block spans on two blocks columns from the original matrix final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, iHeight + rowsShift, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); } else { // the submatrix block spans on one block column from the original matrix copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); } } ++qBlock; } ++pBlock; } return out; } /** * Copy a part of a block into another one *

                    This method can be called only when the specified part fits in both * blocks, no verification is done here.

                    * @param srcBlock source block * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller) * @param srcStartRow start row in the source block * @param srcEndRow end row (exclusive) in the source block * @param srcStartColumn start column in the source block * @param srcEndColumn end column (exclusive) in the source block * @param dstBlock destination block * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller) * @param dstStartRow start row in the destination block * @param dstStartColumn start column in the destination block */ private void copyBlockPart(final T[] srcBlock, final int srcWidth, final int srcStartRow, final int srcEndRow, final int srcStartColumn, final int srcEndColumn, final T[] dstBlock, final int dstWidth, final int dstStartRow, final int dstStartColumn) { final int length = srcEndColumn - srcStartColumn; int srcPos = srcStartRow * srcWidth + srcStartColumn; int dstPos = dstStartRow * dstWidth + dstStartColumn; for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) { System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length); srcPos += srcWidth; dstPos += dstWidth; } } /** {@inheritDoc} */ @Override public void setSubMatrix(final T[][] subMatrix, final int row, final int column) throws MatrixIndexException { // safety checks final int refLength = subMatrix[0].length; if (refLength < 1) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } final int endRow = row + subMatrix.length - 1; final int endColumn = column + refLength - 1; checkSubMatrixIndex(row, endRow, column, endColumn); for (final T[] subRow : subMatrix) { if (subRow.length != refLength) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, refLength, subRow.length); } } // compute blocks bounds final int blockStartRow = row / BLOCK_SIZE; final int blockEndRow = (endRow + BLOCK_SIZE) / BLOCK_SIZE; final int blockStartColumn = column / BLOCK_SIZE; final int blockEndColumn = (endColumn + BLOCK_SIZE) / BLOCK_SIZE; // perform copy block-wise, to ensure good cache behavior for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) { final int iHeight = blockHeight(iBlock); final int firstRow = iBlock * BLOCK_SIZE; final int iStart = FastMath.max(row, firstRow); final int iEnd = FastMath.min(endRow + 1, firstRow + iHeight); for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) { final int jWidth = blockWidth(jBlock); final int firstColumn = jBlock * BLOCK_SIZE; final int jStart = FastMath.max(column, firstColumn); final int jEnd = FastMath.min(endColumn + 1, firstColumn + jWidth); final int jLength = jEnd - jStart; // handle one block, row by row final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = iStart; i < iEnd; ++i) { System.arraycopy(subMatrix[i - row], jStart - column, block, (i - firstRow) * jWidth + (jStart - firstColumn), jLength); } } } } /** {@inheritDoc} */ @Override public FieldMatrix getRowMatrix(final int row) throws MatrixIndexException { checkRowIndex(row); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), 1, columns); // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outBlockIndex = 0; int outIndex = 0; T[] outBlock = out.blocks[outBlockIndex]; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; final int available = outBlock.length - outIndex; if (jWidth > available) { System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available); outBlock = out.blocks[++outBlockIndex]; System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available); outIndex = jWidth - available; } else { System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth); outIndex += jWidth; } } return out; } /** {@inheritDoc} */ @Override public void setRowMatrix(final int row, final FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { try { setRowMatrix(row, (BlockFieldMatrix) matrix); } catch (ClassCastException cce) { super.setRowMatrix(row, matrix); } } /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param matrix row matrix (must have one row and the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance row */ public void setRowMatrix(final int row, final BlockFieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { checkRowIndex(row); final int nCols = getColumnDimension(); if ((matrix.getRowDimension() != 1) || (matrix.getColumnDimension() != nCols)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); } // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int mBlockIndex = 0; int mIndex = 0; T[] mBlock = matrix.blocks[mBlockIndex]; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; final int available = mBlock.length - mIndex; if (jWidth > available) { System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available); mBlock = matrix.blocks[++mBlockIndex]; System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available); mIndex = jWidth - available; } else { System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth); mIndex += jWidth; } } } /** {@inheritDoc} */ @Override public FieldMatrix getColumnMatrix(final int column) throws MatrixIndexException { checkColumnIndex(column); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), rows, 1); // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outBlockIndex = 0; int outIndex = 0; T[] outBlock = out.blocks[outBlockIndex]; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { if (outIndex >= outBlock.length) { outBlock = out.blocks[++outBlockIndex]; outIndex = 0; } outBlock[outIndex++] = block[i * jWidth + jColumn]; } } return out; } /** {@inheritDoc} */ @Override public void setColumnMatrix(final int column, final FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { try { setColumnMatrix(column, (BlockFieldMatrix) matrix); } catch (ClassCastException cce) { super.setColumnMatrix(column, matrix); } } /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param matrix column matrix (must have one column and the same number of rows * as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance column */ void setColumnMatrix(final int column, final BlockFieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException { checkColumnIndex(column); final int nRows = getRowDimension(); if ((matrix.getRowDimension() != nRows) || (matrix.getColumnDimension() != 1)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); } // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int mBlockIndex = 0; int mIndex = 0; T[] mBlock = matrix.blocks[mBlockIndex]; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { if (mIndex >= mBlock.length) { mBlock = matrix.blocks[++mBlockIndex]; mIndex = 0; } block[i * jWidth + jColumn] = mBlock[mIndex++]; } } } /** {@inheritDoc} */ @Override public FieldVector getRowVector(final int row) throws MatrixIndexException { checkRowIndex(row); final T[] outData = buildArray(getField(), columns); // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth); outIndex += jWidth; } return new ArrayFieldVector(outData, false); } /** {@inheritDoc} */ @Override public void setRowVector(final int row, final FieldVector vector) throws MatrixIndexException, InvalidMatrixException { try { setRow(row, ((ArrayFieldVector) vector).getDataRef()); } catch (ClassCastException cce) { super.setRowVector(row, vector); } } /** {@inheritDoc} */ @Override public FieldVector getColumnVector(final int column) throws MatrixIndexException { checkColumnIndex(column); final T[] outData = buildArray(getField(), rows); // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { outData[outIndex++] = block[i * jWidth + jColumn]; } } return new ArrayFieldVector(outData, false); } /** {@inheritDoc} */ @Override public void setColumnVector(final int column, final FieldVector vector) throws MatrixIndexException, InvalidMatrixException { try { setColumn(column, ((ArrayFieldVector) vector).getDataRef()); } catch (ClassCastException cce) { super.setColumnVector(column, vector); } } /** {@inheritDoc} */ @Override public T[] getRow(final int row) throws MatrixIndexException { checkRowIndex(row); final T[] out = buildArray(getField(), columns); // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth); outIndex += jWidth; } return out; } /** {@inheritDoc} */ @Override public void setRow(final int row, final T[] array) throws MatrixIndexException, InvalidMatrixException { checkRowIndex(row); final int nCols = getColumnDimension(); if (array.length != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, array.length, 1, nCols); } // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth); outIndex += jWidth; } } /** {@inheritDoc} */ @Override public T[] getColumn(final int column) throws MatrixIndexException { checkColumnIndex(column); final T[] out = buildArray(getField(), rows); // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { out[outIndex++] = block[i * jWidth + jColumn]; } } return out; } /** {@inheritDoc} */ @Override public void setColumn(final int column, final T[] array) throws MatrixIndexException, InvalidMatrixException { checkColumnIndex(column); final int nRows = getRowDimension(); if (array.length != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, array.length, 1, nRows, 1); } // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { block[i * jWidth + jColumn] = array[outIndex++]; } } } /** {@inheritDoc} */ @Override public T getEntry(final int row, final int column) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); return blocks[iBlock * blockColumns + jBlock][k]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void setEntry(final int row, final int column, final T value) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); blocks[iBlock * blockColumns + jBlock][k] = value; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void addToEntry(final int row, final int column, final T increment) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); final T[] blockIJ = blocks[iBlock * blockColumns + jBlock]; blockIJ[k] = blockIJ[k].add(increment); } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void multiplyEntry(final int row, final int column, final T factor) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); final T[] blockIJ = blocks[iBlock * blockColumns + jBlock]; blockIJ[k] = blockIJ[k].multiply(factor); } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public FieldMatrix transpose() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final BlockFieldMatrix out = new BlockFieldMatrix(getField(), nCols, nRows); // perform transpose block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < blockColumns; ++iBlock) { for (int jBlock = 0; jBlock < blockRows; ++jBlock) { // transpose current block final T[] outBlock = out.blocks[blockIndex]; final T[] tBlock = blocks[jBlock * blockColumns + iBlock]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, columns); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, rows); int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lInc = pEnd - pStart; int l = p - pStart; for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[l]; ++k; l+= lInc; } } // go to next block ++blockIndex; } } return out; } /** {@inheritDoc} */ @Override public int getRowDimension() { return rows; } /** {@inheritDoc} */ @Override public int getColumnDimension() { return columns; } /** {@inheritDoc} */ @Override public T[] operate(final T[] v) throws IllegalArgumentException { if (v.length != columns) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, columns); } final T[] out = buildArray(getField(), rows); final T zero = getField().getZero(); // perform multiplication block-wise, to ensure good cache behavior for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final T[] block = blocks[iBlock * blockColumns + jBlock]; final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { T sum = zero; int q = qStart; while (q < qEnd - 3) { sum = sum. add(block[k].multiply(v[q])). add(block[k + 1].multiply(v[q + 1])). add(block[k + 2].multiply(v[q + 2])). add(block[k + 3].multiply(v[q + 3])); k += 4; q += 4; } while (q < qEnd) { sum = sum.add(block[k++].multiply(v[q++])); } out[p] = out[p].add(sum); } } } return out; } /** {@inheritDoc} */ @Override public T[] preMultiply(final T[] v) throws IllegalArgumentException { if (v.length != rows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, rows); } final T[] out = buildArray(getField(), columns); final T zero = getField().getZero(); // perform multiplication block-wise, to ensure good cache behavior for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int jWidth2 = jWidth + jWidth; final int jWidth3 = jWidth2 + jWidth; final int jWidth4 = jWidth3 + jWidth; final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final T[] block = blocks[iBlock * blockColumns + jBlock]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int q = qStart; q < qEnd; ++q) { int k = q - qStart; T sum = zero; int p = pStart; while (p < pEnd - 3) { sum = sum. add(block[k].multiply(v[p])). add(block[k + jWidth].multiply(v[p + 1])). add(block[k + jWidth2].multiply(v[p + 2])). add(block[k + jWidth3].multiply(v[p + 3])); k += jWidth4; p += 4; } while (p < pEnd) { sum = sum.add(block[k].multiply(v[p++])); k += jWidth; } out[q] = out[q].add(sum); } } } return out; } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final T[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - pStart) * jWidth; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final T[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - pStart) * jWidth; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final T[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInRowOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final T[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInOptimizedOrder(final FieldMatrixChangingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final T[] block = blocks[blockIndex]; int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } ++blockIndex; } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final T[] block = blocks[blockIndex]; int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } ++blockIndex; } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInOptimizedOrder(final FieldMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int p = pStart; p < pEnd; ++p) { int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final T[] block = blocks[iBlock * blockColumns + jBlock]; for (int p = pStart; p < pEnd; ++p) { int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** * Get the height of a block. * @param blockRow row index (in block sense) of the block * @return height (number of rows) of the block */ private int blockHeight(final int blockRow) { return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE; } /** * Get the width of a block. * @param blockColumn column index (in block sense) of the block * @return width (number of columns) of the block */ private int blockWidth(final int blockColumn) { return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/NonSquareMatrixException.java100644 1750 1750 3143 11532241245 31441 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Thrown when an operation defined only for square matrices is applied to non-square ones. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class NonSquareMatrixException extends InvalidMatrixException { /** Serializable version identifier. */ private static final long serialVersionUID = 8996207526636673730L; /** * Construct an exception with the given message. * @param rows number of rows of the faulty matrix * @param columns number of columns of the faulty matrix */ public NonSquareMatrixException(final int rows, final int columns) { super(LocalizedFormats.NON_SQUARE_MATRIX, rows, columns); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java100644 1750 1750 30746 11532241245 31653 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Calculates the Cholesky decomposition of a matrix. *

                    The Cholesky decomposition of a real symmetric positive-definite * matrix A consists of a lower triangular matrix L with same size that * satisfy: A = LLTQ = I). In a sense, this is the square root of A.

                    * * @see MathWorld * @see Wikipedia * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class CholeskyDecompositionImpl implements CholeskyDecomposition { /** Default threshold above which off-diagonal elements are considered too different * and matrix not symmetric. */ public static final double DEFAULT_RELATIVE_SYMMETRY_THRESHOLD = 1.0e-15; /** Default threshold below which diagonal elements are considered null * and matrix not positive definite. */ public static final double DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD = 1.0e-10; /** Row-oriented storage for LT matrix data. */ private double[][] lTData; /** Cached value of L. */ private RealMatrix cachedL; /** Cached value of LT. */ private RealMatrix cachedLT; /** * Calculates the Cholesky decomposition of the given matrix. *

                    * Calling this constructor is equivalent to call {@link * #CholeskyDecompositionImpl(RealMatrix, double, double)} with the * thresholds set to the default values {@link * #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD} and {@link * #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD} *

                    * @param matrix the matrix to decompose * @exception NonSquareMatrixException if matrix is not square * @exception NotSymmetricMatrixException if matrix is not symmetric * @exception NotPositiveDefiniteMatrixException if the matrix is not * strictly positive definite * @see #CholeskyDecompositionImpl(RealMatrix, double, double) * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD */ public CholeskyDecompositionImpl(final RealMatrix matrix) throws NonSquareMatrixException, NotSymmetricMatrixException, NotPositiveDefiniteMatrixException { this(matrix, DEFAULT_RELATIVE_SYMMETRY_THRESHOLD, DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD); } /** * Calculates the Cholesky decomposition of the given matrix. * @param matrix the matrix to decompose * @param relativeSymmetryThreshold threshold above which off-diagonal * elements are considered too different and matrix not symmetric * @param absolutePositivityThreshold threshold below which diagonal * elements are considered null and matrix not positive definite * @exception NonSquareMatrixException if matrix is not square * @exception NotSymmetricMatrixException if matrix is not symmetric * @exception NotPositiveDefiniteMatrixException if the matrix is not * strictly positive definite * @see #CholeskyDecompositionImpl(RealMatrix) * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD */ public CholeskyDecompositionImpl(final RealMatrix matrix, final double relativeSymmetryThreshold, final double absolutePositivityThreshold) throws NonSquareMatrixException, NotSymmetricMatrixException, NotPositiveDefiniteMatrixException { if (!matrix.isSquare()) { throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); } final int order = matrix.getRowDimension(); lTData = matrix.getData(); cachedL = null; cachedLT = null; // check the matrix before transformation for (int i = 0; i < order; ++i) { final double[] lI = lTData[i]; // check off-diagonal elements (and reset them to 0) for (int j = i + 1; j < order; ++j) { final double[] lJ = lTData[j]; final double lIJ = lI[j]; final double lJI = lJ[i]; final double maxDelta = relativeSymmetryThreshold * FastMath.max(FastMath.abs(lIJ), FastMath.abs(lJI)); if (FastMath.abs(lIJ - lJI) > maxDelta) { throw new NotSymmetricMatrixException(); } lJ[i] = 0; } } // transform the matrix for (int i = 0; i < order; ++i) { final double[] ltI = lTData[i]; // check diagonal element if (ltI[i] < absolutePositivityThreshold) { throw new NotPositiveDefiniteMatrixException(); } ltI[i] = FastMath.sqrt(ltI[i]); final double inverse = 1.0 / ltI[i]; for (int q = order - 1; q > i; --q) { ltI[q] *= inverse; final double[] ltQ = lTData[q]; for (int p = q; p < order; ++p) { ltQ[p] -= ltI[q] * ltI[p]; } } } } /** {@inheritDoc} */ public RealMatrix getL() { if (cachedL == null) { cachedL = getLT().transpose(); } return cachedL; } /** {@inheritDoc} */ public RealMatrix getLT() { if (cachedLT == null) { cachedLT = MatrixUtils.createRealMatrix(lTData); } // return the cached matrix return cachedLT; } /** {@inheritDoc} */ public double getDeterminant() { double determinant = 1.0; for (int i = 0; i < lTData.length; ++i) { double lTii = lTData[i][i]; determinant *= lTii * lTii; } return determinant; } /** {@inheritDoc} */ public DecompositionSolver getSolver() { return new Solver(lTData); } /** Specialized solver. */ private static class Solver implements DecompositionSolver { /** Row-oriented storage for LT matrix data. */ private final double[][] lTData; /** * Build a solver from decomposed matrix. * @param lTData row-oriented storage for LT matrix data */ private Solver(final double[][] lTData) { this.lTData = lTData; } /** {@inheritDoc} */ public boolean isNonSingular() { // if we get this far, the matrix was positive definite, hence non-singular return true; } /** {@inheritDoc} */ public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { final int m = lTData.length; if (b.length != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m); } final double[] x = b.clone(); // Solve LY = b for (int j = 0; j < m; j++) { final double[] lJ = lTData[j]; x[j] /= lJ[j]; final double xJ = x[j]; for (int i = j + 1; i < m; i++) { x[i] -= xJ * lJ[i]; } } // Solve LTX = Y for (int j = m - 1; j >= 0; j--) { x[j] /= lTData[j][j]; final double xJ = x[j]; for (int i = 0; i < j; i++) { x[i] -= xJ * lTData[i][j]; } } return x; } /** {@inheritDoc} */ public RealVector solve(RealVector b) throws IllegalArgumentException, InvalidMatrixException { try { return solve((ArrayRealVector) b); } catch (ClassCastException cce) { final int m = lTData.length; if (b.getDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.getDimension(), m); } final double[] x = b.getData(); // Solve LY = b for (int j = 0; j < m; j++) { final double[] lJ = lTData[j]; x[j] /= lJ[j]; final double xJ = x[j]; for (int i = j + 1; i < m; i++) { x[i] -= xJ * lJ[i]; } } // Solve LTX = Y for (int j = m - 1; j >= 0; j--) { x[j] /= lTData[j][j]; final double xJ = x[j]; for (int i = 0; i < j; i++) { x[i] -= xJ * lTData[i][j]; } } return new ArrayRealVector(x, false); } } /** Solve the linear equation A × X = B. *

                    The A matrix is implicit here. It is

                    * @param b right-hand side of the equation A × X = B * @return a vector X such that A × X = B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ public ArrayRealVector solve(ArrayRealVector b) throws IllegalArgumentException, InvalidMatrixException { return new ArrayRealVector(solve(b.getDataRef()), false); } /** {@inheritDoc} */ public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException { final int m = lTData.length; if (b.getRowDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), m, "n"); } final int nColB = b.getColumnDimension(); double[][] x = b.getData(); // Solve LY = b for (int j = 0; j < m; j++) { final double[] lJ = lTData[j]; final double lJJ = lJ[j]; final double[] xJ = x[j]; for (int k = 0; k < nColB; ++k) { xJ[k] /= lJJ; } for (int i = j + 1; i < m; i++) { final double[] xI = x[i]; final double lJI = lJ[i]; for (int k = 0; k < nColB; ++k) { xI[k] -= xJ[k] * lJI; } } } // Solve LTX = Y for (int j = m - 1; j >= 0; j--) { final double lJJ = lTData[j][j]; final double[] xJ = x[j]; for (int k = 0; k < nColB; ++k) { xJ[k] /= lJJ; } for (int i = 0; i < j; i++) { final double[] xI = x[i]; final double lIJ = lTData[i][j]; for (int k = 0; k < nColB; ++k) { xI[k] -= xJ[k] * lIJ; } } } return new Array2DRowRealMatrix(x, false); } /** {@inheritDoc} */ public RealMatrix getInverse() throws InvalidMatrixException { return solve(MatrixUtils.createRealIdentityMatrix(lTData.length)); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/MatrixUtils.java100644 1750 1750 113221 11532241245 27006 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Array; import java.math.BigDecimal; import java.util.Arrays; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.fraction.Fraction; /** * A collection of static methods that operate on or return matrices. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class MatrixUtils { /** * Private constructor. */ private MatrixUtils() { super(); } /** * Returns a {@link RealMatrix} with specified dimensions. *

                    The type of matrix returned depends on the dimension. Below * 212 elements (i.e. 4096 elements or 64×64 for a * square matrix) which can be stored in a 32kB array, a {@link * Array2DRowRealMatrix} instance is built. Above this threshold a {@link * BlockRealMatrix} instance is built.

                    *

                    The matrix elements are all set to 0.0.

                    * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @return RealMatrix with specified dimensions * @see #createRealMatrix(double[][]) */ public static RealMatrix createRealMatrix(final int rows, final int columns) { return (rows * columns <= 4096) ? new Array2DRowRealMatrix(rows, columns) : new BlockRealMatrix(rows, columns); } /** * Returns a {@link FieldMatrix} with specified dimensions. *

                    The type of matrix returned depends on the dimension. Below * 212 elements (i.e. 4096 elements or 64×64 for a * square matrix), a {@link FieldMatrix} instance is built. Above * this threshold a {@link BlockFieldMatrix} instance is built.

                    *

                    The matrix elements are all set to field.getZero().

                    * @param the type of the field elements * @param field field to which the matrix elements belong * @param rows number of rows of the matrix * @param columns number of columns of the matrix * @return FieldMatrix with specified dimensions * @see #createFieldMatrix(FieldElement[][]) * @since 2.0 */ public static > FieldMatrix createFieldMatrix(final Field field, final int rows, final int columns) { return (rows * columns <= 4096) ? new Array2DRowFieldMatrix(field, rows, columns) : new BlockFieldMatrix(field, rows, columns); } /** * Returns a {@link RealMatrix} whose entries are the the values in the * the input array. *

                    The type of matrix returned depends on the dimension. Below * 212 elements (i.e. 4096 elements or 64×64 for a * square matrix) which can be stored in a 32kB array, a {@link * Array2DRowRealMatrix} instance is built. Above this threshold a {@link * BlockRealMatrix} instance is built.

                    *

                    The input array is copied, not referenced.

                    * * @param data input array * @return RealMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if either data or * data[0] is null * @see #createRealMatrix(int, int) */ public static RealMatrix createRealMatrix(double[][] data) { return (data.length * data[0].length <= 4096) ? new Array2DRowRealMatrix(data) : new BlockRealMatrix(data); } /** * Returns a {@link FieldMatrix} whose entries are the the values in the * the input array. *

                    The type of matrix returned depends on the dimension. Below * 212 elements (i.e. 4096 elements or 64×64 for a * square matrix), a {@link FieldMatrix} instance is built. Above * this threshold a {@link BlockFieldMatrix} instance is built.

                    *

                    The input array is copied, not referenced.

                    * @param the type of the field elements * @param data input array * @return RealMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if either data or * data[0] is null * @see #createFieldMatrix(Field, int, int) * @since 2.0 */ public static > FieldMatrix createFieldMatrix(T[][] data) { return (data.length * data[0].length <= 4096) ? new Array2DRowFieldMatrix(data) : new BlockFieldMatrix(data); } /** * Returns dimension x dimension identity matrix. * * @param dimension dimension of identity matrix to generate * @return identity matrix * @throws IllegalArgumentException if dimension is not positive * @since 1.1 */ public static RealMatrix createRealIdentityMatrix(int dimension) { final RealMatrix m = createRealMatrix(dimension, dimension); for (int i = 0; i < dimension; ++i) { m.setEntry(i, i, 1.0); } return m; } /** * Returns dimension x dimension identity matrix. * * @param the type of the field elements * @param field field to which the elements belong * @param dimension dimension of identity matrix to generate * @return identity matrix * @throws IllegalArgumentException if dimension is not positive * @since 2.0 */ public static > FieldMatrix createFieldIdentityMatrix(final Field field, final int dimension) { final T zero = field.getZero(); final T one = field.getOne(); @SuppressWarnings("unchecked") // zero is type T final T[][] d = (T[][]) Array.newInstance(zero.getClass(), new int[] { dimension, dimension }); for (int row = 0; row < dimension; row++) { final T[] dRow = d[row]; Arrays.fill(dRow, zero); dRow[row] = one; } return new Array2DRowFieldMatrix(d, false); } /** * Returns dimension x dimension identity matrix. * * @param dimension dimension of identity matrix to generate * @return identity matrix * @throws IllegalArgumentException if dimension is not positive * @since 1.1 * @deprecated since 2.0, replaced by {@link #createFieldIdentityMatrix(Field, int)} */ @Deprecated public static BigMatrix createBigIdentityMatrix(int dimension) { final BigDecimal[][] d = new BigDecimal[dimension][dimension]; for (int row = 0; row < dimension; row++) { final BigDecimal[] dRow = d[row]; Arrays.fill(dRow, BigMatrixImpl.ZERO); dRow[row] = BigMatrixImpl.ONE; } return new BigMatrixImpl(d, false); } /** * Returns a diagonal matrix with specified elements. * * @param diagonal diagonal elements of the matrix (the array elements * will be copied) * @return diagonal matrix * @since 2.0 */ public static RealMatrix createRealDiagonalMatrix(final double[] diagonal) { final RealMatrix m = createRealMatrix(diagonal.length, diagonal.length); for (int i = 0; i < diagonal.length; ++i) { m.setEntry(i, i, diagonal[i]); } return m; } /** * Returns a diagonal matrix with specified elements. * * @param the type of the field elements * @param diagonal diagonal elements of the matrix (the array elements * will be copied) * @return diagonal matrix * @since 2.0 */ public static > FieldMatrix createFieldDiagonalMatrix(final T[] diagonal) { final FieldMatrix m = createFieldMatrix(diagonal[0].getField(), diagonal.length, diagonal.length); for (int i = 0; i < diagonal.length; ++i) { m.setEntry(i, i, diagonal[i]); } return m; } /** * Returns a {@link BigMatrix} whose entries are the the values in the * the input array. The input array is copied, not referenced. * * @param data input array * @return RealMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if data is null * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} */ @Deprecated public static BigMatrix createBigMatrix(double[][] data) { return new BigMatrixImpl(data); } /** * Returns a {@link BigMatrix} whose entries are the the values in the * the input array. The input array is copied, not referenced. * * @param data input array * @return RealMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if data is null * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} */ @Deprecated public static BigMatrix createBigMatrix(BigDecimal[][] data) { return new BigMatrixImpl(data); } /** * Returns a {@link BigMatrix} whose entries are the the values in the * the input array. *

                    If an array is built specially in order to be embedded in a * BigMatrix and not used directly, the copyArray may be * set to false * @param data data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @return BigMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if data is null * @see #createRealMatrix(double[][]) * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} */ @Deprecated public static BigMatrix createBigMatrix(BigDecimal[][] data, boolean copyArray) { return new BigMatrixImpl(data, copyArray); } /** * Returns a {@link BigMatrix} whose entries are the the values in the * the input array. The input array is copied, not referenced. * * @param data input array * @return RealMatrix containing the values of the array * @throws IllegalArgumentException if data is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if data is null * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} */ @Deprecated public static BigMatrix createBigMatrix(String[][] data) { return new BigMatrixImpl(data); } /** * Creates a {@link RealVector} using the data from the input array. * * @param data the input data * @return a data.length RealVector * @throws IllegalArgumentException if data is empty * @throws NullPointerException if datais null */ public static RealVector createRealVector(double[] data) { return new ArrayRealVector(data, true); } /** * Creates a {@link FieldVector} using the data from the input array. * * @param the type of the field elements * @param data the input data * @return a data.length FieldVector * @throws IllegalArgumentException if data is empty * @throws NullPointerException if datais null */ public static > FieldVector createFieldVector(final T[] data) { return new ArrayFieldVector(data, true); } /** * Creates a row {@link RealMatrix} using the data from the input * array. * * @param rowData the input row data * @return a 1 x rowData.length RealMatrix * @throws IllegalArgumentException if rowData is empty * @throws NullPointerException if rowDatais null */ public static RealMatrix createRowRealMatrix(double[] rowData) { final int nCols = rowData.length; final RealMatrix m = createRealMatrix(1, nCols); for (int i = 0; i < nCols; ++i) { m.setEntry(0, i, rowData[i]); } return m; } /** * Creates a row {@link FieldMatrix} using the data from the input * array. * * @param the type of the field elements * @param rowData the input row data * @return a 1 x rowData.length FieldMatrix * @throws IllegalArgumentException if rowData is empty * @throws NullPointerException if rowDatais null */ public static > FieldMatrix createRowFieldMatrix(final T[] rowData) { final int nCols = rowData.length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } final FieldMatrix m = createFieldMatrix(rowData[0].getField(), 1, nCols); for (int i = 0; i < nCols; ++i) { m.setEntry(0, i, rowData[i]); } return m; } /** * Creates a row {@link BigMatrix} using the data from the input * array. * * @param rowData the input row data * @return a 1 x rowData.length BigMatrix * @throws IllegalArgumentException if rowData is empty * @throws NullPointerException if rowDatais null * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createRowBigMatrix(double[] rowData) { final int nCols = rowData.length; final BigDecimal[][] data = new BigDecimal[1][nCols]; for (int i = 0; i < nCols; ++i) { data[0][i] = new BigDecimal(rowData[i]); } return new BigMatrixImpl(data, false); } /** * Creates a row {@link BigMatrix} using the data from the input * array. * * @param rowData the input row data * @return a 1 x rowData.length BigMatrix * @throws IllegalArgumentException if rowData is empty * @throws NullPointerException if rowDatais null * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createRowBigMatrix(BigDecimal[] rowData) { final int nCols = rowData.length; final BigDecimal[][] data = new BigDecimal[1][nCols]; System.arraycopy(rowData, 0, data[0], 0, nCols); return new BigMatrixImpl(data, false); } /** * Creates a row {@link BigMatrix} using the data from the input * array. * * @param rowData the input row data * @return a 1 x rowData.length BigMatrix * @throws IllegalArgumentException if rowData is empty * @throws NullPointerException if rowDatais null * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createRowBigMatrix(String[] rowData) { final int nCols = rowData.length; final BigDecimal[][] data = new BigDecimal[1][nCols]; for (int i = 0; i < nCols; ++i) { data[0][i] = new BigDecimal(rowData[i]); } return new BigMatrixImpl(data, false); } /** * Creates a column {@link RealMatrix} using the data from the input * array. * * @param columnData the input column data * @return a columnData x 1 RealMatrix * @throws IllegalArgumentException if columnData is empty * @throws NullPointerException if columnDatais null */ public static RealMatrix createColumnRealMatrix(double[] columnData) { final int nRows = columnData.length; final RealMatrix m = createRealMatrix(nRows, 1); for (int i = 0; i < nRows; ++i) { m.setEntry(i, 0, columnData[i]); } return m; } /** * Creates a column {@link FieldMatrix} using the data from the input * array. * * @param the type of the field elements * @param columnData the input column data * @return a columnData x 1 FieldMatrix * @throws IllegalArgumentException if columnData is empty * @throws NullPointerException if columnDatais null */ public static > FieldMatrix createColumnFieldMatrix(final T[] columnData) { final int nRows = columnData.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final FieldMatrix m = createFieldMatrix(columnData[0].getField(), nRows, 1); for (int i = 0; i < nRows; ++i) { m.setEntry(i, 0, columnData[i]); } return m; } /** * Creates a column {@link BigMatrix} using the data from the input * array. * * @param columnData the input column data * @return a columnData x 1 BigMatrix * @throws IllegalArgumentException if columnData is empty * @throws NullPointerException if columnDatais null * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createColumnBigMatrix(double[] columnData) { final int nRows = columnData.length; final BigDecimal[][] data = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = new BigDecimal(columnData[row]); } return new BigMatrixImpl(data, false); } /** * Creates a column {@link BigMatrix} using the data from the input * array. * * @param columnData the input column data * @return a columnData x 1 BigMatrix * @throws IllegalArgumentException if columnData is empty * @throws NullPointerException if columnDatais null * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createColumnBigMatrix(BigDecimal[] columnData) { final int nRows = columnData.length; final BigDecimal[][] data = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = columnData[row]; } return new BigMatrixImpl(data, false); } /** * Creates a column {@link BigMatrix} using the data from the input * array. * * @param columnData the input column data * @return a columnData x 1 BigMatrix * @throws IllegalArgumentException if columnData is empty * @throws NullPointerException if columnDatais null * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} */ @Deprecated public static BigMatrix createColumnBigMatrix(String[] columnData) { int nRows = columnData.length; final BigDecimal[][] data = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = new BigDecimal(columnData[row]); } return new BigMatrixImpl(data, false); } /** * Check if a row index is valid. * @param m matrix containing the submatrix * @param row row index to check * @exception MatrixIndexException if index is not valid */ public static void checkRowIndex(final AnyMatrix m, final int row) { if (row < 0 || row >= m.getRowDimension()) { throw new MatrixIndexException(LocalizedFormats.ROW_INDEX_OUT_OF_RANGE, row, 0, m.getRowDimension() - 1); } } /** * Check if a column index is valid. * @param m matrix containing the submatrix * @param column column index to check * @exception MatrixIndexException if index is not valid */ public static void checkColumnIndex(final AnyMatrix m, final int column) throws MatrixIndexException { if (column < 0 || column >= m.getColumnDimension()) { throw new MatrixIndexException(LocalizedFormats.COLUMN_INDEX_OUT_OF_RANGE, column, 0, m.getColumnDimension() - 1); } } /** * Check if submatrix ranges indices are valid. * Rows and columns are indicated counting from 0 to n-1. * * @param m matrix containing the submatrix * @param startRow Initial row index * @param endRow Final row index * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixIndexException if the indices are not valid */ public static void checkSubMatrixIndex(final AnyMatrix m, final int startRow, final int endRow, final int startColumn, final int endColumn) { checkRowIndex(m, startRow); checkRowIndex(m, endRow); if (startRow > endRow) { throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW, startRow, endRow); } checkColumnIndex(m, startColumn); checkColumnIndex(m, endColumn); if (startColumn > endColumn) { throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN, startColumn, endColumn); } } /** * Check if submatrix ranges indices are valid. * Rows and columns are indicated counting from 0 to n-1. * * @param m matrix containing the submatrix * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @exception MatrixIndexException if row or column selections are not valid */ public static void checkSubMatrixIndex(final AnyMatrix m, final int[] selectedRows, final int[] selectedColumns) throws MatrixIndexException { if (selectedRows.length * selectedColumns.length == 0) { if (selectedRows.length == 0) { throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY); } throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY); } for (final int row : selectedRows) { checkRowIndex(m, row); } for (final int column : selectedColumns) { checkColumnIndex(m, column); } } /** * Check if matrices are addition compatible * @param left left hand side matrix * @param right right hand side matrix * @exception IllegalArgumentException if matrices are not addition compatible */ public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right) throws IllegalArgumentException { if ((left.getRowDimension() != right.getRowDimension()) || (left.getColumnDimension() != right.getColumnDimension())) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_ADDITION_COMPATIBLE_MATRICES, left.getRowDimension(), left.getColumnDimension(), right.getRowDimension(), right.getColumnDimension()); } } /** * Check if matrices are subtraction compatible * @param left left hand side matrix * @param right right hand side matrix * @exception IllegalArgumentException if matrices are not subtraction compatible */ public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right) throws IllegalArgumentException { if ((left.getRowDimension() != right.getRowDimension()) || (left.getColumnDimension() != right.getColumnDimension())) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_SUBTRACTION_COMPATIBLE_MATRICES, left.getRowDimension(), left.getColumnDimension(), right.getRowDimension(), right.getColumnDimension()); } } /** * Check if matrices are multiplication compatible * @param left left hand side matrix * @param right right hand side matrix * @exception IllegalArgumentException if matrices are not multiplication compatible */ public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right) throws IllegalArgumentException { if (left.getColumnDimension() != right.getRowDimension()) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_MULTIPLICATION_COMPATIBLE_MATRICES, left.getRowDimension(), left.getColumnDimension(), right.getRowDimension(), right.getColumnDimension()); } } /** * Convert a {@link FieldMatrix}/{@link Fraction} matrix to a {@link RealMatrix}. * @param m matrix to convert * @return converted matrix */ public static Array2DRowRealMatrix fractionMatrixToRealMatrix(final FieldMatrix m) { final FractionMatrixConverter converter = new FractionMatrixConverter(); m.walkInOptimizedOrder(converter); return converter.getConvertedMatrix(); } /** Converter for {@link FieldMatrix}/{@link Fraction}. */ private static class FractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor { /** Converted array. */ private double[][] data; /** Simple constructor. */ public FractionMatrixConverter() { super(Fraction.ZERO); } /** {@inheritDoc} */ @Override public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { data = new double[rows][columns]; } /** {@inheritDoc} */ @Override public void visit(int row, int column, Fraction value) { data[row][column] = value.doubleValue(); } /** Get the converted matrix. * @return converted matrix */ Array2DRowRealMatrix getConvertedMatrix() { return new Array2DRowRealMatrix(data, false); } } /** * Convert a {@link FieldMatrix}/{@link BigFraction} matrix to a {@link RealMatrix}. * @param m matrix to convert * @return converted matrix */ public static Array2DRowRealMatrix bigFractionMatrixToRealMatrix(final FieldMatrix m) { final BigFractionMatrixConverter converter = new BigFractionMatrixConverter(); m.walkInOptimizedOrder(converter); return converter.getConvertedMatrix(); } /** Converter for {@link FieldMatrix}/{@link BigFraction}. */ private static class BigFractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor { /** Converted array. */ private double[][] data; /** Simple constructor. */ public BigFractionMatrixConverter() { super(BigFraction.ZERO); } /** {@inheritDoc} */ @Override public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { data = new double[rows][columns]; } /** {@inheritDoc} */ @Override public void visit(int row, int column, BigFraction value) { data[row][column] = value.doubleValue(); } /** Get the converted matrix. * @return converted matrix */ Array2DRowRealMatrix getConvertedMatrix() { return new Array2DRowRealMatrix(data, false); } } /** Serialize a {@link RealVector}. *

                    * This method is intended to be called from within a private * writeObject method (after a call to * oos.defaultWriteObject()) in a class that has a * {@link RealVector} field, which should be declared transient. * This way, the default handling does not serialize the vector (the {@link * RealVector} interface is not serializable by default) but this method does * serialize it specifically. *

                    *

                    * The following example shows how a simple class with a name and a real vector * should be written: *

                    
                         * public class NamedVector implements Serializable {
                         *
                         *     private final String name;
                         *     private final transient RealVector coefficients;
                         *
                         *     // omitted constructors, getters ...
                         *
                         *     private void writeObject(ObjectOutputStream oos) throws IOException {
                         *         oos.defaultWriteObject();  // takes care of name field
                         *         MatrixUtils.serializeRealVector(coefficients, oos);
                         *     }
                         *
                         *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
                         *         ois.defaultReadObject();  // takes care of name field
                         *         MatrixUtils.deserializeRealVector(this, "coefficients", ois);
                         *     }
                         *
                         * }
                         * 
                    *

                    * * @param vector real vector to serialize * @param oos stream where the real vector should be written * @exception IOException if object cannot be written to stream * @see #deserializeRealVector(Object, String, ObjectInputStream) */ public static void serializeRealVector(final RealVector vector, final ObjectOutputStream oos) throws IOException { final int n = vector.getDimension(); oos.writeInt(n); for (int i = 0; i < n; ++i) { oos.writeDouble(vector.getEntry(i)); } } /** Deserialize a {@link RealVector} field in a class. *

                    * This method is intended to be called from within a private * readObject method (after a call to * ois.defaultReadObject()) in a class that has a * {@link RealVector} field, which should be declared transient. * This way, the default handling does not deserialize the vector (the {@link * RealVector} interface is not serializable by default) but this method does * deserialize it specifically. *

                    * @param instance instance in which the field must be set up * @param fieldName name of the field within the class (may be private and final) * @param ois stream from which the real vector should be read * @exception ClassNotFoundException if a class in the stream cannot be found * @exception IOException if object cannot be read from the stream * @see #serializeRealVector(RealVector, ObjectOutputStream) */ public static void deserializeRealVector(final Object instance, final String fieldName, final ObjectInputStream ois) throws ClassNotFoundException, IOException { try { // read the vector data final int n = ois.readInt(); final double[] data = new double[n]; for (int i = 0; i < n; ++i) { data[i] = ois.readDouble(); } // create the instance final RealVector vector = new ArrayRealVector(data, false); // set up the field final java.lang.reflect.Field f = instance.getClass().getDeclaredField(fieldName); f.setAccessible(true); f.set(instance, vector); } catch (NoSuchFieldException nsfe) { IOException ioe = new IOException(); ioe.initCause(nsfe); throw ioe; } catch (IllegalAccessException iae) { IOException ioe = new IOException(); ioe.initCause(iae); throw ioe; } } /** Serialize a {@link RealMatrix}. *

                    * This method is intended to be called from within a private * writeObject method (after a call to * oos.defaultWriteObject()) in a class that has a * {@link RealMatrix} field, which should be declared transient. * This way, the default handling does not serialize the matrix (the {@link * RealMatrix} interface is not serializable by default) but this method does * serialize it specifically. *

                    *

                    * The following example shows how a simple class with a name and a real matrix * should be written: *

                    
                         * public class NamedMatrix implements Serializable {
                         *
                         *     private final String name;
                         *     private final transient RealMatrix coefficients;
                         *
                         *     // omitted constructors, getters ...
                         *
                         *     private void writeObject(ObjectOutputStream oos) throws IOException {
                         *         oos.defaultWriteObject();  // takes care of name field
                         *         MatrixUtils.serializeRealMatrix(coefficients, oos);
                         *     }
                         *
                         *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
                         *         ois.defaultReadObject();  // takes care of name field
                         *         MatrixUtils.deserializeRealMatrix(this, "coefficients", ois);
                         *     }
                         *
                         * }
                         * 
                    *

                    * * @param matrix real matrix to serialize * @param oos stream where the real matrix should be written * @exception IOException if object cannot be written to stream * @see #deserializeRealMatrix(Object, String, ObjectInputStream) */ public static void serializeRealMatrix(final RealMatrix matrix, final ObjectOutputStream oos) throws IOException { final int n = matrix.getRowDimension(); final int m = matrix.getColumnDimension(); oos.writeInt(n); oos.writeInt(m); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { oos.writeDouble(matrix.getEntry(i, j)); } } } /** Deserialize a {@link RealMatrix} field in a class. *

                    * This method is intended to be called from within a private * readObject method (after a call to * ois.defaultReadObject()) in a class that has a * {@link RealMatrix} field, which should be declared transient. * This way, the default handling does not deserialize the matrix (the {@link * RealMatrix} interface is not serializable by default) but this method does * deserialize it specifically. *

                    * @param instance instance in which the field must be set up * @param fieldName name of the field within the class (may be private and final) * @param ois stream from which the real matrix should be read * @exception ClassNotFoundException if a class in the stream cannot be found * @exception IOException if object cannot be read from the stream * @see #serializeRealMatrix(RealMatrix, ObjectOutputStream) */ public static void deserializeRealMatrix(final Object instance, final String fieldName, final ObjectInputStream ois) throws ClassNotFoundException, IOException { try { // read the matrix data final int n = ois.readInt(); final int m = ois.readInt(); final double[][] data = new double[n][m]; for (int i = 0; i < n; ++i) { final double[] dataI = data[i]; for (int j = 0; j < m; ++j) { dataI[j] = ois.readDouble(); } } // create the instance final RealMatrix matrix = new Array2DRowRealMatrix(data, false); // set up the field final java.lang.reflect.Field f = instance.getClass().getDeclaredField(fieldName); f.setAccessible(true); f.set(instance, matrix); } catch (NoSuchFieldException nsfe) { IOException ioe = new IOException(); ioe.initCause(nsfe); throw ioe; } catch (IllegalAccessException iae) { IOException ioe = new IOException(); ioe.initCause(iae); throw ioe; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/BiDiagonalTransformer.java100644 1750 1750 32267 11532241245 30727 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.util.FastMath; /** * Class transforming any matrix to bi-diagonal shape. *

                    Any m × n matrix A can be written as the product of three matrices: * A = U × B × VT with U an m × m orthogonal matrix, * B an m × n bi-diagonal matrix (lower diagonal if m < n, upper diagonal * otherwise), and V an n × n orthogonal matrix.

                    *

                    Transformation to bi-diagonal shape is often not a goal by itself, but it is * an intermediate step in more general decomposition algorithms like {@link * SingularValueDecomposition Singular Value Decomposition}. This class is therefore * intended for internal use by the library and is not public. As a consequence of * this explicitly limited scope, many methods directly returns references to * internal arrays, not copies.

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ class BiDiagonalTransformer { /** Householder vectors. */ private final double householderVectors[][]; /** Main diagonal. */ private final double[] main; /** Secondary diagonal. */ private final double[] secondary; /** Cached value of U. */ private RealMatrix cachedU; /** Cached value of B. */ private RealMatrix cachedB; /** Cached value of V. */ private RealMatrix cachedV; /** * Build the transformation to bi-diagonal shape of a matrix. * @param matrix the matrix to transform. */ public BiDiagonalTransformer(RealMatrix matrix) { final int m = matrix.getRowDimension(); final int n = matrix.getColumnDimension(); final int p = FastMath.min(m, n); householderVectors = matrix.getData(); main = new double[p]; secondary = new double[p - 1]; cachedU = null; cachedB = null; cachedV = null; // transform matrix if (m >= n) { transformToUpperBiDiagonal(); } else { transformToLowerBiDiagonal(); } } /** * Returns the matrix U of the transform. *

                    U is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the U matrix */ public RealMatrix getU() { if (cachedU == null) { final int m = householderVectors.length; final int n = householderVectors[0].length; final int p = main.length; final int diagOffset = (m >= n) ? 0 : 1; final double[] diagonal = (m >= n) ? main : secondary; cachedU = MatrixUtils.createRealMatrix(m, m); // fill up the part of the matrix not affected by Householder transforms for (int k = m - 1; k >= p; --k) { cachedU.setEntry(k, k, 1); } // build up first part of the matrix by applying Householder transforms for (int k = p - 1; k >= diagOffset; --k) { final double[] hK = householderVectors[k]; cachedU.setEntry(k, k, 1); if (hK[k - diagOffset] != 0.0) { for (int j = k; j < m; ++j) { double alpha = 0; for (int i = k; i < m; ++i) { alpha -= cachedU.getEntry(i, j) * householderVectors[i][k - diagOffset]; } alpha /= diagonal[k - diagOffset] * hK[k - diagOffset]; for (int i = k; i < m; ++i) { cachedU.addToEntry(i, j, -alpha * householderVectors[i][k - diagOffset]); } } } } if (diagOffset > 0) { cachedU.setEntry(0, 0, 1); } } // return the cached matrix return cachedU; } /** * Returns the bi-diagonal matrix B of the transform. * @return the B matrix */ public RealMatrix getB() { if (cachedB == null) { final int m = householderVectors.length; final int n = householderVectors[0].length; cachedB = MatrixUtils.createRealMatrix(m, n); for (int i = 0; i < main.length; ++i) { cachedB.setEntry(i, i, main[i]); if (m < n) { if (i > 0) { cachedB.setEntry(i, i - 1, secondary[i - 1]); } } else { if (i < main.length - 1) { cachedB.setEntry(i, i + 1, secondary[i]); } } } } // return the cached matrix return cachedB; } /** * Returns the matrix V of the transform. *

                    V is an orthogonal matrix, i.e. its transpose is also its inverse.

                    * @return the V matrix */ public RealMatrix getV() { if (cachedV == null) { final int m = householderVectors.length; final int n = householderVectors[0].length; final int p = main.length; final int diagOffset = (m >= n) ? 1 : 0; final double[] diagonal = (m >= n) ? secondary : main; cachedV = MatrixUtils.createRealMatrix(n, n); // fill up the part of the matrix not affected by Householder transforms for (int k = n - 1; k >= p; --k) { cachedV.setEntry(k, k, 1); } // build up first part of the matrix by applying Householder transforms for (int k = p - 1; k >= diagOffset; --k) { final double[] hK = householderVectors[k - diagOffset]; cachedV.setEntry(k, k, 1); if (hK[k] != 0.0) { for (int j = k; j < n; ++j) { double beta = 0; for (int i = k; i < n; ++i) { beta -= cachedV.getEntry(i, j) * hK[i]; } beta /= diagonal[k - diagOffset] * hK[k]; for (int i = k; i < n; ++i) { cachedV.addToEntry(i, j, -beta * hK[i]); } } } } if (diagOffset > 0) { cachedV.setEntry(0, 0, 1); } } // return the cached matrix return cachedV; } /** * Get the Householder vectors of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the main diagonal elements of the B matrix */ double[][] getHouseholderVectorsRef() { return householderVectors; } /** * Get the main diagonal elements of the matrix B of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the main diagonal elements of the B matrix */ double[] getMainDiagonalRef() { return main; } /** * Get the secondary diagonal elements of the matrix B of the transform. *

                    Note that since this class is only intended for internal use, * it returns directly a reference to its internal arrays, not a copy.

                    * @return the secondary diagonal elements of the B matrix */ double[] getSecondaryDiagonalRef() { return secondary; } /** * Check if the matrix is transformed to upper bi-diagonal. * @return true if the matrix is transformed to upper bi-diagonal */ boolean isUpperBiDiagonal() { return householderVectors.length >= householderVectors[0].length; } /** * Transform original matrix to upper bi-diagonal form. *

                    Transformation is done using alternate Householder transforms * on columns and rows.

                    */ private void transformToUpperBiDiagonal() { final int m = householderVectors.length; final int n = householderVectors[0].length; for (int k = 0; k < n; k++) { //zero-out a column double xNormSqr = 0; for (int i = k; i < m; ++i) { final double c = householderVectors[i][k]; xNormSqr += c * c; } final double[] hK = householderVectors[k]; final double a = (hK[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); main[k] = a; if (a != 0.0) { hK[k] -= a; for (int j = k + 1; j < n; ++j) { double alpha = 0; for (int i = k; i < m; ++i) { final double[] hI = householderVectors[i]; alpha -= hI[j] * hI[k]; } alpha /= a * householderVectors[k][k]; for (int i = k; i < m; ++i) { final double[] hI = householderVectors[i]; hI[j] -= alpha * hI[k]; } } } if (k < n - 1) { //zero-out a row xNormSqr = 0; for (int j = k + 1; j < n; ++j) { final double c = hK[j]; xNormSqr += c * c; } final double b = (hK[k + 1] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); secondary[k] = b; if (b != 0.0) { hK[k + 1] -= b; for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; double beta = 0; for (int j = k + 1; j < n; ++j) { beta -= hI[j] * hK[j]; } beta /= b * hK[k + 1]; for (int j = k + 1; j < n; ++j) { hI[j] -= beta * hK[j]; } } } } } } /** * Transform original matrix to lower bi-diagonal form. *

                    Transformation is done using alternate Householder transforms * on rows and columns.

                    */ private void transformToLowerBiDiagonal() { final int m = householderVectors.length; final int n = householderVectors[0].length; for (int k = 0; k < m; k++) { //zero-out a row final double[] hK = householderVectors[k]; double xNormSqr = 0; for (int j = k; j < n; ++j) { final double c = hK[j]; xNormSqr += c * c; } final double a = (hK[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); main[k] = a; if (a != 0.0) { hK[k] -= a; for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; double alpha = 0; for (int j = k; j < n; ++j) { alpha -= hI[j] * hK[j]; } alpha /= a * householderVectors[k][k]; for (int j = k; j < n; ++j) { hI[j] -= alpha * hK[j]; } } } if (k < m - 1) { //zero-out a column final double[] hKp1 = householderVectors[k + 1]; xNormSqr = 0; for (int i = k + 1; i < m; ++i) { final double c = householderVectors[i][k]; xNormSqr += c * c; } final double b = (hKp1[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); secondary[k] = b; if (b != 0.0) { hKp1[k] -= b; for (int j = k + 1; j < n; ++j) { double beta = 0; for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; beta -= hI[j] * hI[k]; } beta /= b * hKp1[k]; for (int i = k + 1; i < m; ++i) { final double[] hI = householderVectors[i]; hI[j] -= beta * hI[k]; } } } } } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/package.html100644 1750 1750 1655 11532241245 26106 0ustarlucluc 0 0 Linear algebra support. commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/MatrixIndexException.java100644 1750 1750 4166 11532241245 30603 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * Thrown when an operation addresses a matrix coordinate (row, col) * which is outside of the dimensions of a matrix. * @version $Revision: 1073255 $ $Date: 2011-02-22 09:42:06 +0100 (mar. 22 févr. 2011) $ */ public class MatrixIndexException extends MathRuntimeException { /** Serializable version identifier */ private static final long serialVersionUID = 8120540015829487660L; /** * Constructs a new instance with specified formatted detail message. * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MatrixIndexException(Localizable, Object...)} */ @Deprecated public MatrixIndexException(final String pattern, final Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Constructs a new instance with specified formatted detail message. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MatrixIndexException(final Localizable pattern, final Object ... arguments) { super(pattern, arguments); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java100644 1750 1750 107335 11532241245 27577 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.util.Arrays; import java.util.Iterator; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * This class implements the {@link RealVector} interface with a double array. * @version $Revision: 1003993 $ $Date: 2010-10-03 18:39:16 +0200 (dim. 03 oct. 2010) $ * @since 2.0 */ public class ArrayRealVector extends AbstractRealVector implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -1097961340710804027L; /** Default format. */ private static final RealVectorFormat DEFAULT_FORMAT = RealVectorFormat.getInstance(); /** Entries of the vector. */ protected double data[]; /** * Build a 0-length vector. *

                    Zero-length vectors may be used to initialized construction of vectors * by data gathering. We start with zero-length and use either the {@link * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor * or one of the append method ({@link #append(double)}, {@link * #append(double[])}, {@link #append(ArrayRealVector)}) to gather data * into this vector.

                    */ public ArrayRealVector() { data = new double[0]; } /** * Construct a (size)-length vector of zeros. * @param size size of the vector */ public ArrayRealVector(int size) { data = new double[size]; } /** * Construct an (size)-length vector with preset values. * @param size size of the vector * @param preset fill the vector with this scalar value */ public ArrayRealVector(int size, double preset) { data = new double[size]; Arrays.fill(data, preset); } /** * Construct a vector from an array, copying the input array. * @param d array of doubles. */ public ArrayRealVector(double[] d) { data = d.clone(); } /** * Create a new ArrayRealVector using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * ArrayRealVector and not used directly, the copyArray may be * set to false * @param d data for new vector * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @see #ArrayRealVector(double[]) */ public ArrayRealVector(double[] d, boolean copyArray) { data = copyArray ? d.clone() : d; } /** * Construct a vector from part of a array. * @param d array of doubles. * @param pos position of first entry * @param size number of entries to copy */ public ArrayRealVector(double[] d, int pos, int size) { if (d.length < pos + size) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY, pos, size, d.length); } data = new double[size]; System.arraycopy(d, pos, data, 0, size); } /** * Construct a vector from an array. * @param d array of Doubles. */ public ArrayRealVector(Double[] d) { data = new double[d.length]; for (int i = 0; i < d.length; i++) { data[i] = d[i].doubleValue(); } } /** * Construct a vector from part of a Double array * @param d array of Doubles. * @param pos position of first entry * @param size number of entries to copy */ public ArrayRealVector(Double[] d, int pos, int size) { if (d.length < pos + size) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY, pos, size, d.length); } data = new double[size]; for (int i = pos; i < pos + size; i++) { data[i-pos] = d[i].doubleValue(); } } /** * Construct a vector from another vector, using a deep copy. * @param v vector to copy */ public ArrayRealVector(RealVector v) { data = new double[v.getDimension()]; for (int i = 0; i < data.length; ++i) { data[i] = v.getEntry(i); } } /** * Construct a vector from another vector, using a deep copy. * @param v vector to copy */ public ArrayRealVector(ArrayRealVector v) { this(v, true); } /** * Construct a vector from another vector. * @param v vector to copy * @param deep if true perform a deep copy otherwise perform a shallow copy */ public ArrayRealVector(ArrayRealVector v, boolean deep) { data = deep ? v.data.clone() : v.data; } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) { data = new double[v1.data.length + v2.data.length]; System.arraycopy(v1.data, 0, data, 0, v1.data.length); System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(ArrayRealVector v1, RealVector v2) { final int l1 = v1.data.length; final int l2 = v2.getDimension(); data = new double[l1 + l2]; System.arraycopy(v1.data, 0, data, 0, l1); for (int i = 0; i < l2; ++i) { data[l1 + i] = v2.getEntry(i); } } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(RealVector v1, ArrayRealVector v2) { final int l1 = v1.getDimension(); final int l2 = v2.data.length; data = new double[l1 + l2]; for (int i = 0; i < l1; ++i) { data[i] = v1.getEntry(i); } System.arraycopy(v2.data, 0, data, l1, l2); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(ArrayRealVector v1, double[] v2) { final int l1 = v1.getDimension(); final int l2 = v2.length; data = new double[l1 + l2]; System.arraycopy(v1.data, 0, data, 0, l1); System.arraycopy(v2, 0, data, l1, l2); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(double[] v1, ArrayRealVector v2) { final int l1 = v1.length; final int l2 = v2.getDimension(); data = new double[l1 + l2]; System.arraycopy(v1, 0, data, 0, l1); System.arraycopy(v2.data, 0, data, l1, l2); } /** * Construct a vector by appending one vector to another vector. * @param v1 first vector (will be put in front of the new vector) * @param v2 second vector (will be put at back of the new vector) */ public ArrayRealVector(double[] v1, double[] v2) { final int l1 = v1.length; final int l2 = v2.length; data = new double[l1 + l2]; System.arraycopy(v1, 0, data, 0, l1); System.arraycopy(v2, 0, data, l1, l2); } /** {@inheritDoc} */ @Override public AbstractRealVector copy() { return new ArrayRealVector(this, true); } /** {@inheritDoc} */ @Override public RealVector add(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return add((ArrayRealVector) v); } else { checkVectorDimensions(v); double[] out = data.clone(); Iterator it = v.sparseIterator(); Entry e; while (it.hasNext() && (e = it.next()) != null) { out[e.getIndex()] += e.getValue(); } return new ArrayRealVector(out, false); } } /** {@inheritDoc} */ @Override public RealVector add(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] += v[i]; } return new ArrayRealVector(out, false); } /** * Compute the sum of this and v. * @param v vector to be added * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayRealVector add(ArrayRealVector v) throws IllegalArgumentException { return (ArrayRealVector) add(v.data); } /** {@inheritDoc} */ @Override public RealVector subtract(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return subtract((ArrayRealVector) v); } else { checkVectorDimensions(v); double[] out = data.clone(); Iterator it = v.sparseIterator(); Entry e; while(it.hasNext() && (e = it.next()) != null) { out[e.getIndex()] -= e.getValue(); } return new ArrayRealVector(out, false); } } /** {@inheritDoc} */ @Override public RealVector subtract(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] -= v[i]; } return new ArrayRealVector(out, false); } /** * Compute this minus v. * @param v vector to be subtracted * @return this + v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayRealVector subtract(ArrayRealVector v) throws IllegalArgumentException { return (ArrayRealVector) subtract(v.data); } /** {@inheritDoc} */ @Override public RealVector mapAddToSelf(double d) { for (int i = 0; i < data.length; i++) { data[i] = data[i] + d; } return this; } /** {@inheritDoc} */ @Override public RealVector mapSubtractToSelf(double d) { for (int i = 0; i < data.length; i++) { data[i] = data[i] - d; } return this; } /** {@inheritDoc} */ @Override public RealVector mapMultiplyToSelf(double d) { for (int i = 0; i < data.length; i++) { data[i] = data[i] * d; } return this; } /** {@inheritDoc} */ @Override public RealVector mapDivideToSelf(double d) { for (int i = 0; i < data.length; i++) { data[i] = data[i] / d; } return this; } /** {@inheritDoc} */ @Override public RealVector mapPowToSelf(double d) { for (int i = 0; i < data.length; i++) { data[i] = FastMath.pow(data[i], d); } return this; } /** {@inheritDoc} */ @Override public RealVector mapExpToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.exp(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapExpm1ToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.expm1(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapLogToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.log(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapLog10ToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.log10(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapLog1pToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.log1p(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapCoshToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.cosh(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapSinhToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.sinh(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapTanhToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.tanh(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapCosToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.cos(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapSinToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.sin(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapTanToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.tan(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapAcosToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.acos(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapAsinToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.asin(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapAtanToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.atan(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapInvToSelf() { for (int i = 0; i < data.length; i++) { data[i] = 1.0 / data[i]; } return this; } /** {@inheritDoc} */ @Override public RealVector mapAbsToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.abs(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapSqrtToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.sqrt(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapCbrtToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.cbrt(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapCeilToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.ceil(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapFloorToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.floor(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapRintToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.rint(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapSignumToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.signum(data[i]); } return this; } /** {@inheritDoc} */ @Override public RealVector mapUlpToSelf() { for (int i = 0; i < data.length; i++) { data[i] = FastMath.ulp(data[i]); } return this; } /** {@inheritDoc} */ public RealVector ebeMultiply(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return ebeMultiply((ArrayRealVector) v); } else { checkVectorDimensions(v); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] *= v.getEntry(i); } return new ArrayRealVector(out, false); } } /** {@inheritDoc} */ @Override public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] *= v[i]; } return new ArrayRealVector(out, false); } /** * Element-by-element multiplication. * @param v vector by which instance elements must be multiplied * @return a vector containing this[i] * v[i] for all i * @exception IllegalArgumentException if v is not the same size as this */ public ArrayRealVector ebeMultiply(ArrayRealVector v) throws IllegalArgumentException { return (ArrayRealVector) ebeMultiply(v.data); } /** {@inheritDoc} */ public RealVector ebeDivide(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return ebeDivide((ArrayRealVector) v); } else { checkVectorDimensions(v); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] /= v.getEntry(i); } return new ArrayRealVector(out, false); } } /** {@inheritDoc} */ @Override public RealVector ebeDivide(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double[] out = data.clone(); for (int i = 0; i < data.length; i++) { out[i] /= v[i]; } return new ArrayRealVector(out, false); } /** * Element-by-element division. * @param v vector by which instance elements must be divided * @return a vector containing this[i] / v[i] for all i * @throws IllegalArgumentException if v is not the same size as this */ public ArrayRealVector ebeDivide(ArrayRealVector v) throws IllegalArgumentException { return (ArrayRealVector) ebeDivide(v.data); } /** {@inheritDoc} */ @Override public double[] getData() { return data.clone(); } /** * Returns a reference to the underlying data array. *

                    Does not make a fresh copy of the underlying data.

                    * @return array of entries */ public double[] getDataRef() { return data; } /** {@inheritDoc} */ @Override public double dotProduct(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return dotProduct((ArrayRealVector) v); } else { checkVectorDimensions(v); double dot = 0; Iterator it = v.sparseIterator(); Entry e; while(it.hasNext() && (e = it.next()) != null) { dot += data[e.getIndex()] * e.getValue(); } return dot; } } /** {@inheritDoc} */ @Override public double dotProduct(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double dot = 0; for (int i = 0; i < data.length; i++) { dot += data[i] * v[i]; } return dot; } /** * Compute the dot product. * @param v vector with which dot product should be computed * @return the scalar dot product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ public double dotProduct(ArrayRealVector v) throws IllegalArgumentException { return dotProduct(v.data); } /** {@inheritDoc} */ @Override public double getNorm() { double sum = 0; for (double a : data) { sum += a * a; } return FastMath.sqrt(sum); } /** {@inheritDoc} */ @Override public double getL1Norm() { double sum = 0; for (double a : data) { sum += FastMath.abs(a); } return sum; } /** {@inheritDoc} */ @Override public double getLInfNorm() { double max = 0; for (double a : data) { max = FastMath.max(max, FastMath.abs(a)); } return max; } /** {@inheritDoc} */ @Override public double getDistance(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return getDistance((ArrayRealVector) v); } else { checkVectorDimensions(v); double sum = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v.getEntry(i); sum += delta * delta; } return FastMath.sqrt(sum); } } /** {@inheritDoc} */ @Override public double getDistance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double sum = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v[i]; sum += delta * delta; } return FastMath.sqrt(sum); } /** * Distance between two vectors. *

                    This method computes the distance consistent with the * L2 norm, i.e. the square root of the sum of * elements differences, or euclidian distance.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @exception IllegalArgumentException if v is not the same size as this * @see #getDistance(RealVector) * @see #getL1Distance(ArrayRealVector) * @see #getLInfDistance(ArrayRealVector) * @see #getNorm() */ public double getDistance(ArrayRealVector v) throws IllegalArgumentException { return getDistance(v.data); } /** {@inheritDoc} */ @Override public double getL1Distance(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return getL1Distance((ArrayRealVector) v); } else { checkVectorDimensions(v); double sum = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v.getEntry(i); sum += FastMath.abs(delta); } return sum; } } /** {@inheritDoc} */ @Override public double getL1Distance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double sum = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v[i]; sum += FastMath.abs(delta); } return sum; } /** * Distance between two vectors. *

                    This method computes the distance consistent with * L1 norm, i.e. the sum of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @exception IllegalArgumentException if v is not the same size as this * @see #getDistance(RealVector) * @see #getL1Distance(ArrayRealVector) * @see #getLInfDistance(ArrayRealVector) * @see #getNorm() */ public double getL1Distance(ArrayRealVector v) throws IllegalArgumentException { return getL1Distance(v.data); } /** {@inheritDoc} */ @Override public double getLInfDistance(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return getLInfDistance((ArrayRealVector) v); } else { checkVectorDimensions(v); double max = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v.getEntry(i); max = FastMath.max(max, FastMath.abs(delta)); } return max; } } /** {@inheritDoc} */ @Override public double getLInfDistance(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); double max = 0; for (int i = 0; i < data.length; ++i) { final double delta = data[i] - v[i]; max = FastMath.max(max, FastMath.abs(delta)); } return max; } /** * Distance between two vectors. *

                    This method computes the distance consistent with * L norm, i.e. the max of the absolute values of * elements differences.

                    * @param v vector to which distance is requested * @return distance between two vectors. * @exception IllegalArgumentException if v is not the same size as this * @see #getDistance(RealVector) * @see #getL1Distance(ArrayRealVector) * @see #getLInfDistance(ArrayRealVector) * @see #getNorm() */ public double getLInfDistance(ArrayRealVector v) throws IllegalArgumentException { return getLInfDistance(v.data); } /** {@inheritDoc} */ @Override public RealVector unitVector() throws ArithmeticException { final double norm = getNorm(); if (norm == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM); } return mapDivide(norm); } /** {@inheritDoc} */ @Override public void unitize() throws ArithmeticException { final double norm = getNorm(); if (norm == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR); } mapDivideToSelf(norm); } /** {@inheritDoc} */ public RealVector projection(RealVector v) { return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); } /** {@inheritDoc} */ @Override public RealVector projection(double[] v) { return projection(new ArrayRealVector(v, false)); } /** Find the orthogonal projection of this vector onto another vector. * @param v vector onto which instance must be projected * @return projection of the instance onto v * @throws IllegalArgumentException if v is not the same size as this */ public ArrayRealVector projection(ArrayRealVector v) { return (ArrayRealVector) v.mapMultiply(dotProduct(v) / v.dotProduct(v)); } /** {@inheritDoc} */ @Override public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { if (v instanceof ArrayRealVector) { return outerProduct((ArrayRealVector) v); } else { checkVectorDimensions(v); final int m = data.length; final RealMatrix out = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < data.length; i++) { for (int j = 0; j < data.length; j++) { out.setEntry(i, j, data[i] * v.getEntry(j)); } } return out; } } /** * Compute the outer product. * @param v vector with which outer product should be computed * @return the square matrix outer product between instance and v * @exception IllegalArgumentException if v is not the same size as this */ public RealMatrix outerProduct(ArrayRealVector v) throws IllegalArgumentException { return outerProduct(v.data); } /** {@inheritDoc} */ @Override public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); final int m = data.length; final RealMatrix out = MatrixUtils.createRealMatrix(m, m); for (int i = 0; i < data.length; i++) { for (int j = 0; j < data.length; j++) { out.setEntry(i, j, data[i] * v[j]); } } return out; } /** {@inheritDoc} */ public double getEntry(int index) throws MatrixIndexException { return data[index]; } /** {@inheritDoc} */ public int getDimension() { return data.length; } /** {@inheritDoc} */ public RealVector append(RealVector v) { try { return new ArrayRealVector(this, (ArrayRealVector) v); } catch (ClassCastException cce) { return new ArrayRealVector(this, v); } } /** * Construct a vector by appending a vector to this vector. * @param v vector to append to this one. * @return a new vector */ public ArrayRealVector append(ArrayRealVector v) { return new ArrayRealVector(this, v); } /** {@inheritDoc} */ public RealVector append(double in) { final double[] out = new double[data.length + 1]; System.arraycopy(data, 0, out, 0, data.length); out[data.length] = in; return new ArrayRealVector(out, false); } /** {@inheritDoc} */ public RealVector append(double[] in) { return new ArrayRealVector(this, in); } /** {@inheritDoc} */ public RealVector getSubVector(int index, int n) { ArrayRealVector out = new ArrayRealVector(n); try { System.arraycopy(data, index, out.data, 0, n); } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + n - 1); } return out; } /** {@inheritDoc} */ public void setEntry(int index, double value) { try { data[index] = value; } catch (IndexOutOfBoundsException e) { checkIndex(index); } } /** {@inheritDoc} */ @Override public void setSubVector(int index, RealVector v) { try { try { set(index, (ArrayRealVector) v); } catch (ClassCastException cce) { for (int i = index; i < index + v.getDimension(); ++i) { data[i] = v.getEntry(i-index); } } } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + v.getDimension() - 1); } } /** {@inheritDoc} */ @Override public void setSubVector(int index, double[] v) { try { System.arraycopy(v, 0, data, index, v.length); } catch (IndexOutOfBoundsException e) { checkIndex(index); checkIndex(index + v.length - 1); } } /** * Set a set of consecutive elements. * * @param index index of first element to be set. * @param v vector containing the values to set. * @exception MatrixIndexException if the index is * inconsistent with vector size */ public void set(int index, ArrayRealVector v) throws MatrixIndexException { setSubVector(index, v.data); } /** {@inheritDoc} */ @Override public void set(double value) { Arrays.fill(data, value); } /** {@inheritDoc} */ @Override public double[] toArray(){ return data.clone(); } /** {@inheritDoc} */ @Override public String toString(){ return DEFAULT_FORMAT.format(this); } /** * Check if instance and specified vectors have the same dimension. * @param v vector to compare instance with * @exception IllegalArgumentException if the vectors do not * have the same dimension */ @Override protected void checkVectorDimensions(RealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); } /** * Check if instance dimension is equal to some expected value. * * @param n expected dimension. * @exception IllegalArgumentException if the dimension is * inconsistent with vector size */ @Override protected void checkVectorDimensions(int n) throws IllegalArgumentException { if (data.length != n) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, data.length, n); } } /** * Returns true if any coordinate of this vector is NaN; false otherwise * @return true if any coordinate of this vector is NaN; false otherwise */ public boolean isNaN() { for (double v : data) { if (Double.isNaN(v)) { return true; } } return false; } /** * Returns true if any coordinate of this vector is infinite and none are NaN; * false otherwise * @return true if any coordinate of this vector is infinite and none are NaN; * false otherwise */ public boolean isInfinite() { if (isNaN()) { return false; } for (double v : data) { if (Double.isInfinite(v)) { return true; } } return false; } /** * Test for the equality of two real vectors. *

                    * If all coordinates of two real vectors are exactly the same, and none are * Double.NaN, the two real vectors are considered to be equal. *

                    *

                    * NaN coordinates are considered to affect globally the vector * and be equals to each other - i.e, if either (or all) coordinates of the * real vector are equal to Double.NaN, the real vector is equal to * a vector with all Double.NaN coordinates. *

                    * * @param other Object to test for equality to this * @return true if two vector objects are equal, false if * object is null, not an instance of RealVector, or * not equal to this RealVector instance * */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other == null || !(other instanceof RealVector)) { return false; } RealVector rhs = (RealVector) other; if (data.length != rhs.getDimension()) { return false; } if (rhs.isNaN()) { return this.isNaN(); } for (int i = 0; i < data.length; ++i) { if (data[i] != rhs.getEntry(i)) { return false; } } return true; } /** * Get a hashCode for the real vector. *

                    All NaN values have the same hash code.

                    * @return a hash code value for this object */ @Override public int hashCode() { if (isNaN()) { return 9; } return MathUtils.hash(data); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealMatrix.java100644 1750 1750 114405 11532241245 26576 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining a real-valued matrix with basic algebraic operations. *

                    * Matrix element indexing is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public interface RealMatrix extends AnyMatrix { /** * Create a new RealMatrix of the same type as the instance with the supplied * row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @return a new matrix of the same type as the instance * @throws IllegalArgumentException if row or column dimension is not positive * @since 2.0 */ RealMatrix createMatrix(final int rowDimension, final int columnDimension); /** * Returns a (deep) copy of this. * * @return matrix copy */ RealMatrix copy(); /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ RealMatrix add(RealMatrix m) throws IllegalArgumentException; /** * Compute this minus m. * * @param m matrix to be subtracted * @return this - m * @throws IllegalArgumentException if m is not the same size as this */ RealMatrix subtract(RealMatrix m) throws IllegalArgumentException; /** * Returns the result of adding d to each entry of this. * * @param d value to be added to each entry * @return d + this */ RealMatrix scalarAdd(double d); /** * Returns the result multiplying each entry of this by d. * * @param d value to multiply all entries by * @return d * this */ RealMatrix scalarMultiply(double d); /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ RealMatrix multiply(RealMatrix m) throws IllegalArgumentException; /** * Returns the result premultiplying this by m. * @param m matrix to premultiply by * @return m * this * @throws IllegalArgumentException * if rowDimension(this) != columnDimension(m) */ RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException; /** * Returns matrix entries as a two-dimensional array. * * @return 2-dimensional array of entries */ double[][] getData(); /** * Returns the * maximum absolute row sum norm of the matrix. * * @return norm */ double getNorm(); /** * Returns the * Frobenius norm of the matrix. * * @return norm */ double getFrobeniusNorm(); /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @return The subMatrix containing the data of the * specified rows and columns * @exception MatrixIndexException if the indices are not valid */ RealMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException; /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @return The subMatrix containing the data in the * specified rows and columns * @exception MatrixIndexException if row or column selections are not valid */ RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException; /** * Copy a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @param destination The arrays where the submatrix data should be copied * (if larger than rows/columns counts, only the upper-left part will be used) * @exception MatrixIndexException if the indices are not valid * @exception IllegalArgumentException if the destination array is too small */ void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn, double[][] destination) throws MatrixIndexException, IllegalArgumentException; /** * Copy a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @param destination The arrays where the submatrix data should be copied * (if larger than rows/columns counts, only the upper-left part will be used) * @exception MatrixIndexException if the indices are not valid * @exception IllegalArgumentException if the destination array is too small */ void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination) throws MatrixIndexException, IllegalArgumentException; /** * Replace the submatrix starting at row, column using data in * the input subMatrix array. Indexes are 0-based. *

                    * Example:
                    * Starting with

                        * 1  2  3  4
                        * 5  6  7  8
                        * 9  0  1  2
                        * 
                    * and subMatrix = {{3, 4} {5,6}}, invoking * setSubMatrix(subMatrix,1,1)) will result in
                        * 1  2  3  4
                        * 5  3  4  8
                        * 9  5  6  2
                        * 

                    * * @param subMatrix array containing the submatrix replacement data * @param row row coordinate of the top, left element to be replaced * @param column column coordinate of the top, left element to be replaced * @throws MatrixIndexException if subMatrix does not fit into this * matrix from element in (row, column) * @throws IllegalArgumentException if subMatrix is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if subMatrix is null * @since 2.0 */ void setSubMatrix(double[][] subMatrix, int row, int column) throws MatrixIndexException; /** * Returns the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be fetched * @return row matrix * @throws MatrixIndexException if the specified row index is invalid */ RealMatrix getRowMatrix(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param matrix row matrix (must have one row and the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance row */ void setRowMatrix(int row, RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be fetched * @return column matrix * @throws MatrixIndexException if the specified column index is invalid */ RealMatrix getColumnMatrix(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param matrix column matrix (must have one column and the same number of rows * as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance column */ void setColumnMatrix(int column, RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in row number row * as a vector. Row indices start at 0. * * @param row the row to be fetched * @return row vector * @throws MatrixIndexException if the specified row index is invalid */ RealVector getRowVector(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a vector. Row indices start at 0. * * @param row the row to be set * @param vector row vector (must have the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the vector dimension does not match one * instance row */ void setRowVector(int row, RealVector vector) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number column * as a vector. Column indices start at 0. * * @param column the column to be fetched * @return column vector * @throws MatrixIndexException if the specified column index is invalid */ RealVector getColumnVector(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a vector. Column indices start at 0. * * @param column the column to be set * @param vector column vector (must have the same number of rows as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the vector dimension does not match one * instance column */ void setColumnVector(int column, RealVector vector) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in row number row as an array. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ double[] getRow(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param array row matrix (must have the same number of columns as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the array size does not match one * instance row */ void setRow(int row, double[] array) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number col as an array. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param column the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ double[] getColumn(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param array column array (must have the same number of rows as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the array size does not match one * instance column */ void setColumn(int column, double[] array) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid */ double getEntry(int row, int column) throws MatrixIndexException; /** * Set the entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param value matrix entry to be set in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void setEntry(int row, int column, double value) throws MatrixIndexException; /** * Change an entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param increment value to add to the current matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void addToEntry(int row, int column, double increment) throws MatrixIndexException; /** * Change an entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param factor multiplication factor for the current matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void multiplyEntry(int row, int column, double factor) throws MatrixIndexException; /** * Returns the transpose of this matrix. * * @return transpose matrix */ RealMatrix transpose(); /** * Returns the inverse of this matrix. * * @return inverse matrix * @throws InvalidMatrixException if this is not invertible * @deprecated as of release 2.0, replaced by * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver() * getSolver()}.{@link DecompositionSolver#getInverse() * getInverse()} */ @Deprecated RealMatrix inverse() throws InvalidMatrixException; /** * Returns the determinant of this matrix. * * @return determinant * @deprecated as of release 2.0, replaced by * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) * new LUDecompositionImpl(m)}.{@link LUDecomposition#getDeterminant() * getDeterminant()} */ @Deprecated double getDeterminant(); /** * Is this a singular matrix? * @return true if the matrix is singular * @deprecated as of release 2.0, replaced by the boolean negation of * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver() * getSolver()}.{@link DecompositionSolver#isNonSingular() * isNonSingular()} */ @Deprecated boolean isSingular(); /** * Returns the * trace of the matrix (the sum of the elements on the main diagonal). * * @return trace * @throws NonSquareMatrixException if the matrix is not square */ double getTrace() throws NonSquareMatrixException; /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ double[] operate(double[] v) throws IllegalArgumentException; /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ RealVector operate(RealVector v) throws IllegalArgumentException; /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ double[] preMultiply(double[] v) throws IllegalArgumentException; /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ RealVector preMultiply(RealVector v) throws IllegalArgumentException; /** * Visit (and possibly change) all matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInRowOrder(RealMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInRowOrder(RealMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInRowOrder(RealMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInRowOrder(RealMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (and possibly change) all matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInColumnOrder(RealMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInColumnOrder(RealMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInColumnOrder(RealMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (and possibly change) all matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInOptimizedOrder(RealMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end * of the walk */ double walkInOptimizedOrder(RealMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(RealMatrixChangingVisitor) * @see #walkInRowOrder(RealMatrixPreservingVisitor) * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixChangingVisitor) * @see #walkInColumnOrder(RealMatrixPreservingVisitor) * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end * of the walk */ double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Returns the solution vector for a linear system with coefficient * matrix = this and constant vector = b. * * @param b constant vector * @return vector of solution values to AX = b, where A is *this * @throws IllegalArgumentException if this.rowDimension != b.length * @throws InvalidMatrixException if this matrix is not square or is singular * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(double[])} */ @Deprecated double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException; /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of * b. * * @param b matrix of constant vectors forming RHS of linear systems to * to solve * @return matrix of solution vectors * @throws IllegalArgumentException if this.rowDimension != row dimension * @throws InvalidMatrixException if this matrix is not square or is singular * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(RealMatrix)} */ @Deprecated RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/AbstractRealMatrix.java100644 1750 1750 107726 11532241245 30272 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Basic implementation of RealMatrix methods regardless of the underlying storage. *

                    All the methods implemented here use {@link #getEntry(int, int)} to access * matrix elements. Derived class can provide faster implementations.

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public abstract class AbstractRealMatrix implements RealMatrix { /** Cached LU solver. * @deprecated as of release 2.0, since all methods using this are deprecated */ @Deprecated private DecompositionSolver lu; /** * Creates a matrix with no data */ protected AbstractRealMatrix() { lu = null; } /** * Create a new RealMatrix with the supplied row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not positive */ protected AbstractRealMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { if (rowDimension < 1 ) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1); } if (columnDimension <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1); } lu = null; } /** {@inheritDoc} */ public abstract RealMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException; /** {@inheritDoc} */ public abstract RealMatrix copy(); /** {@inheritDoc} */ public RealMatrix add(RealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final RealMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col) + m.getEntry(row, col)); } } return out; } /** {@inheritDoc} */ public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final RealMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col) - m.getEntry(row, col)); } } return out; } /** {@inheritDoc} */ public RealMatrix scalarAdd(final double d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final RealMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col) + d); } } return out; } /** {@inheritDoc} */ public RealMatrix scalarMultiply(final double d) { final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final RealMatrix out = createMatrix(rowCount, columnCount); for (int row = 0; row < rowCount; ++row) { for (int col = 0; col < columnCount; ++col) { out.setEntry(row, col, getEntry(row, col) * d); } } return out; } /** {@inheritDoc} */ public RealMatrix multiply(final RealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int nRows = getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = getColumnDimension(); final RealMatrix out = createMatrix(nRows, nCols); for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { double sum = 0; for (int i = 0; i < nSum; ++i) { sum += getEntry(row, i) * m.getEntry(i, col); } out.setEntry(row, col, sum); } } return out; } /** {@inheritDoc} */ public RealMatrix preMultiply(final RealMatrix m) throws IllegalArgumentException { return m.multiply(this); } /** {@inheritDoc} */ public double[][] getData() { final double[][] data = new double[getRowDimension()][getColumnDimension()]; for (int i = 0; i < data.length; ++i) { final double[] dataI = data[i]; for (int j = 0; j < dataI.length; ++j) { dataI[j] = getEntry(i, j); } } return data; } /** {@inheritDoc} */ public double getNorm() { return walkInColumnOrder(new RealMatrixPreservingVisitor() { /** Last row index. */ private double endRow; /** Sum of absolute values on one column. */ private double columnSum; /** Maximal sum across all columns. */ private double maxColSum; /** {@inheritDoc} */ public void start(final int rows, final int columns, final int startRow, final int endRow, final int startColumn, final int endColumn) { this.endRow = endRow; columnSum = 0; maxColSum = 0; } /** {@inheritDoc} */ public void visit(final int row, final int column, final double value) { columnSum += FastMath.abs(value); if (row == endRow) { maxColSum = FastMath.max(maxColSum, columnSum); columnSum = 0; } } /** {@inheritDoc} */ public double end() { return maxColSum; } }); } /** {@inheritDoc} */ public double getFrobeniusNorm() { return walkInOptimizedOrder(new RealMatrixPreservingVisitor() { /** Sum of squared entries. */ private double sum; /** {@inheritDoc} */ public void start(final int rows, final int columns, final int startRow, final int endRow, final int startColumn, final int endColumn) { sum = 0; } /** {@inheritDoc} */ public void visit(final int row, final int column, final double value) { sum += value * value; } /** {@inheritDoc} */ public double end() { return FastMath.sqrt(sum); } }); } /** {@inheritDoc} */ public RealMatrix getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); final RealMatrix subMatrix = createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); for (int i = startRow; i <= endRow; ++i) { for (int j = startColumn; j <= endColumn; ++j) { subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j)); } } return subMatrix; } /** {@inheritDoc} */ public RealMatrix getSubMatrix(final int[] selectedRows, final int[] selectedColumns) throws MatrixIndexException { // safety checks MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); // copy entries final RealMatrix subMatrix = createMatrix(selectedRows.length, selectedColumns.length); subMatrix.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() { /** {@inheritDoc} */ @Override public double visit(final int row, final int column, final double value) { return getEntry(selectedRows[row], selectedColumns[column]); } }); return subMatrix; } /** {@inheritDoc} */ public void copySubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn, final double[][] destination) throws MatrixIndexException, IllegalArgumentException { // safety checks MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); final int rowsCount = endRow + 1 - startRow; final int columnsCount = endColumn + 1 - startColumn; if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, destination.length, destination[0].length, rowsCount, columnsCount); } // copy entries walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { /** Initial row index. */ private int startRow; /** Initial column index. */ private int startColumn; /** {@inheritDoc} */ @Override public void start(final int rows, final int columns, final int startRow, final int endRow, final int startColumn, final int endColumn) { this.startRow = startRow; this.startColumn = startColumn; } /** {@inheritDoc} */ @Override public void visit(final int row, final int column, final double value) { destination[row - startRow][column - startColumn] = value; } }, startRow, endRow, startColumn, endColumn); } /** {@inheritDoc} */ public void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination) throws MatrixIndexException, IllegalArgumentException { // safety checks MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); if ((destination.length < selectedRows.length) || (destination[0].length < selectedColumns.length)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, destination.length, destination[0].length, selectedRows.length, selectedColumns.length); } // copy entries for (int i = 0; i < selectedRows.length; i++) { final double[] destinationI = destination[i]; for (int j = 0; j < selectedColumns.length; j++) { destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); } } } /** {@inheritDoc} */ public void setSubMatrix(final double[][] subMatrix, final int row, final int column) throws MatrixIndexException { final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; ++r) { if (subMatrix[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[r].length); } } MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); MatrixUtils.checkRowIndex(this, nRows + row - 1); MatrixUtils.checkColumnIndex(this, nCols + column - 1); for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { setEntry(row + i, column + j, subMatrix[i][j]); } } lu = null; } /** {@inheritDoc} */ public RealMatrix getRowMatrix(final int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); final RealMatrix out = createMatrix(1, nCols); for (int i = 0; i < nCols; ++i) { out.setEntry(0, i, getEntry(row, i)); } return out; } /** {@inheritDoc} */ public void setRowMatrix(final int row, final RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); if ((matrix.getRowDimension() != 1) || (matrix.getColumnDimension() != nCols)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, matrix.getEntry(0, i)); } } /** {@inheritDoc} */ public RealMatrix getColumnMatrix(final int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); final RealMatrix out = createMatrix(nRows, 1); for (int i = 0; i < nRows; ++i) { out.setEntry(i, 0, getEntry(i, column)); } return out; } /** {@inheritDoc} */ public void setColumnMatrix(final int column, final RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); if ((matrix.getRowDimension() != nRows) || (matrix.getColumnDimension() != 1)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, matrix.getEntry(i, 0)); } } /** {@inheritDoc} */ public RealVector getRowVector(final int row) throws MatrixIndexException { return new ArrayRealVector(getRow(row), false); } /** {@inheritDoc} */ public void setRowVector(final int row, final RealVector vector) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); if (vector.getDimension() != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, vector.getDimension(), 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, vector.getEntry(i)); } } /** {@inheritDoc} */ public RealVector getColumnVector(final int column) throws MatrixIndexException { return new ArrayRealVector(getColumn(column), false); } /** {@inheritDoc} */ public void setColumnVector(final int column, final RealVector vector) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); if (vector.getDimension() != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, vector.getDimension(), 1, nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, vector.getEntry(i)); } } /** {@inheritDoc} */ public double[] getRow(final int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); final double[] out = new double[nCols]; for (int i = 0; i < nCols; ++i) { out[i] = getEntry(row, i); } return out; } /** {@inheritDoc} */ public void setRow(final int row, final double[] array) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); if (array.length != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, array.length, 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, array[i]); } } /** {@inheritDoc} */ public double[] getColumn(final int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); final double[] out = new double[nRows]; for (int i = 0; i < nRows; ++i) { out[i] = getEntry(i, column); } return out; } /** {@inheritDoc} */ public void setColumn(final int column, final double[] array) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); if (array.length != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, array.length, 1, nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, array[i]); } } /** {@inheritDoc} */ public abstract double getEntry(int row, int column) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void setEntry(int row, int column, double value) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void addToEntry(int row, int column, double increment) throws MatrixIndexException; /** {@inheritDoc} */ public abstract void multiplyEntry(int row, int column, double factor) throws MatrixIndexException; /** {@inheritDoc} */ public RealMatrix transpose() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final RealMatrix out = createMatrix(nCols, nRows); walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { /** {@inheritDoc} */ @Override public void visit(final int row, final int column, final double value) { out.setEntry(column, row, value); } }); return out; } /** {@inheritDoc} */ @Deprecated public RealMatrix inverse() throws InvalidMatrixException { if (lu == null) { lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); } return lu.getInverse(); } /** {@inheritDoc} */ @Deprecated public double getDeterminant() throws InvalidMatrixException { return new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getDeterminant(); } /** {@inheritDoc} */ public boolean isSquare() { return getColumnDimension() == getRowDimension(); } /** {@inheritDoc} */ @Deprecated public boolean isSingular() { if (lu == null) { lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); } return !lu.isNonSingular(); } /** {@inheritDoc} */ public abstract int getRowDimension(); /** {@inheritDoc} */ public abstract int getColumnDimension(); /** {@inheritDoc} */ public double getTrace() throws NonSquareMatrixException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (nRows != nCols) { throw new NonSquareMatrixException(nRows, nCols); } double trace = 0; for (int i = 0; i < nRows; ++i) { trace += getEntry(i, i); } return trace; } /** {@inheritDoc} */ public double[] operate(final double[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols); } final double[] out = new double[nRows]; for (int row = 0; row < nRows; ++row) { double sum = 0; for (int i = 0; i < nCols; ++i) { sum += getEntry(row, i) * v[i]; } out[row] = sum; } return out; } /** {@inheritDoc} */ public RealVector operate(final RealVector v) throws IllegalArgumentException { try { return new ArrayRealVector(operate(((ArrayRealVector) v).getDataRef()), false); } catch (ClassCastException cce) { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.getDimension() != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.getDimension(), nCols); } final double[] out = new double[nRows]; for (int row = 0; row < nRows; ++row) { double sum = 0; for (int i = 0; i < nCols; ++i) { sum += getEntry(row, i) * v.getEntry(i); } out[row] = sum; } return new ArrayRealVector(out, false); } } /** {@inheritDoc} */ public double[] preMultiply(final double[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows); } final double[] out = new double[nCols]; for (int col = 0; col < nCols; ++col) { double sum = 0; for (int i = 0; i < nRows; ++i) { sum += getEntry(i, col) * v[i]; } out[col] = sum; } return out; } /** {@inheritDoc} */ public RealVector preMultiply(final RealVector v) throws IllegalArgumentException { try { return new ArrayRealVector(preMultiply(((ArrayRealVector) v).getDataRef()), false); } catch (ClassCastException cce) { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.getDimension() != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.getDimension(), nRows); } final double[] out = new double[nCols]; for (int col = 0; col < nCols; ++col) { double sum = 0; for (int i = 0; i < nRows; ++i) { sum += getEntry(i, col) * v.getEntry(i); } out[col] = sum; } return new ArrayRealVector(out); } } /** {@inheritDoc} */ public double walkInRowOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int row = 0; row < rows; ++row) { for (int column = 0; column < columns; ++column) { final double oldValue = getEntry(row, column); final double newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } lu = null; return visitor.end(); } /** {@inheritDoc} */ public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int row = 0; row < rows; ++row) { for (int column = 0; column < columns; ++column) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public double walkInRowOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int row = startRow; row <= endRow; ++row) { for (int column = startColumn; column <= endColumn; ++column) { final double oldValue = getEntry(row, column); final double newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } lu = null; return visitor.end(); } /** {@inheritDoc} */ public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int row = startRow; row <= endRow; ++row) { for (int column = startColumn; column <= endColumn; ++column) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int column = 0; column < columns; ++column) { for (int row = 0; row < rows; ++row) { final double oldValue = getEntry(row, column); final double newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } lu = null; return visitor.end(); } /** {@inheritDoc} */ public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int column = 0; column < columns; ++column) { for (int row = 0; row < rows; ++row) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int column = startColumn; column <= endColumn; ++column) { for (int row = startRow; row <= endRow; ++row) { final double oldValue = getEntry(row, column); final double newValue = visitor.visit(row, column, oldValue); setEntry(row, column, newValue); } } lu = null; return visitor.end(); } /** {@inheritDoc} */ public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int column = startColumn; column <= endColumn; ++column) { for (int row = startRow; row <= endRow; ++row) { visitor.visit(row, column, getEntry(row, column)); } } return visitor.end(); } /** {@inheritDoc} */ public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { return walkInRowOrder(visitor); } /** {@inheritDoc} */ public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { return walkInRowOrder(visitor); } /** {@inheritDoc} */ public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); } /** {@inheritDoc} */ public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); } /** {@inheritDoc} */ @Deprecated public double[] solve(final double[] b) throws IllegalArgumentException, InvalidMatrixException { if (lu == null) { lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); } return lu.solve(b); } /** {@inheritDoc} */ @Deprecated public RealMatrix solve(final RealMatrix b) throws IllegalArgumentException, InvalidMatrixException { if (lu == null) { lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); } return lu.solve(b); } /** * Computes a new * * LU decomposition for this matrix, storing the result for use by other methods. *

                    * Implementation Note:
                    * Uses * Crout's algorithm, with partial pivoting.

                    *

                    * Usage Note:
                    * This method should rarely be invoked directly. Its only use is * to force recomputation of the LU decomposition when changes have been * made to the underlying data using direct array references. Changes * made using setXxx methods will trigger recomputation when needed * automatically.

                    * * @throws InvalidMatrixException if the matrix is non-square or singular. * @deprecated as of release 2.0, replaced by {@link LUDecomposition} */ @Deprecated public void luDecompose() throws InvalidMatrixException { if (lu == null) { lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); } } /** * Get a string representation for this matrix. * @return a string representation for this matrix */ @Override public String toString() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final StringBuilder res = new StringBuilder(); String fullClassName = getClass().getName(); String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); res.append(shortClassName).append("{"); for (int i = 0; i < nRows; ++i) { if (i > 0) { res.append(","); } res.append("{"); for (int j = 0; j < nCols; ++j) { if (j > 0) { res.append(","); } res.append(getEntry(i, j)); } res.append("}"); } res.append("}"); return res.toString(); } /** * Returns true iff object is a * RealMatrix instance with the same dimensions as this * and all corresponding matrix entries are equal. * * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(final Object object) { if (object == this ) { return true; } if (object instanceof RealMatrix == false) { return false; } RealMatrix m = (RealMatrix) object; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { return false; } for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { if (getEntry(row, col) != m.getEntry(row, col)) { return false; } } } return true; } /** * Computes a hashcode for the matrix. * * @return hashcode for matrix */ @Override public int hashCode() { int ret = 7; final int nRows = getRowDimension(); final int nCols = getColumnDimension(); ret = ret * 31 + nRows; ret = ret * 31 + nCols; for (int row = 0; row < nRows; ++row) { for (int col = 0; col < nCols; ++col) { ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * MathUtils.hash(getEntry(row, col)); } } return ret; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealVectorFormat.java100644 1750 1750 26643 11532241245 27733 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.CompositeFormat; /** * Formats a vector in components list format "{v0; v1; ...; vk-1}". *

                    The prefix and suffix "{" and "}" and the separator "; " can be replaced by * any user-defined strings. The number format for components can be configured.

                    *

                    White space is ignored at parse time, even if it is in the prefix, suffix * or separator specifications. So even if the default separator does include a space * character that is used at format time, both input string "{1;1;1}" and * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be * returned. In the second case, however, the parse position after parsing will be * just after the closing curly brace, i.e. just before the trailing space.

                    * * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ * @since 2.0 */ public class RealVectorFormat extends CompositeFormat { /** Serializable version identifier */ private static final long serialVersionUID = -708767813036157690L; /** The default prefix: "{". */ private static final String DEFAULT_PREFIX = "{"; /** The default suffix: "}". */ private static final String DEFAULT_SUFFIX = "}"; /** The default separator: ", ". */ private static final String DEFAULT_SEPARATOR = "; "; /** Prefix. */ private final String prefix; /** Suffix. */ private final String suffix; /** Separator. */ private final String separator; /** Trimmed prefix. */ private final String trimmedPrefix; /** Trimmed suffix. */ private final String trimmedSuffix; /** Trimmed separator. */ private final String trimmedSeparator; /** The format used for components. */ private final NumberFormat format; /** * Create an instance with default settings. *

                    The instance uses the default prefix, suffix and separator: * "{", "}", and "; " and the default number format for components.

                    */ public RealVectorFormat() { this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, getDefaultNumberFormat()); } /** * Create an instance with a custom number format for components. * @param format the custom format for components. */ public RealVectorFormat(final NumberFormat format) { this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format); } /** * Create an instance with custom prefix, suffix and separator. * @param prefix prefix to use instead of the default "{" * @param suffix suffix to use instead of the default "}" * @param separator separator to use instead of the default "; " */ public RealVectorFormat(final String prefix, final String suffix, final String separator) { this(prefix, suffix, separator, getDefaultNumberFormat()); } /** * Create an instance with custom prefix, suffix, separator and format * for components. * @param prefix prefix to use instead of the default "{" * @param suffix suffix to use instead of the default "}" * @param separator separator to use instead of the default "; " * @param format the custom format for components. */ public RealVectorFormat(final String prefix, final String suffix, final String separator, final NumberFormat format) { this.prefix = prefix; this.suffix = suffix; this.separator = separator; trimmedPrefix = prefix.trim(); trimmedSuffix = suffix.trim(); trimmedSeparator = separator.trim(); this.format = format; } /** * Get the set of locales for which real vectors formats are available. *

                    This is the same set as the {@link NumberFormat} set.

                    * @return available real vector format locales. */ public static Locale[] getAvailableLocales() { return NumberFormat.getAvailableLocales(); } /** * Get the format prefix. * @return format prefix. */ public String getPrefix() { return prefix; } /** * Get the format suffix. * @return format suffix. */ public String getSuffix() { return suffix; } /** * Get the format separator between components. * @return format separator. */ public String getSeparator() { return separator; } /** * Get the components format. * @return components format. */ public NumberFormat getFormat() { return format; } /** * Returns the default real vector format for the current locale. * @return the default real vector format. */ public static RealVectorFormat getInstance() { return getInstance(Locale.getDefault()); } /** * Returns the default real vector format for the given locale. * @param locale the specific locale used by the format. * @return the real vector format specific to the given locale. */ public static RealVectorFormat getInstance(final Locale locale) { return new RealVectorFormat(getDefaultNumberFormat(locale)); } /** * This static method calls {@link #format(Object)} on a default instance of * RealVectorFormat. * * @param v RealVector object to format * @return A formatted vector */ public static String formatRealVector(RealVector v) { return getInstance().format(v); } /** * Formats a {@link RealVector} object to produce a string. * @param vector the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ public StringBuffer format(RealVector vector, StringBuffer toAppendTo, FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); // format prefix toAppendTo.append(prefix); // format components for (int i = 0; i < vector.getDimension(); ++i) { if (i > 0) { toAppendTo.append(separator); } formatDouble(vector.getEntry(i), format, toAppendTo, pos); } // format suffix toAppendTo.append(suffix); return toAppendTo; } /** * Formats a object to produce a string. *

                    obj must be a {@link RealVector} object. Any other type of * object will result in an {@link IllegalArgumentException} being thrown.

                    * @param obj the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) * @throws IllegalArgumentException is obj is not a valid type. */ @Override public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { if (obj instanceof RealVector) { return format( (RealVector)obj, toAppendTo, pos); } throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR, obj.getClass().getName()); } /** * Parses a string to produce a {@link RealVector} object. * @param source the string to parse * @return the parsed {@link RealVector} object. * @exception ParseException if the beginning of the specified string * cannot be parsed. */ public ArrayRealVector parse(String source) throws ParseException { ParsePosition parsePosition = new ParsePosition(0); ArrayRealVector result = parse(source, parsePosition); if (parsePosition.getIndex() == 0) { throw MathRuntimeException.createParseException( parsePosition.getErrorIndex(), LocalizedFormats.UNPARSEABLE_REAL_VECTOR, source); } return result; } /** * Parses a string to produce a {@link RealVector} object. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link RealVector} object. */ public ArrayRealVector parse(String source, ParsePosition pos) { int initialIndex = pos.getIndex(); // parse prefix parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedPrefix, pos)) { return null; } // parse components List components = new ArrayList(); for (boolean loop = true; loop;){ if (!components.isEmpty()) { parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedSeparator, pos)) { loop = false; } } if (loop) { parseAndIgnoreWhitespace(source, pos); Number component = parseNumber(source, format, pos); if (component != null) { components.add(component); } else { // invalid component // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } } } // parse suffix parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedSuffix, pos)) { return null; } // build vector double[] data = new double[components.size()]; for (int i = 0; i < data.length; ++i) { data[i] = components.get(i).doubleValue(); } return new ArrayRealVector(data, false); } /** * Parses a string to produce a object. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed object. * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) */ @Override public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SparseRealVector.java100644 1750 1750 2077 11532241245 27713 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * Marker interface for RealVectors that require sparse backing storage * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 * */ public interface SparseRealVector extends RealVector { } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisito100644 1750 1750 4056 11532241245 32526 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; import org.apache.commons.math.linear.MatrixVisitorException; /** * Default implementation of the {@link FieldMatrixPreservingVisitor} interface. *

                    * This class is a convenience to create custom visitors without defining all * methods. This class provides default implementations that do nothing. *

                    * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class DefaultFieldMatrixPreservingVisitor> implements FieldMatrixPreservingVisitor { /** Zero element of the field. */ private final T zero; /** Build a new instance. * @param zero additive identity of the field */ public DefaultFieldMatrixPreservingVisitor(final T zero) { this.zero = zero; } /** {@inheritDoc} */ public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { } /** {@inheritDoc} */ public void visit(int row, int column, T value) throws MatrixVisitorException { } /** {@inheritDoc} */ public T end() { return zero; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldDecompositionSolver.java100644 1750 1750 7546 11532241245 31450 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.FieldElement; /** * Interface handling decomposition algorithms that can solve A × X = B. *

                    Decomposition algorithms decompose an A matrix has a product of several specific * matrices from which they can solve A × X = B in least squares sense: they find X * such that ||A × X - B|| is minimal.

                    *

                    Some solvers like {@link LUDecomposition} can only find the solution for * square matrices and when the solution is an exact linear solution, i.e. when * ||A × X - B|| is exactly 0. Other solvers can also find solutions * with non-square matrix A and with non-null minimal norm. If an exact linear * solution exists it is also the minimal norm solution.

                    * * @param the type of the field elements * @version $Revision: 781122 $ $Date: 2009-06-02 20:53:23 +0200 (mar. 02 juin 2009) $ * @since 2.0 */ public interface FieldDecompositionSolver> { /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ T[] solve(final T[] b) throws IllegalArgumentException, InvalidMatrixException; /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ FieldVector solve(final FieldVector b) throws IllegalArgumentException, InvalidMatrixException; /** Solve the linear equation A × X = B for matrices A. *

                    The A matrix is implicit, it is provided by the underlying * decomposition algorithm.

                    * @param b right-hand side of the equation A × X = B * @return a matrix X that minimizes the two norm of A × X - B * @exception IllegalArgumentException if matrices dimensions don't match * @exception InvalidMatrixException if decomposed matrix is singular */ FieldMatrix solve(final FieldMatrix b) throws IllegalArgumentException, InvalidMatrixException; /** * Check if the decomposed matrix is non-singular. * @return true if the decomposed matrix is non-singular */ boolean isNonSingular(); /** Get the inverse (or pseudo-inverse) of the decomposed matrix. * @return inverse matrix * @throws InvalidMatrixException if decomposed matrix is singular */ FieldMatrix getInverse() throws InvalidMatrixException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/CholeskyDecomposition.java100644 1750 1750 5303 11532241245 31000 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * An interface to classes that implement an algorithm to calculate the * Cholesky decomposition of a real symmetric positive-definite matrix. *

                    This interface is based on the class with similar name from the * JAMA library, with the * following changes:

                    *
                      *
                    • a {@link #getLT() getLT} method has been added,
                    • *
                    • the isspd method has been removed, the constructors of * implementation classes being expected to throw {@link * NotPositiveDefiniteMatrixException} when a matrix cannot be decomposed,
                    • *
                    • a {@link #getDeterminant() getDeterminant} method has been added,
                    • *
                    • the solve method has been replaced by a {@link * #getSolver() getSolver} method and the equivalent method provided by * the returned {@link DecompositionSolver}.
                    • *
                    * * @see MathWorld * @see Wikipedia * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $ * @since 2.0 */ public interface CholeskyDecomposition { /** * Returns the matrix L of the decomposition. *

                    L is an lower-triangular matrix

                    * @return the L matrix */ RealMatrix getL(); /** * Returns the transpose of the matrix L of the decomposition. *

                    LT is an upper-triangular matrix

                    * @return the transpose of the matrix L of the decomposition */ RealMatrix getLT(); /** * Return the determinant of the matrix * @return determinant of the matrix */ double getDeterminant(); /** * Get a solver for finding the A × X = B solution in least square sense. * @return a solver */ DecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/LUDecomposition.java100644 1750 1750 7032 11532241245 27540 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * An interface to classes that implement an algorithm to calculate the * LU-decomposition of a real matrix. *

                    The LU-decomposition of matrix A is a set of three matrices: P, L and U * such that P×A = L×U. P is a rows permutation matrix that is used * to rearrange the rows of A before so that it can be decomposed. L is a lower * triangular matrix with unit diagonal terms and U is an upper triangular matrix.

                    *

                    This interface is based on the class with similar name from the * JAMA library.

                    *
                      *
                    • a {@link #getP() getP} method has been added,
                    • *
                    • the det method has been renamed as {@link #getDeterminant() * getDeterminant},
                    • *
                    • the getDoublePivot method has been removed (but the int based * {@link #getPivot() getPivot} method has been kept),
                    • *
                    • the solve and isNonSingular methods have been replaced * by a {@link #getSolver() getSolver} method and the equivalent methods provided by * the returned {@link DecompositionSolver}.
                    • *
                    * * @see MathWorld * @see Wikipedia * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $ * @since 2.0 */ public interface LUDecomposition { /** * Returns the matrix L of the decomposition. *

                    L is an lower-triangular matrix

                    * @return the L matrix (or null if decomposed matrix is singular) */ RealMatrix getL(); /** * Returns the matrix U of the decomposition. *

                    U is an upper-triangular matrix

                    * @return the U matrix (or null if decomposed matrix is singular) */ RealMatrix getU(); /** * Returns the P rows permutation matrix. *

                    P is a sparse matrix with exactly one element set to 1.0 in * each row and each column, all other elements being set to 0.0.

                    *

                    The positions of the 1 elements are given by the {@link #getPivot() * pivot permutation vector}.

                    * @return the P rows permutation matrix (or null if decomposed matrix is singular) * @see #getPivot() */ RealMatrix getP(); /** * Returns the pivot permutation vector. * @return the pivot permutation vector * @see #getP() */ int[] getPivot(); /** * Return the determinant of the matrix * @return determinant of the matrix */ double getDeterminant(); /** * Get a solver for finding the A × X = B solution in exact linear sense. * @return a solver */ DecompositionSolver getSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/AnyMatrix.java100644 1750 1750 2655 11532241245 26405 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; /** * Interface defining very basic matrix operations. * @version $Revision: 772119 $ $Date: 2009-05-06 11:43:28 +0200 (mer. 06 mai 2009) $ * @since 2.0 */ public interface AnyMatrix { /** * Is this a square matrix? * @return true if the matrix is square (rowDimension = columnDimension) */ boolean isSquare(); /** * Returns the number of rows in the matrix. * * @return rowDimension */ int getRowDimension(); /** * Returns the number of columns in the matrix. * * @return columnDimension */ int getColumnDimension(); } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException100644 1750 1750 3036 11532241245 32542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * This class represents exceptions thrown when a matrix expected to * be positive definite is not. * * @since 1.2 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class NotPositiveDefiniteMatrixException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = 4122929125438624648L; /** Simple constructor. * build an exception with a default message. */ public NotPositiveDefiniteMatrixException() { super(LocalizedFormats.NOT_POSITIVE_DEFINITE_MATRIX); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SingularMatrixException.java100644 1750 1750 2605 11532241245 31314 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Thrown when a matrix is singular. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class SingularMatrixException extends InvalidMatrixException { /** Serializable version identifier. */ private static final long serialVersionUID = -7379143356784298432L; /** * Construct an exception with a default message. */ public SingularMatrixException() { super(LocalizedFormats.SINGULAR_MATRIX); } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.jav100644 1750 1750 31064 11532241245 32504 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Calculates the compact Singular Value Decomposition of a matrix. *

                    * The Singular Value Decomposition of matrix A is a set of three matrices: U, * Σ and V such that A = U × Σ × VT. Let A be * a m × n matrix, then U is a m × p orthogonal matrix, Σ is a * p × p diagonal matrix with positive or null elements, V is a p × * n orthogonal matrix (hence VT is also orthogonal) where * p=min(m,n). *

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class SingularValueDecompositionImpl implements SingularValueDecomposition { /** Number of rows of the initial matrix. */ private int m; /** Number of columns of the initial matrix. */ private int n; /** Eigen decomposition of the tridiagonal matrix. */ private EigenDecomposition eigenDecomposition; /** Singular values. */ private double[] singularValues; /** Cached value of U. */ private RealMatrix cachedU; /** Cached value of UT. */ private RealMatrix cachedUt; /** Cached value of S. */ private RealMatrix cachedS; /** Cached value of V. */ private RealMatrix cachedV; /** Cached value of VT. */ private RealMatrix cachedVt; /** * Calculates the compact Singular Value Decomposition of the given matrix. * @param matrix * The matrix to decompose. * @exception InvalidMatrixException * (wrapping a * {@link org.apache.commons.math.ConvergenceException} if * algorithm fails to converge */ public SingularValueDecompositionImpl(final RealMatrix matrix) throws InvalidMatrixException { m = matrix.getRowDimension(); n = matrix.getColumnDimension(); cachedU = null; cachedS = null; cachedV = null; cachedVt = null; double[][] localcopy = matrix.getData(); double[][] matATA = new double[n][n]; // // create A^T*A // for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { matATA[i][j] = 0.0; for (int k = 0; k < m; k++) { matATA[i][j] += localcopy[k][i] * localcopy[k][j]; } matATA[j][i]=matATA[i][j]; } } double[][] matAAT = new double[m][m]; // // create A*A^T // for (int i = 0; i < m; i++) { for (int j = i; j < m; j++) { matAAT[i][j] = 0.0; for (int k = 0; k < n; k++) { matAAT[i][j] += localcopy[i][k] * localcopy[j][k]; } matAAT[j][i]=matAAT[i][j]; } } int p; if (m>=n) { p=n; // compute eigen decomposition of A^T*A eigenDecomposition = new EigenDecompositionImpl( new Array2DRowRealMatrix(matATA),1.0); singularValues = eigenDecomposition.getRealEigenvalues(); cachedV = eigenDecomposition.getV(); // compute eigen decomposition of A*A^T eigenDecomposition = new EigenDecompositionImpl( new Array2DRowRealMatrix(matAAT),1.0); cachedU = eigenDecomposition.getV().getSubMatrix(0, m - 1, 0, p - 1); } else { p=m; // compute eigen decomposition of A*A^T eigenDecomposition = new EigenDecompositionImpl( new Array2DRowRealMatrix(matAAT),1.0); singularValues = eigenDecomposition.getRealEigenvalues(); cachedU = eigenDecomposition.getV(); // compute eigen decomposition of A^T*A eigenDecomposition = new EigenDecompositionImpl( new Array2DRowRealMatrix(matATA),1.0); cachedV = eigenDecomposition.getV().getSubMatrix(0,n-1,0,p-1); } for (int i = 0; i < p; i++) { singularValues[i] = FastMath.sqrt(FastMath.abs(singularValues[i])); } // Up to this point, U and V are computed independently of each other. // There still a sign indetermination of each column of, say, U. // The sign is set such that A.V_i=sigma_i.U_i (i<=p) // The right sign corresponds to a positive dot product of A.V_i and U_i for (int i = 0; i < p; i++) { RealVector tmp = cachedU.getColumnVector(i); double product=matrix.operate(cachedV.getColumnVector(i)).dotProduct(tmp); if (product<0) { cachedU.setColumnVector(i, tmp.mapMultiply(-1.0)); } } } /** {@inheritDoc} */ public RealMatrix getU() throws InvalidMatrixException { // return the cached matrix return cachedU; } /** {@inheritDoc} */ public RealMatrix getUT() throws InvalidMatrixException { if (cachedUt == null) { cachedUt = getU().transpose(); } // return the cached matrix return cachedUt; } /** {@inheritDoc} */ public RealMatrix getS() throws InvalidMatrixException { if (cachedS == null) { // cache the matrix for subsequent calls cachedS = MatrixUtils.createRealDiagonalMatrix(singularValues); } return cachedS; } /** {@inheritDoc} */ public double[] getSingularValues() throws InvalidMatrixException { return singularValues.clone(); } /** {@inheritDoc} */ public RealMatrix getV() throws InvalidMatrixException { // return the cached matrix return cachedV; } /** {@inheritDoc} */ public RealMatrix getVT() throws InvalidMatrixException { if (cachedVt == null) { cachedVt = getV().transpose(); } // return the cached matrix return cachedVt; } /** {@inheritDoc} */ public RealMatrix getCovariance(final double minSingularValue) { // get the number of singular values to consider final int p = singularValues.length; int dimension = 0; while ((dimension < p) && (singularValues[dimension] >= minSingularValue)) { ++dimension; } if (dimension == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.TOO_LARGE_CUTOFF_SINGULAR_VALUE, minSingularValue, singularValues[0]); } final double[][] data = new double[dimension][p]; getVT().walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { /** {@inheritDoc} */ @Override public void visit(final int row, final int column, final double value) { data[row][column] = value / singularValues[row]; } }, 0, dimension - 1, 0, p - 1); RealMatrix jv = new Array2DRowRealMatrix(data, false); return jv.transpose().multiply(jv); } /** {@inheritDoc} */ public double getNorm() throws InvalidMatrixException { return singularValues[0]; } /** {@inheritDoc} */ public double getConditionNumber() throws InvalidMatrixException { return singularValues[0] / singularValues[singularValues.length - 1]; } /** {@inheritDoc} */ public int getRank() throws IllegalStateException { final double threshold = FastMath.max(m, n) * FastMath.ulp(singularValues[0]); for (int i = singularValues.length - 1; i >= 0; --i) { if (singularValues[i] > threshold) { return i + 1; } } return 0; } /** {@inheritDoc} */ public DecompositionSolver getSolver() { return new Solver(singularValues, getUT(), getV(), getRank() == Math .max(m, n)); } /** Specialized solver. */ private static class Solver implements DecompositionSolver { /** Pseudo-inverse of the initial matrix. */ private final RealMatrix pseudoInverse; /** Singularity indicator. */ private boolean nonSingular; /** * Build a solver from decomposed matrix. * @param singularValues * singularValues * @param uT * UT matrix of the decomposition * @param v * V matrix of the decomposition * @param nonSingular * singularity indicator */ private Solver(final double[] singularValues, final RealMatrix uT, final RealMatrix v, final boolean nonSingular) { double[][] suT = uT.getData(); for (int i = 0; i < singularValues.length; ++i) { final double a; if (singularValues[i]>0) { a=1.0 / singularValues[i]; } else { a=0.0; } final double[] suTi = suT[i]; for (int j = 0; j < suTi.length; ++j) { suTi[j] *= a; } } pseudoInverse = v.multiply(new Array2DRowRealMatrix(suT, false)); this.nonSingular = nonSingular; } /** * Solve the linear equation A × X = B in least square sense. *

                    * The m×n matrix A may not be square, the solution X is such that * ||A × X - B|| is minimal. *

                    * @param b * right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match */ public double[] solve(final double[] b) throws IllegalArgumentException { return pseudoInverse.operate(b); } /** * Solve the linear equation A × X = B in least square sense. *

                    * The m×n matrix A may not be square, the solution X is such that * ||A × X - B|| is minimal. *

                    * @param b * right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match */ public RealVector solve(final RealVector b) throws IllegalArgumentException { return pseudoInverse.operate(b); } /** * Solve the linear equation A × X = B in least square sense. *

                    * The m×n matrix A may not be square, the solution X is such that * ||A × X - B|| is minimal. *

                    * @param b * right-hand side of the equation A × X = B * @return a matrix X that minimizes the two norm of A × X - B * @exception IllegalArgumentException * if matrices dimensions don't match */ public RealMatrix solve(final RealMatrix b) throws IllegalArgumentException { return pseudoInverse.multiply(b); } /** * Check if the decomposed matrix is non-singular. * @return true if the decomposed matrix is non-singular */ public boolean isNonSingular() { return nonSingular; } /** * Get the pseudo-inverse of the decomposed matrix. * @return inverse matrix */ public RealMatrix getInverse() { return pseudoInverse; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/MatrixVisitorException.java100644 1750 1750 3740 11532241245 31170 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * Thrown when a visitor encounters an error while processing a matrix entry. * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class MatrixVisitorException extends MathRuntimeException { /** Serializable version identifier */ private static final long serialVersionUID = 3814333035048617048L; /** * Constructs a new instance with specified formatted detail message. * @param pattern format specifier * @param arguments format arguments */ public MatrixVisitorException(final String pattern, final Object[] arguments) { super(new DummyLocalizable(pattern), arguments); } /** * Constructs a new instance with specified formatted detail message. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MatrixVisitorException(final Localizable pattern, final Object[] arguments) { super(pattern, arguments); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/RealMatrixImpl.java100644 1750 1750 54213 11532241245 27400 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implementation of RealMatrix using a double[][] array to store entries and * * LU decomposition to support linear system * solution and inverse. *

                    * The LU decomposition is performed as needed, to support the following operations:

                      *
                    • solve
                    • *
                    • isSingular
                    • *
                    • getDeterminant
                    • *
                    • inverse

                    *

                    * Usage notes:
                    *

                    • * The LU decomposition is cached and reused on subsequent calls. * If data are modified via references to the underlying array obtained using * getDataRef(), then the stored LU decomposition will not be * discarded. In this case, you need to explicitly invoke * LUDecompose() to recompute the decomposition * before using any of the methods above.
                    • *
                    • * As specified in the {@link RealMatrix} interface, matrix element indexing * is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.
                    *

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @deprecated as of 2.0 replaced by {@link Array2DRowRealMatrix} */ @Deprecated public class RealMatrixImpl extends AbstractRealMatrix implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1067294169172445528L; /** Entries of the matrix */ protected double data[][]; /** * Creates a matrix with no data */ public RealMatrixImpl() { } /** * Create a new RealMatrix with the supplied row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public RealMatrixImpl(final int rowDimension, final int columnDimension) throws IllegalArgumentException { super(rowDimension, columnDimension); data = new double[rowDimension][columnDimension]; } /** * Create a new RealMatrix using the input array as the underlying * data array. *

                    The input array is copied, not referenced. This constructor has * the same effect as calling {@link #RealMatrixImpl(double[][], boolean)} * with the second argument set to true.

                    * * @param d data for new matrix * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #RealMatrixImpl(double[][], boolean) */ public RealMatrixImpl(final double[][] d) throws IllegalArgumentException, NullPointerException { copyIn(d); } /** * Create a new RealMatrix using the input array as the underlying * data array. *

                    If an array is built specially in order to be embedded in a * RealMatrix and not used directly, the copyArray may be * set to false * @param d data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * @throws IllegalArgumentException if d is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if d is null * @see #RealMatrixImpl(double[][]) */ public RealMatrixImpl(final double[][] d, final boolean copyArray) throws IllegalArgumentException, NullPointerException { if (copyArray) { copyIn(d); } else { if (d == null) { throw new NullPointerException(); } final int nRows = d.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = d[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } for (int r = 1; r < nRows; r++) { if (d[r].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length); } } data = d; } } /** * Create a new (column) RealMatrix using v as the * data for the unique column of the v.length x 1 matrix * created. *

                    The input array is copied, not referenced.

                    * * @param v column vector holding data for new matrix */ public RealMatrixImpl(final double[] v) { final int nRows = v.length; data = new double[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = v[row]; } } /** {@inheritDoc} */ @Override public RealMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { return new RealMatrixImpl(rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public RealMatrix copy() { return new RealMatrixImpl(copyOut(), false); } /** {@inheritDoc} */ @Override public RealMatrix add(final RealMatrix m) throws IllegalArgumentException { try { return add((RealMatrixImpl) m); } catch (ClassCastException cce) { return super.add(m); } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public RealMatrixImpl add(final RealMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final double[] dataRow = data[row]; final double[] mRow = m.data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col] + mRow[col]; } } return new RealMatrixImpl(outData, false); } /** {@inheritDoc} */ @Override public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { try { return subtract((RealMatrixImpl) m); } catch (ClassCastException cce) { return super.subtract(m); } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public RealMatrixImpl subtract(final RealMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final int rowCount = getRowDimension(); final int columnCount = getColumnDimension(); final double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { final double[] dataRow = data[row]; final double[] mRow = m.data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < columnCount; col++) { outDataRow[col] = dataRow[col] - mRow[col]; } } return new RealMatrixImpl(outData, false); } /** {@inheritDoc} */ @Override public RealMatrix multiply(final RealMatrix m) throws IllegalArgumentException { try { return multiply((RealMatrixImpl) m); } catch (ClassCastException cce) { return super.multiply(m); } } /** * Returns the result of postmultiplying this by m. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public RealMatrixImpl multiply(final RealMatrixImpl m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final int nRows = this.getRowDimension(); final int nCols = m.getColumnDimension(); final int nSum = this.getColumnDimension(); final double[][] outData = new double[nRows][nCols]; for (int row = 0; row < nRows; row++) { final double[] dataRow = data[row]; final double[] outDataRow = outData[row]; for (int col = 0; col < nCols; col++) { double sum = 0; for (int i = 0; i < nSum; i++) { sum += dataRow[i] * m.data[i][col]; } outDataRow[col] = sum; } } return new RealMatrixImpl(outData, false); } /** {@inheritDoc} */ @Override public double[][] getData() { return copyOut(); } /** * Returns a reference to the underlying data array. *

                    * Does not make a fresh copy of the underlying data.

                    * * @return 2-dimensional array of entries */ public double[][] getDataRef() { return data; } /** {@inheritDoc} */ @Override public void setSubMatrix(final double[][] subMatrix, final int row, final int column) throws MatrixIndexException { if (data == null) { if (row > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row); } if (column > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column); } final int nRows = subMatrix.length; if (nRows == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW); } final int nCols = subMatrix[0].length; if (nCols == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } data = new double[subMatrix.length][nCols]; for (int i = 0; i < data.length; ++i) { if (subMatrix[i].length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[i].length); } System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); } } else { super.setSubMatrix(subMatrix, row, column); } } /** {@inheritDoc} */ @Override public double getEntry(final int row, final int column) throws MatrixIndexException { try { return data[row][column]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void setEntry(final int row, final int column, final double value) throws MatrixIndexException { try { data[row][column] = value; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void addToEntry(final int row, final int column, final double increment) throws MatrixIndexException { try { data[row][column] += increment; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void multiplyEntry(final int row, final int column, final double factor) throws MatrixIndexException { try { data[row][column] *= factor; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public int getRowDimension() { return (data == null) ? 0 : data.length; } /** {@inheritDoc} */ @Override public int getColumnDimension() { return ((data == null) || (data[0] == null)) ? 0 : data[0].length; } /** {@inheritDoc} */ @Override public double[] operate(final double[] v) throws IllegalArgumentException { final int nRows = this.getRowDimension(); final int nCols = this.getColumnDimension(); if (v.length != nCols) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols); } final double[] out = new double[nRows]; for (int row = 0; row < nRows; row++) { final double[] dataRow = data[row]; double sum = 0; for (int i = 0; i < nCols; i++) { sum += dataRow[i] * v[i]; } out[row] = sum; } return out; } /** {@inheritDoc} */ @Override public double[] preMultiply(final double[] v) throws IllegalArgumentException { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); if (v.length != nRows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows); } final double[] out = new double[nCols]; for (int col = 0; col < nCols; ++col) { double sum = 0; for (int i = 0; i < nRows; ++i) { sum += data[i][col] * v[i]; } out[col] = sum; } return out; } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; for (int j = 0; j < columns; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; for (int j = 0; j < columns; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; for (int j = startColumn; j <= endColumn; ++j) { visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { final double[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { final int rows = getRowDimension(); final int columns = getColumnDimension(); visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int j = 0; j < columns; ++j) { for (int i = 0; i < rows; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { final double[] rowI = data[i]; rowI[j] = visitor.visit(i, j, rowI[j]); } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { visitor.visit(i, j, data[i][j]); } } return visitor.end(); } /** * Returns a fresh copy of the underlying data array. * * @return a copy of the underlying data array. */ private double[][] copyOut() { final int nRows = this.getRowDimension(); final double[][] out = new double[nRows][this.getColumnDimension()]; // can't copy 2-d array in one shot, otherwise get row references for (int i = 0; i < nRows; i++) { System.arraycopy(data[i], 0, out[i], 0, data[i].length); } return out; } /** * Replaces data with a fresh copy of the input array. *

                    * Verifies that the input array is rectangular and non-empty.

                    * * @param in data to copy in * @throws IllegalArgumentException if input array is empty or not * rectangular * @throws NullPointerException if input array is null */ private void copyIn(final double[][] in) { setSubMatrix(in, 0, 0); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/NotSymmetricMatrixException.java100644 1750 1750 3000 11532241245 32153 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * This class represents exceptions thrown when a matrix expected to * be symmetric is not * * @since 2.0 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class NotSymmetricMatrixException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -7012803946709786097L; /** Simple constructor. * build an exception with a default message. */ public NotSymmetricMatrixException() { super(LocalizedFormats.NOT_SYMMETRIC_MATRIX); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/BlockRealMatrix.java100644 1750 1750 206540 11532241245 27553 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.linear.MatrixVisitorException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Cache-friendly implementation of RealMatrix using a flat arrays to store * square blocks of the matrix. *

                    * This implementation is specially designed to be cache-friendly. Square blocks are * stored as small arrays and allow efficient traversal of data both in row major direction * and columns major direction, one block at a time. This greatly increases performances * for algorithms that use crossed directions loops like multiplication or transposition. *

                    *

                    * The size of square blocks is a static parameter. It may be tuned according to the cache * size of the target computer processor. As a rule of thumbs, it should be the largest * value that allows three blocks to be simultaneously cached (this is necessary for example * for matrix multiplication). The default value is to use 52x52 blocks which is well suited * for processors with 64k L1 cache (one block holds 2704 values or 21632 bytes). This value * could be lowered to 36x36 for processors with 32k L1 cache. *

                    *

                    * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square * blocks are flattened in row major order in single dimension arrays which are therefore * {@link #BLOCK_SIZE}2 elements long for regular blocks. The blocks are themselves * organized in row major order. *

                    *

                    * As an example, for a block size of 52x52, a 100x60 matrix would be stored in 4 blocks. * Block 0 would be a double[2704] array holding the upper left 52x52 square, block 1 would be * a double[416] array holding the upper right 52x8 rectangle, block 2 would be a double[2496] * array holding the lower left 48x52 rectangle and block 3 would be a double[384] array * holding the lower right 48x8 rectangle. *

                    *

                    * The layout complexity overhead versus simple mapping of matrices to java * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads * to up to 3-fold improvements for matrices of moderate to large size. *

                    * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class BlockRealMatrix extends AbstractRealMatrix implements Serializable { /** Block size. */ public static final int BLOCK_SIZE = 52; /** Serializable version identifier */ private static final long serialVersionUID = 4991895511313664478L; /** Blocks of matrix entries. */ private final double blocks[][]; /** Number of rows of the matrix. */ private final int rows; /** Number of columns of the matrix. */ private final int columns; /** Number of block rows of the matrix. */ private final int blockRows; /** Number of block columns of the matrix. */ private final int blockColumns; /** * Create a new matrix with the supplied row and column dimensions. * * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @throws IllegalArgumentException if row or column dimension is not * positive */ public BlockRealMatrix(final int rows, final int columns) throws IllegalArgumentException { super(rows, columns); this.rows = rows; this.columns = columns; // number of blocks blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; // allocate storage blocks, taking care of smaller ones at right and bottom blocks = createBlocksLayout(rows, columns); } /** * Create a new dense matrix copying entries from raw layout data. *

                    The input array must already be in raw layout.

                    *

                    Calling this constructor is equivalent to call: *

                    matrix = new BlockRealMatrix(rawData.length, rawData[0].length,
                         *                                   toBlocksLayout(rawData), false);
                    *

                    * @param rawData data for new matrix, in raw layout * * @exception IllegalArgumentException if blockData shape is * inconsistent with block layout * @see #BlockRealMatrix(int, int, double[][], boolean) */ public BlockRealMatrix(final double[][] rawData) throws IllegalArgumentException { this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false); } /** * Create a new dense matrix copying entries from block layout data. *

                    The input array must already be in blocks layout.

                    * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @param blockData data for new matrix * @param copyArray if true, the input array will be copied, otherwise * it will be referenced * * @exception IllegalArgumentException if blockData shape is * inconsistent with block layout * @see #createBlocksLayout(int, int) * @see #toBlocksLayout(double[][]) * @see #BlockRealMatrix(double[][]) */ public BlockRealMatrix(final int rows, final int columns, final double[][] blockData, final boolean copyArray) throws IllegalArgumentException { super(rows, columns); this.rows = rows; this.columns = columns; // number of blocks blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; if (copyArray) { // allocate storage blocks, taking care of smaller ones at right and bottom blocks = new double[blockRows * blockColumns][]; } else { // reference existing array blocks = blockData; } int index = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) { if (blockData[index].length != iHeight * blockWidth(jBlock)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.WRONG_BLOCK_LENGTH, blockData[index].length, iHeight * blockWidth(jBlock)); } if (copyArray) { blocks[index] = blockData[index].clone(); } } } } /** * Convert a data array from raw layout to blocks layout. *

                    * Raw layout is the straightforward layout where element at row i and * column j is in array element rawData[i][j]. Blocks layout * is the layout used in {@link BlockRealMatrix} instances, where the matrix * is split in square blocks (except at right and bottom side where blocks may * be rectangular to fit matrix size) and each block is stored in a flattened * one-dimensional array. *

                    *

                    * This method creates an array in blocks layout from an input array in raw layout. * It can be used to provide the array argument of the {@link * #BlockRealMatrix(int, int, double[][], boolean)} constructor. *

                    * @param rawData data array in raw layout * @return a new data array containing the same entries but in blocks layout * @exception IllegalArgumentException if rawData is not rectangular * (not all rows have the same length) * @see #createBlocksLayout(int, int) * @see #BlockRealMatrix(int, int, double[][], boolean) */ public static double[][] toBlocksLayout(final double[][] rawData) throws IllegalArgumentException { final int rows = rawData.length; final int columns = rawData[0].length; final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; // safety checks for (int i = 0; i < rawData.length; ++i) { final int length = rawData[i].length; if (length != columns) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, columns, length); } } // convert array final double[][] blocks = new double[blockRows * blockColumns][]; int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int iHeight = pEnd - pStart; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final int jWidth = qEnd - qStart; // allocate new block final double[] block = new double[iHeight * jWidth]; blocks[blockIndex] = block; // copy data int index = 0; for (int p = pStart; p < pEnd; ++p) { System.arraycopy(rawData[p], qStart, block, index, jWidth); index += jWidth; } ++blockIndex; } } return blocks; } /** * Create a data array in blocks layout. *

                    * This method can be used to create the array argument of the {@link * #BlockRealMatrix(int, int, double[][], boolean)} constructor. *

                    * @param rows the number of rows in the new matrix * @param columns the number of columns in the new matrix * @return a new data array in blocks layout * @see #toBlocksLayout(double[][]) * @see #BlockRealMatrix(int, int, double[][], boolean) */ public static double[][] createBlocksLayout(final int rows, final int columns) { final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; final double[][] blocks = new double[blockRows * blockColumns][]; int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int iHeight = pEnd - pStart; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final int jWidth = qEnd - qStart; blocks[blockIndex] = new double[iHeight * jWidth]; ++blockIndex; } } return blocks; } /** {@inheritDoc} */ @Override public BlockRealMatrix createMatrix(final int rowDimension, final int columnDimension) throws IllegalArgumentException { return new BlockRealMatrix(rowDimension, columnDimension); } /** {@inheritDoc} */ @Override public BlockRealMatrix copy() { // create an empty matrix BlockRealMatrix copied = new BlockRealMatrix(rows, columns); // copy the blocks for (int i = 0; i < blocks.length; ++i) { System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length); } return copied; } /** {@inheritDoc} */ @Override public BlockRealMatrix add(final RealMatrix m) throws IllegalArgumentException { try { return add((BlockRealMatrix) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkAdditionCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform addition block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { // perform addition on the current block final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[k] + m.getEntry(p, q); ++k; } } // go to next block ++blockIndex; } } return out; } } /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ public BlockRealMatrix add(final BlockRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkAdditionCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform addition block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; final double[] mBlock = m.blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k] + mBlock[k]; } } return out; } /** {@inheritDoc} */ @Override public BlockRealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { try { return subtract((BlockRealMatrix) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform subtraction block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { // perform subtraction on the current block final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[k] - m.getEntry(p, q); ++k; } } // go to next block ++blockIndex; } } return out; } } /** * Compute this minus m. * * @param m matrix to be subtracted * @return this - m * @throws IllegalArgumentException if m is not the same size as this */ public BlockRealMatrix subtract(final BlockRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkSubtractionCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; final double[] mBlock = m.blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k] - mBlock[k]; } } return out; } /** {@inheritDoc} */ @Override public BlockRealMatrix scalarAdd(final double d) throws IllegalArgumentException { final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k] + d; } } return out; } /** {@inheritDoc} */ @Override public RealMatrix scalarMultiply(final double d) throws IllegalArgumentException { final BlockRealMatrix out = new BlockRealMatrix(rows, columns); // perform subtraction block-wise, to ensure good cache behavior for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[blockIndex]; for (int k = 0; k < outBlock.length; ++k) { outBlock[k] = tBlock[k] * d; } } return out; } /** {@inheritDoc} */ @Override public BlockRealMatrix multiply(final RealMatrix m) throws IllegalArgumentException { try { return multiply((BlockRealMatrix) m); } catch (ClassCastException cce) { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, m.getColumnDimension()); // perform multiplication block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, m.getColumnDimension()); // select current block final double[] outBlock = out.blocks[blockIndex]; // perform multiplication on current block for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { final int kWidth = blockWidth(kBlock); final double[] tBlock = blocks[iBlock * blockColumns + kBlock]; final int rStart = kBlock * BLOCK_SIZE; int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lStart = (p - pStart) * kWidth; final int lEnd = lStart + kWidth; for (int q = qStart; q < qEnd; ++q) { double sum = 0; int r = rStart; for (int l = lStart; l < lEnd; ++l) { sum += tBlock[l] * m.getEntry(r, q); ++r; } outBlock[k] += sum; ++k; } } } // go to next block ++blockIndex; } } return out; } } /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BlockRealMatrix multiply(BlockRealMatrix m) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, m); final BlockRealMatrix out = new BlockRealMatrix(rows, m.columns); // perform multiplication block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int jWidth = out.blockWidth(jBlock); final int jWidth2 = jWidth + jWidth; final int jWidth3 = jWidth2 + jWidth; final int jWidth4 = jWidth3 + jWidth; // select current block final double[] outBlock = out.blocks[blockIndex]; // perform multiplication on current block for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { final int kWidth = blockWidth(kBlock); final double[] tBlock = blocks[iBlock * blockColumns + kBlock]; final double[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock]; int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lStart = (p - pStart) * kWidth; final int lEnd = lStart + kWidth; for (int nStart = 0; nStart < jWidth; ++nStart) { double sum = 0; int l = lStart; int n = nStart; while (l < lEnd - 3) { sum += tBlock[l] * mBlock[n] + tBlock[l + 1] * mBlock[n + jWidth] + tBlock[l + 2] * mBlock[n + jWidth2] + tBlock[l + 3] * mBlock[n + jWidth3]; l += 4; n += jWidth4; } while (l < lEnd) { sum += tBlock[l++] * mBlock[n]; n += jWidth; } outBlock[k] += sum; ++k; } } } // go to next block ++blockIndex; } } return out; } /** {@inheritDoc} */ @Override public double[][] getData() { final double[][] data = new double[getRowDimension()][getColumnDimension()]; final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); int regularPos = 0; int lastPos = 0; for (int p = pStart; p < pEnd; ++p) { final double[] dataP = data[p]; int blockIndex = iBlock * blockColumns; int dataPos = 0; for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) { System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE); dataPos += BLOCK_SIZE; } System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns); regularPos += BLOCK_SIZE; lastPos += lastColumns; } } return data; } /** {@inheritDoc} */ @Override public double getNorm() { final double[] colSums = new double[BLOCK_SIZE]; double maxColSum = 0; for (int jBlock = 0; jBlock < blockColumns; jBlock++) { final int jWidth = blockWidth(jBlock); Arrays.fill(colSums, 0, jWidth, 0.0); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int j = 0; j < jWidth; ++j) { double sum = 0; for (int i = 0; i < iHeight; ++i) { sum += FastMath.abs(block[i * jWidth + j]); } colSums[j] += sum; } } for (int j = 0; j < jWidth; ++j) { maxColSum = FastMath.max(maxColSum, colSums[j]); } } return maxColSum; } /** {@inheritDoc} */ @Override public double getFrobeniusNorm() { double sum2 = 0; for (int blockIndex = 0; blockIndex < blocks.length; ++blockIndex) { for (final double entry : blocks[blockIndex]) { sum2 += entry * entry; } } return FastMath.sqrt(sum2); } /** {@inheritDoc} */ @Override public BlockRealMatrix getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException { // safety checks MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); // create the output matrix final BlockRealMatrix out = new BlockRealMatrix(endRow - startRow + 1, endColumn - startColumn + 1); // compute blocks shifts final int blockStartRow = startRow / BLOCK_SIZE; final int rowsShift = startRow % BLOCK_SIZE; final int blockStartColumn = startColumn / BLOCK_SIZE; final int columnsShift = startColumn % BLOCK_SIZE; // perform extraction block-wise, to ensure good cache behavior int pBlock = blockStartRow; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int iHeight = out.blockHeight(iBlock); int qBlock = blockStartColumn; for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int jWidth = out.blockWidth(jBlock); // handle one block of the output matrix final int outIndex = iBlock * out.blockColumns + jBlock; final double[] outBlock = out.blocks[outIndex]; final int index = pBlock * blockColumns + qBlock; final int width = blockWidth(qBlock); final int heightExcess = iHeight + rowsShift - BLOCK_SIZE; final int widthExcess = jWidth + columnsShift - BLOCK_SIZE; if (heightExcess > 0) { // the submatrix block spans on two blocks rows from the original matrix if (widthExcess > 0) { // the submatrix block spans on two blocks columns from the original matrix final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, BLOCK_SIZE, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, BLOCK_SIZE, outBlock, jWidth, iHeight - heightExcess, 0); copyBlockPart(blocks[index + blockColumns + 1], width2, 0, heightExcess, 0, widthExcess, outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess); } else { // the submatrix block spans on one block column from the original matrix copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, jWidth + columnsShift, outBlock, jWidth, iHeight - heightExcess, 0); } } else { // the submatrix block spans on one block row from the original matrix if (widthExcess > 0) { // the submatrix block spans on two blocks columns from the original matrix final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, iHeight + rowsShift, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); } else { // the submatrix block spans on one block column from the original matrix copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); } } ++qBlock; } ++pBlock; } return out; } /** * Copy a part of a block into another one *

                    This method can be called only when the specified part fits in both * blocks, no verification is done here.

                    * @param srcBlock source block * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller) * @param srcStartRow start row in the source block * @param srcEndRow end row (exclusive) in the source block * @param srcStartColumn start column in the source block * @param srcEndColumn end column (exclusive) in the source block * @param dstBlock destination block * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller) * @param dstStartRow start row in the destination block * @param dstStartColumn start column in the destination block */ private void copyBlockPart(final double[] srcBlock, final int srcWidth, final int srcStartRow, final int srcEndRow, final int srcStartColumn, final int srcEndColumn, final double[] dstBlock, final int dstWidth, final int dstStartRow, final int dstStartColumn) { final int length = srcEndColumn - srcStartColumn; int srcPos = srcStartRow * srcWidth + srcStartColumn; int dstPos = dstStartRow * dstWidth + dstStartColumn; for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) { System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length); srcPos += srcWidth; dstPos += dstWidth; } } /** {@inheritDoc} */ @Override public void setSubMatrix(final double[][] subMatrix, final int row, final int column) throws MatrixIndexException { // safety checks final int refLength = subMatrix[0].length; if (refLength < 1) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN); } final int endRow = row + subMatrix.length - 1; final int endColumn = column + refLength - 1; MatrixUtils.checkSubMatrixIndex(this, row, endRow, column, endColumn); for (final double[] subRow : subMatrix) { if (subRow.length != refLength) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, refLength, subRow.length); } } // compute blocks bounds final int blockStartRow = row / BLOCK_SIZE; final int blockEndRow = (endRow + BLOCK_SIZE) / BLOCK_SIZE; final int blockStartColumn = column / BLOCK_SIZE; final int blockEndColumn = (endColumn + BLOCK_SIZE) / BLOCK_SIZE; // perform copy block-wise, to ensure good cache behavior for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) { final int iHeight = blockHeight(iBlock); final int firstRow = iBlock * BLOCK_SIZE; final int iStart = FastMath.max(row, firstRow); final int iEnd = FastMath.min(endRow + 1, firstRow + iHeight); for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) { final int jWidth = blockWidth(jBlock); final int firstColumn = jBlock * BLOCK_SIZE; final int jStart = FastMath.max(column, firstColumn); final int jEnd = FastMath.min(endColumn + 1, firstColumn + jWidth); final int jLength = jEnd - jStart; // handle one block, row by row final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = iStart; i < iEnd; ++i) { System.arraycopy(subMatrix[i - row], jStart - column, block, (i - firstRow) * jWidth + (jStart - firstColumn), jLength); } } } } /** {@inheritDoc} */ @Override public BlockRealMatrix getRowMatrix(final int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final BlockRealMatrix out = new BlockRealMatrix(1, columns); // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outBlockIndex = 0; int outIndex = 0; double[] outBlock = out.blocks[outBlockIndex]; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; final int available = outBlock.length - outIndex; if (jWidth > available) { System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available); outBlock = out.blocks[++outBlockIndex]; System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available); outIndex = jWidth - available; } else { System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth); outIndex += jWidth; } } return out; } /** {@inheritDoc} */ @Override public void setRowMatrix(final int row, final RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { try { setRowMatrix(row, (BlockRealMatrix) matrix); } catch (ClassCastException cce) { super.setRowMatrix(row, matrix); } } /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param matrix row matrix (must have one row and the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance row */ public void setRowMatrix(final int row, final BlockRealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); if ((matrix.getRowDimension() != 1) || (matrix.getColumnDimension() != nCols)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); } // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int mBlockIndex = 0; int mIndex = 0; double[] mBlock = matrix.blocks[mBlockIndex]; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; final int available = mBlock.length - mIndex; if (jWidth > available) { System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available); mBlock = matrix.blocks[++mBlockIndex]; System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available); mIndex = jWidth - available; } else { System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth); mIndex += jWidth; } } } /** {@inheritDoc} */ @Override public BlockRealMatrix getColumnMatrix(final int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final BlockRealMatrix out = new BlockRealMatrix(rows, 1); // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outBlockIndex = 0; int outIndex = 0; double[] outBlock = out.blocks[outBlockIndex]; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { if (outIndex >= outBlock.length) { outBlock = out.blocks[++outBlockIndex]; outIndex = 0; } outBlock[outIndex++] = block[i * jWidth + jColumn]; } } return out; } /** {@inheritDoc} */ @Override public void setColumnMatrix(final int column, final RealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { try { setColumnMatrix(column, (BlockRealMatrix) matrix); } catch (ClassCastException cce) { super.setColumnMatrix(column, matrix); } } /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param matrix column matrix (must have one column and the same number of rows * as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance column */ void setColumnMatrix(final int column, final BlockRealMatrix matrix) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); if ((matrix.getRowDimension() != nRows) || (matrix.getColumnDimension() != 1)) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); } // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int mBlockIndex = 0; int mIndex = 0; double[] mBlock = matrix.blocks[mBlockIndex]; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { if (mIndex >= mBlock.length) { mBlock = matrix.blocks[++mBlockIndex]; mIndex = 0; } block[i * jWidth + jColumn] = mBlock[mIndex++]; } } } /** {@inheritDoc} */ @Override public RealVector getRowVector(final int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final double[] outData = new double[columns]; // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth); outIndex += jWidth; } return new ArrayRealVector(outData, false); } /** {@inheritDoc} */ @Override public void setRowVector(final int row, final RealVector vector) throws MatrixIndexException, InvalidMatrixException { try { setRow(row, ((ArrayRealVector) vector).getDataRef()); } catch (ClassCastException cce) { super.setRowVector(row, vector); } } /** {@inheritDoc} */ @Override public RealVector getColumnVector(final int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final double[] outData = new double[rows]; // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { outData[outIndex++] = block[i * jWidth + jColumn]; } } return new ArrayRealVector(outData, false); } /** {@inheritDoc} */ @Override public void setColumnVector(final int column, final RealVector vector) throws MatrixIndexException, InvalidMatrixException { try { setColumn(column, ((ArrayRealVector) vector).getDataRef()); } catch (ClassCastException cce) { super.setColumnVector(column, vector); } } /** {@inheritDoc} */ @Override public double[] getRow(final int row) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); final double[] out = new double[columns]; // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth); outIndex += jWidth; } return out; } /** {@inheritDoc} */ @Override public void setRow(final int row, final double[] array) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkRowIndex(this, row); final int nCols = getColumnDimension(); if (array.length != nCols) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, array.length, 1, nCols); } // perform copy block-wise, to ensure good cache behavior final int iBlock = row / BLOCK_SIZE; final int iRow = row - iBlock * BLOCK_SIZE; int outIndex = 0; for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth); outIndex += jWidth; } } /** {@inheritDoc} */ @Override public double[] getColumn(final int column) throws MatrixIndexException { MatrixUtils.checkColumnIndex(this, column); final double[] out = new double[rows]; // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { out[outIndex++] = block[i * jWidth + jColumn]; } } return out; } /** {@inheritDoc} */ @Override public void setColumn(final int column, final double[] array) throws MatrixIndexException, InvalidMatrixException { MatrixUtils.checkColumnIndex(this, column); final int nRows = getRowDimension(); if (array.length != nRows) { throw new InvalidMatrixException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, array.length, 1, nRows, 1); } // perform copy block-wise, to ensure good cache behavior final int jBlock = column / BLOCK_SIZE; final int jColumn = column - jBlock * BLOCK_SIZE; final int jWidth = blockWidth(jBlock); int outIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int iHeight = blockHeight(iBlock); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int i = 0; i < iHeight; ++i) { block[i * jWidth + jColumn] = array[outIndex++]; } } } /** {@inheritDoc} */ @Override public double getEntry(final int row, final int column) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); return blocks[iBlock * blockColumns + jBlock][k]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void setEntry(final int row, final int column, final double value) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); blocks[iBlock * blockColumns + jBlock][k] = value; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void addToEntry(final int row, final int column, final double increment) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); blocks[iBlock * blockColumns + jBlock][k] += increment; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public void multiplyEntry(final int row, final int column, final double factor) throws MatrixIndexException { try { final int iBlock = row / BLOCK_SIZE; final int jBlock = column / BLOCK_SIZE; final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + (column - jBlock * BLOCK_SIZE); blocks[iBlock * blockColumns + jBlock][k] *= factor; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixIndexException( LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension()); } } /** {@inheritDoc} */ @Override public BlockRealMatrix transpose() { final int nRows = getRowDimension(); final int nCols = getColumnDimension(); final BlockRealMatrix out = new BlockRealMatrix(nCols, nRows); // perform transpose block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < blockColumns; ++iBlock) { for (int jBlock = 0; jBlock < blockRows; ++jBlock) { // transpose current block final double[] outBlock = out.blocks[blockIndex]; final double[] tBlock = blocks[jBlock * blockColumns + iBlock]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, columns); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, rows); int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lInc = pEnd - pStart; int l = p - pStart; for (int q = qStart; q < qEnd; ++q) { outBlock[k] = tBlock[l]; ++k; l+= lInc; } } // go to next block ++blockIndex; } } return out; } /** {@inheritDoc} */ @Override public int getRowDimension() { return rows; } /** {@inheritDoc} */ @Override public int getColumnDimension() { return columns; } /** {@inheritDoc} */ @Override public double[] operate(final double[] v) throws IllegalArgumentException { if (v.length != columns) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, columns); } final double[] out = new double[rows]; // perform multiplication block-wise, to ensure good cache behavior for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final double[] block = blocks[iBlock * blockColumns + jBlock]; final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); int k = 0; for (int p = pStart; p < pEnd; ++p) { double sum = 0; int q = qStart; while (q < qEnd - 3) { sum += block[k] * v[q] + block[k + 1] * v[q + 1] + block[k + 2] * v[q + 2] + block[k + 3] * v[q + 3]; k += 4; q += 4; } while (q < qEnd) { sum += block[k++] * v[q++]; } out[p] += sum; } } } return out; } /** {@inheritDoc} */ @Override public double[] preMultiply(final double[] v) throws IllegalArgumentException { if (v.length != rows) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, rows); } final double[] out = new double[columns]; // perform multiplication block-wise, to ensure good cache behavior for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int jWidth2 = jWidth + jWidth; final int jWidth3 = jWidth2 + jWidth; final int jWidth4 = jWidth3 + jWidth; final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final double[] block = blocks[iBlock * blockColumns + jBlock]; final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int q = qStart; q < qEnd; ++q) { int k = q - qStart; double sum = 0; int p = pStart; while (p < pEnd - 3) { sum += block[k] * v[p] + block[k + jWidth] * v[p + 1] + block[k + jWidth2] * v[p + 2] + block[k + jWidth3] * v[p + 3]; k += jWidth4; p += 4; } while (p < pEnd) { sum += block[k] * v[p++]; k += jWidth; } out[q] += sum; } } } return out; } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final double[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - pStart) * jWidth; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int jWidth = blockWidth(jBlock); final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final double[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - pStart) * jWidth; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final double[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int p = pStart; p < pEnd; ++p) { for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final double[] block = blocks[iBlock * blockColumns + jBlock]; int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final double[] block = blocks[blockIndex]; int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } ++blockIndex; } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor) throws MatrixVisitorException { visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); int blockIndex = 0; for (int iBlock = 0; iBlock < blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, columns); final double[] block = blocks[blockIndex]; int k = 0; for (int p = pStart; p < pEnd; ++p) { for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } ++blockIndex; } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int p = pStart; p < pEnd; ++p) { int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { block[k] = visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** {@inheritDoc} */ @Override public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor, final int startRow, final int endRow, final int startColumn, final int endColumn) throws MatrixIndexException, MatrixVisitorException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { final int p0 = iBlock * BLOCK_SIZE; final int pStart = FastMath.max(startRow, p0); final int pEnd = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { final int jWidth = blockWidth(jBlock); final int q0 = jBlock * BLOCK_SIZE; final int qStart = FastMath.max(startColumn, q0); final int qEnd = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); final double[] block = blocks[iBlock * blockColumns + jBlock]; for (int p = pStart; p < pEnd; ++p) { int k = (p - p0) * jWidth + qStart - q0; for (int q = qStart; q < qEnd; ++q) { visitor.visit(p, q, block[k]); ++k; } } } } return visitor.end(); } /** * Get the height of a block. * @param blockRow row index (in block sense) of the block * @return height (number of rows) of the block */ private int blockHeight(final int blockRow) { return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE; } /** * Get the width of a block. * @param blockColumn column index (in block sense) of the block * @return width (number of columns) of the block */ private int blockWidth(final int blockColumn) { return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE; } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor100644 1750 1750 3275 11532241245 32552 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.linear.MatrixVisitorException; /** * Default implementation of the {@link RealMatrixPreservingVisitor} interface. *

                    * This class is a convenience to create custom visitors without defining all * methods. This class provides default implementations that do nothing. *

                    * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class DefaultRealMatrixPreservingVisitor implements RealMatrixPreservingVisitor { /** {@inheritDoc} */ public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { } /** {@inheritDoc} */ public void visit(int row, int column, double value) throws MatrixVisitorException { } /** {@inheritDoc} */ public double end() { return 0; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java100644 1750 1750 40307 11532241245 30406 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Calculates the QR-decomposition of a matrix. *

                    The QR-decomposition of a matrix A consists of two matrices Q and R * that satisfy: A = QR, Q is orthogonal (QTQ = I), and R is * upper triangular. If A is m×n, Q is m×m and R m×n.

                    *

                    This class compute the decomposition using Householder reflectors.

                    *

                    For efficiency purposes, the decomposition in packed form is transposed. * This allows inner loop to iterate inside rows, which is much more cache-efficient * in Java.

                    * * @see MathWorld * @see Wikipedia * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class QRDecompositionImpl implements QRDecomposition { /** * A packed TRANSPOSED representation of the QR decomposition. *

                    The elements BELOW the diagonal are the elements of the UPPER triangular * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors * from which an explicit form of Q can be recomputed if desired.

                    */ private double[][] qrt; /** The diagonal elements of R. */ private double[] rDiag; /** Cached value of Q. */ private RealMatrix cachedQ; /** Cached value of QT. */ private RealMatrix cachedQT; /** Cached value of R. */ private RealMatrix cachedR; /** Cached value of H. */ private RealMatrix cachedH; /** * Calculates the QR-decomposition of the given matrix. * @param matrix The matrix to decompose. */ public QRDecompositionImpl(RealMatrix matrix) { final int m = matrix.getRowDimension(); final int n = matrix.getColumnDimension(); qrt = matrix.transpose().getData(); rDiag = new double[FastMath.min(m, n)]; cachedQ = null; cachedQT = null; cachedR = null; cachedH = null; /* * The QR decomposition of a matrix A is calculated using Householder * reflectors by repeating the following operations to each minor * A(minor,minor) of A: */ for (int minor = 0; minor < FastMath.min(m, n); minor++) { final double[] qrtMinor = qrt[minor]; /* * Let x be the first column of the minor, and a^2 = |x|^2. * x will be in the positions qr[minor][minor] through qr[m][minor]. * The first column of the transformed minor will be (a,0,0,..)' * The sign of a is chosen to be opposite to the sign of the first * component of x. Let's find a: */ double xNormSqr = 0; for (int row = minor; row < m; row++) { final double c = qrtMinor[row]; xNormSqr += c * c; } final double a = (qrtMinor[minor] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr); rDiag[minor] = a; if (a != 0.0) { /* * Calculate the normalized reflection vector v and transform * the first column. We know the norm of v beforehand: v = x-ae * so |v|^2 = = -2a+a^2 = * a^2+a^2-2a = 2a*(a - ). * Here is now qr[minor][minor]. * v = x-ae is stored in the column at qr: */ qrtMinor[minor] -= a; // now |v|^2 = -2a*(qr[minor][minor]) /* * Transform the rest of the columns of the minor: * They will be transformed by the matrix H = I-2vv'/|v|^2. * If x is a column vector of the minor, then * Hx = (I-2vv'/|v|^2)x = x-2vv'x/|v|^2 = x - 2/|v|^2 v. * Therefore the transformation is easily calculated by * subtracting the column vector (2/|v|^2)v from x. * * Let 2/|v|^2 = alpha. From above we have * |v|^2 = -2a*(qr[minor][minor]), so * alpha = -/(a*qr[minor][minor]) */ for (int col = minor+1; col < n; col++) { final double[] qrtCol = qrt[col]; double alpha = 0; for (int row = minor; row < m; row++) { alpha -= qrtCol[row] * qrtMinor[row]; } alpha /= a * qrtMinor[minor]; // Subtract the column vector alpha*v from x. for (int row = minor; row < m; row++) { qrtCol[row] -= alpha * qrtMinor[row]; } } } } } /** {@inheritDoc} */ public RealMatrix getR() { if (cachedR == null) { // R is supposed to be m x n final int n = qrt.length; final int m = qrt[0].length; cachedR = MatrixUtils.createRealMatrix(m, n); // copy the diagonal from rDiag and the upper triangle of qr for (int row = FastMath.min(m, n) - 1; row >= 0; row--) { cachedR.setEntry(row, row, rDiag[row]); for (int col = row + 1; col < n; col++) { cachedR.setEntry(row, col, qrt[col][row]); } } } // return the cached matrix return cachedR; } /** {@inheritDoc} */ public RealMatrix getQ() { if (cachedQ == null) { cachedQ = getQT().transpose(); } return cachedQ; } /** {@inheritDoc} */ public RealMatrix getQT() { if (cachedQT == null) { // QT is supposed to be m x m final int n = qrt.length; final int m = qrt[0].length; cachedQT = MatrixUtils.createRealMatrix(m, m); /* * Q = Q1 Q2 ... Q_m, so Q is formed by first constructing Q_m and then * applying the Householder transformations Q_(m-1),Q_(m-2),...,Q1 in * succession to the result */ for (int minor = m - 1; minor >= FastMath.min(m, n); minor--) { cachedQT.setEntry(minor, minor, 1.0); } for (int minor = FastMath.min(m, n)-1; minor >= 0; minor--){ final double[] qrtMinor = qrt[minor]; cachedQT.setEntry(minor, minor, 1.0); if (qrtMinor[minor] != 0.0) { for (int col = minor; col < m; col++) { double alpha = 0; for (int row = minor; row < m; row++) { alpha -= cachedQT.getEntry(col, row) * qrtMinor[row]; } alpha /= rDiag[minor] * qrtMinor[minor]; for (int row = minor; row < m; row++) { cachedQT.addToEntry(col, row, -alpha * qrtMinor[row]); } } } } } // return the cached matrix return cachedQT; } /** {@inheritDoc} */ public RealMatrix getH() { if (cachedH == null) { final int n = qrt.length; final int m = qrt[0].length; cachedH = MatrixUtils.createRealMatrix(m, n); for (int i = 0; i < m; ++i) { for (int j = 0; j < FastMath.min(i + 1, n); ++j) { cachedH.setEntry(i, j, qrt[j][i] / -rDiag[j]); } } } // return the cached matrix return cachedH; } /** {@inheritDoc} */ public DecompositionSolver getSolver() { return new Solver(qrt, rDiag); } /** Specialized solver. */ private static class Solver implements DecompositionSolver { /** * A packed TRANSPOSED representation of the QR decomposition. *

                    The elements BELOW the diagonal are the elements of the UPPER triangular * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors * from which an explicit form of Q can be recomputed if desired.

                    */ private final double[][] qrt; /** The diagonal elements of R. */ private final double[] rDiag; /** * Build a solver from decomposed matrix. * @param qrt packed TRANSPOSED representation of the QR decomposition * @param rDiag diagonal elements of R */ private Solver(final double[][] qrt, final double[] rDiag) { this.qrt = qrt; this.rDiag = rDiag; } /** {@inheritDoc} */ public boolean isNonSingular() { for (double diag : rDiag) { if (diag == 0) { return false; } } return true; } /** {@inheritDoc} */ public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { final int n = qrt.length; final int m = qrt[0].length; if (b.length != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m); } if (!isNonSingular()) { throw new SingularMatrixException(); } final double[] x = new double[n]; final double[] y = b.clone(); // apply Householder transforms to solve Q.y = b for (int minor = 0; minor < FastMath.min(m, n); minor++) { final double[] qrtMinor = qrt[minor]; double dotProduct = 0; for (int row = minor; row < m; row++) { dotProduct += y[row] * qrtMinor[row]; } dotProduct /= rDiag[minor] * qrtMinor[minor]; for (int row = minor; row < m; row++) { y[row] += dotProduct * qrtMinor[row]; } } // solve triangular system R.x = y for (int row = rDiag.length - 1; row >= 0; --row) { y[row] /= rDiag[row]; final double yRow = y[row]; final double[] qrtRow = qrt[row]; x[row] = yRow; for (int i = 0; i < row; i++) { y[i] -= yRow * qrtRow[i]; } } return x; } /** {@inheritDoc} */ public RealVector solve(RealVector b) throws IllegalArgumentException, InvalidMatrixException { try { return solve((ArrayRealVector) b); } catch (ClassCastException cce) { return new ArrayRealVector(solve(b.getData()), false); } } /** Solve the linear equation A × X = B. *

                    The A matrix is implicit here. It is

                    * @param b right-hand side of the equation A × X = B * @return a vector X that minimizes the two norm of A × X - B * @throws IllegalArgumentException if matrices dimensions don't match * @throws InvalidMatrixException if decomposed matrix is singular */ public ArrayRealVector solve(ArrayRealVector b) throws IllegalArgumentException, InvalidMatrixException { return new ArrayRealVector(solve(b.getDataRef()), false); } /** {@inheritDoc} */ public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException { final int n = qrt.length; final int m = qrt[0].length; if (b.getRowDimension() != m) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_2x2, b.getRowDimension(), b.getColumnDimension(), m, "n"); } if (!isNonSingular()) { throw new SingularMatrixException(); } final int columns = b.getColumnDimension(); final int blockSize = BlockRealMatrix.BLOCK_SIZE; final int cBlocks = (columns + blockSize - 1) / blockSize; final double[][] xBlocks = BlockRealMatrix.createBlocksLayout(n, columns); final double[][] y = new double[b.getRowDimension()][blockSize]; final double[] alpha = new double[blockSize]; for (int kBlock = 0; kBlock < cBlocks; ++kBlock) { final int kStart = kBlock * blockSize; final int kEnd = FastMath.min(kStart + blockSize, columns); final int kWidth = kEnd - kStart; // get the right hand side vector b.copySubMatrix(0, m - 1, kStart, kEnd - 1, y); // apply Householder transforms to solve Q.y = b for (int minor = 0; minor < FastMath.min(m, n); minor++) { final double[] qrtMinor = qrt[minor]; final double factor = 1.0 / (rDiag[minor] * qrtMinor[minor]); Arrays.fill(alpha, 0, kWidth, 0.0); for (int row = minor; row < m; ++row) { final double d = qrtMinor[row]; final double[] yRow = y[row]; for (int k = 0; k < kWidth; ++k) { alpha[k] += d * yRow[k]; } } for (int k = 0; k < kWidth; ++k) { alpha[k] *= factor; } for (int row = minor; row < m; ++row) { final double d = qrtMinor[row]; final double[] yRow = y[row]; for (int k = 0; k < kWidth; ++k) { yRow[k] += alpha[k] * d; } } } // solve triangular system R.x = y for (int j = rDiag.length - 1; j >= 0; --j) { final int jBlock = j / blockSize; final int jStart = jBlock * blockSize; final double factor = 1.0 / rDiag[j]; final double[] yJ = y[j]; final double[] xBlock = xBlocks[jBlock * cBlocks + kBlock]; int index = (j - jStart) * kWidth; for (int k = 0; k < kWidth; ++k) { yJ[k] *= factor; xBlock[index++] = yJ[k]; } final double[] qrtJ = qrt[j]; for (int i = 0; i < j; ++i) { final double rIJ = qrtJ[i]; final double[] yI = y[i]; for (int k = 0; k < kWidth; ++k) { yI[k] -= yJ[k] * rIJ; } } } } return new BlockRealMatrix(n, columns, xBlocks, false); } /** {@inheritDoc} */ public RealMatrix getInverse() throws InvalidMatrixException { return solve(MatrixUtils.createRealIdentityMatrix(rDiag.length)); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/linear/FieldMatrix.java100644 1750 1750 107345 11532241245 26743 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.linear; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.linear.MatrixVisitorException; /** * Interface defining field-valued matrix with basic algebraic operations. *

                    * Matrix element indexing is 0-based -- e.g., getEntry(0, 0) * returns the element in the first row, first column of the matrix.

                    * * @param the type of the field elements * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public interface FieldMatrix> extends AnyMatrix { /** * Get the type of field elements of the matrix. * @return type of field elements of the matrix */ Field getField(); /** * Create a new FieldMatrix of the same type as the instance with the supplied * row and column dimensions. * * @param rowDimension the number of rows in the new matrix * @param columnDimension the number of columns in the new matrix * @return a new matrix of the same type as the instance * @throws IllegalArgumentException if row or column dimension is not positive * @since 2.0 */ FieldMatrix createMatrix(final int rowDimension, final int columnDimension); /** * Returns a (deep) copy of this. * * @return matrix copy */ FieldMatrix copy(); /** * Compute the sum of this and m. * * @param m matrix to be added * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ FieldMatrix add(FieldMatrix m) throws IllegalArgumentException; /** * Compute this minus m. * * @param m matrix to be subtracted * @return this + m * @throws IllegalArgumentException if m is not the same size as this */ FieldMatrix subtract(FieldMatrix m) throws IllegalArgumentException; /** * Returns the result of adding d to each entry of this. * * @param d value to be added to each entry * @return d + this */ FieldMatrix scalarAdd(T d); /** * Returns the result multiplying each entry of this by d. * * @param d value to multiply all entries by * @return d * this */ FieldMatrix scalarMultiply(T d); /** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ FieldMatrix multiply(FieldMatrix m) throws IllegalArgumentException; /** * Returns the result premultiplying this by m. * @param m matrix to premultiply by * @return m * this * @throws IllegalArgumentException * if rowDimension(this) != columnDimension(m) */ FieldMatrix preMultiply(FieldMatrix m) throws IllegalArgumentException; /** * Returns matrix entries as a two-dimensional array. * * @return 2-dimensional array of entries */ T[][] getData(); /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @return The subMatrix containing the data of the * specified rows and columns * @exception MatrixIndexException if the indices are not valid */ FieldMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException; /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @return The subMatrix containing the data in the * specified rows and columns * @exception MatrixIndexException if row or column selections are not valid */ FieldMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException; /** * Copy a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @param destination The arrays where the submatrix data should be copied * (if larger than rows/columns counts, only the upper-left part will be used) * @exception MatrixIndexException if the indices are not valid * @exception IllegalArgumentException if the destination array is too small */ void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn, T[][] destination) throws MatrixIndexException, IllegalArgumentException; /** * Copy a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices. * @param selectedColumns Array of column indices. * @param destination The arrays where the submatrix data should be copied * (if larger than rows/columns counts, only the upper-left part will be used) * @exception MatrixIndexException if the indices are not valid * @exception IllegalArgumentException if the destination array is too small */ void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination) throws MatrixIndexException, IllegalArgumentException; /** * Replace the submatrix starting at row, column using data in * the input subMatrix array. Indexes are 0-based. *

                    * Example:
                    * Starting with

                        * 1  2  3  4
                        * 5  6  7  8
                        * 9  0  1  2
                        * 
                    * and subMatrix = {{3, 4} {5,6}}, invoking * setSubMatrix(subMatrix,1,1)) will result in
                        * 1  2  3  4
                        * 5  3  4  8
                        * 9  5  6  2
                        * 

                    * * @param subMatrix array containing the submatrix replacement data * @param row row coordinate of the top, left element to be replaced * @param column column coordinate of the top, left element to be replaced * @throws MatrixIndexException if subMatrix does not fit into this * matrix from element in (row, column) * @throws IllegalArgumentException if subMatrix is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if subMatrix is null * @since 2.0 */ void setSubMatrix(T[][] subMatrix, int row, int column) throws MatrixIndexException; /** * Returns the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be fetched * @return row matrix * @throws MatrixIndexException if the specified row index is invalid */ FieldMatrix getRowMatrix(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param matrix row matrix (must have one row and the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance row */ void setRowMatrix(int row, FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be fetched * @return column matrix * @throws MatrixIndexException if the specified column index is invalid */ FieldMatrix getColumnMatrix(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param matrix column matrix (must have one column and the same number of rows * as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the matrix dimensions do not match one * instance column */ void setColumnMatrix(int column, FieldMatrix matrix) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in row number row * as a vector. Row indices start at 0. * * @param row the row to be fetched * @return row vector * @throws MatrixIndexException if the specified row index is invalid */ FieldVector getRowVector(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a vector. Row indices start at 0. * * @param row the row to be set * @param vector row vector (must have the same number of columns * as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the vector dimension does not match one * instance row */ void setRowVector(int row, FieldVector vector) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number column * as a vector. Column indices start at 0. * * @param column the column to be fetched * @return column vector * @throws MatrixIndexException if the specified column index is invalid */ FieldVector getColumnVector(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a vector. Column indices start at 0. * * @param column the column to be set * @param vector column vector (must have the same number of rows as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the vector dimension does not match one * instance column */ void setColumnVector(int column, FieldVector vector) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in row number row as an array. *

                    * Row indices start at 0. A MatrixIndexException is thrown * unless 0 <= row < rowDimension.

                    * * @param row the row to be fetched * @return array of entries in the row * @throws MatrixIndexException if the specified row index is not valid */ T[] getRow(int row) throws MatrixIndexException; /** * Sets the entries in row number row * as a row matrix. Row indices start at 0. * * @param row the row to be set * @param array row matrix (must have the same number of columns as the instance) * @throws MatrixIndexException if the specified row index is invalid * @throws InvalidMatrixException if the array size does not match one * instance row */ void setRow(int row, T[] array) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entries in column number col as an array. *

                    * Column indices start at 0. A MatrixIndexException is thrown * unless 0 <= column < columnDimension.

                    * * @param column the column to be fetched * @return array of entries in the column * @throws MatrixIndexException if the specified column index is not valid */ T[] getColumn(int column) throws MatrixIndexException; /** * Sets the entries in column number column * as a column matrix. Column indices start at 0. * * @param column the column to be set * @param array column array (must have the same number of rows as the instance) * @throws MatrixIndexException if the specified column index is invalid * @throws InvalidMatrixException if the array size does not match one * instance column */ void setColumn(int column, T[] array) throws MatrixIndexException, InvalidMatrixException; /** * Returns the entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be fetched * @param column column location of entry to be fetched * @return matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid */ T getEntry(int row, int column) throws MatrixIndexException; /** * Set the entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param value matrix entry to be set in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void setEntry(int row, int column, T value) throws MatrixIndexException; /** * Change an entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param increment value to add to the current matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void addToEntry(int row, int column, T increment) throws MatrixIndexException; /** * Change an entry in the specified row and column. *

                    * Row and column indices start at 0 and must satisfy *

                      *
                    • 0 <= row < rowDimension
                    • *
                    • 0 <= column < columnDimension
                    • *
                    * otherwise a MatrixIndexException is thrown.

                    * * @param row row location of entry to be set * @param column column location of entry to be set * @param factor multiplication factor for the current matrix entry in row,column * @throws MatrixIndexException if the row or column index is not valid * @since 2.0 */ void multiplyEntry(int row, int column, T factor) throws MatrixIndexException; /** * Returns the transpose of this matrix. * * @return transpose matrix */ FieldMatrix transpose(); /** * Returns the * trace of the matrix (the sum of the elements on the main diagonal). * * @return trace * @throws NonSquareMatrixException if the matrix is not square */ T getTrace() throws NonSquareMatrixException; /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ T[] operate(T[] v) throws IllegalArgumentException; /** * Returns the result of multiplying this by the vector v. * * @param v the vector to operate on * @return this*v * @throws IllegalArgumentException if columnDimension != v.size() */ FieldVector operate(FieldVector v) throws IllegalArgumentException; /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ T[] preMultiply(T[] v) throws IllegalArgumentException; /** * Returns the (row) vector result of premultiplying this by the vector v. * * @param v the row vector to premultiply by * @return v*this * @throws IllegalArgumentException if rowDimension != v.size() */ FieldVector preMultiply(FieldVector v) throws IllegalArgumentException; /** * Visit (and possibly change) all matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInRowOrder(FieldMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInRowOrder(FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInRowOrder(FieldMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries in row order. *

                    Row order starts at upper left and iterating through all elements * of a row from left to right before going to the leftmost element * of the next row.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInRowOrder(FieldMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (and possibly change) all matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInColumnOrder(FieldMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInColumnOrder(FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInColumnOrder(FieldMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries in column order. *

                    Column order starts at upper left and iterating through all elements * of a column from top to bottom before going to the topmost element * of the next column.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInColumnOrder(FieldMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (and possibly change) all matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInOptimizedOrder(FieldMatrixChangingVisitor visitor) throws MatrixVisitorException; /** * Visit (but don't change) all matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @exception MatrixVisitorException if the visitor cannot process an entry * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInOptimizedOrder(FieldMatrixPreservingVisitor visitor) throws MatrixVisitorException; /** * Visit (and possibly change) some matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end * of the walk */ T walkInOptimizedOrder(FieldMatrixChangingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; /** * Visit (but don't change) some matrix entries using the fastest possible order. *

                    The fastest walking order depends on the exact matrix class. It may be * different from traditional row or column orders.

                    * @param visitor visitor used to process all matrix entries * @param startRow Initial row index * @param endRow Final row index (inclusive) * @param startColumn Initial column index * @param endColumn Final column index (inclusive) * @exception MatrixVisitorException if the visitor cannot process an entry * @exception MatrixIndexException if the indices are not valid * @see #walkInRowOrder(FieldMatrixChangingVisitor) * @see #walkInRowOrder(FieldMatrixPreservingVisitor) * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixChangingVisitor) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end * of the walk */ T walkInOptimizedOrder(FieldMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException, MatrixVisitorException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/RandomKey.java100644 1750 1750 25047 11532241244 26730 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; /** *

                    * Random Key chromosome is used for permutation representation. It is a vector * of a fixed length of real numbers in [0,1] interval. The index of the i-th * smallest value in the vector represents an i-th member of the permutation. *

                    * *

                    * For example, the random key [0.2, 0.3, 0.8, 0.1] corresponds to the * permutation of indices (3,0,1,2). If the original (unpermuted) sequence would * be (a,b,c,d), this would mean the sequence (d,a,b,c). *

                    * *

                    * With this representation, common operators like n-point crossover can be * used, because any such chromosome represents a valid permutation. *

                    * *

                    * Since the chromosome (and thus its arrayRepresentation) is immutable, the * array representation is sorted only once in the constructor. *

                    * *

                    * For details, see: *

                      *
                    • Bean, J.C.: Genetic algorithms and random keys for sequencing and * optimization. ORSA Journal on Computing 6 (1994) 154–160
                    • *
                    • Rothlauf, F.: Representations for Genetic and Evolutionary Algorithms. * Volume 104 of Studies in Fuzziness and Soft Computing. Physica-Verlag, * Heidelberg (2002)
                    • *
                    *

                    * * @param * type of the permuted objects * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class RandomKey extends AbstractListChromosome implements PermutationChromosome { /** * Cache of sorted representation (unmodifiable). */ private final List sortedRepresentation; /** * Base sequence [0,1,...,n-1], permuted accorting to the representation (unmodifiable). */ private final List baseSeqPermutation; /** * Constructor. * * @param representation list of [0,1] values representing the permutation */ public RandomKey(List representation) { super(representation); // store the sorted representation List sortedRepr = new ArrayList (getRepresentation()); Collections.sort(sortedRepr); sortedRepresentation = Collections.unmodifiableList(sortedRepr); // store the permutation of [0,1,...,n-1] list for toString() and isSame() methods baseSeqPermutation = Collections.unmodifiableList( decodeGeneric(baseSequence(getLength()), getRepresentation(), sortedRepresentation) ); } /** * Constructor. * * @param representation array of [0,1] values representing the permutation */ public RandomKey(Double[] representation) { this(Arrays.asList(representation)); } /** * {@inheritDoc} */ public List decode(List sequence) { return decodeGeneric(sequence, getRepresentation(), sortedRepresentation); } /** * Decodes a permutation represented by representation and * returns a (generic) list with the permuted values. * * @param generic type of the sequence values * @param sequence the unpermuted sequence * @param representation representation of the permutation ([0,1] vector) * @param sortedRepr sorted representation * @return list with the sequence values permuted according to the representation */ private static List decodeGeneric(List sequence, List representation, List sortedRepr) { int l = sequence.size(); if (representation.size() != l) { throw new IllegalArgumentException(String.format("Length of sequence for decoding (%s) has to be equal to the length of the RandomKey (%s)", l, representation.size())); } if (representation.size() != sortedRepr.size()) { throw new IllegalArgumentException(String.format("Representation and sortedRepr must have same sizes, %d != %d", representation.size(), sortedRepr.size())); } List reprCopy = new ArrayList (representation);// do not modify the orig. representation // now find the indices in the original repr and use them for permuting List res = new ArrayList (l); for (int i=0; itrue
                    iff another is a RandomKey and * encodes the same permutation. * * @param another chromosome to compare * @return true iff chromosomes encode the same permutation */ @Override protected boolean isSame(Chromosome another) { // type check if (! (another instanceof RandomKey)) return false; RandomKey anotherRk = (RandomKey) another; // size check if (getLength() != anotherRk.getLength()) return false; // two different representations can still encode the same permutation // the ordering is what counts List thisPerm = this.baseSeqPermutation; List anotherPerm = anotherRk.baseSeqPermutation; for (int i=0; i chromosomeRepresentation) throws InvalidRepresentationException { for (double val : chromosomeRepresentation) { if (val < 0 || val > 1) { throw new InvalidRepresentationException("Values of representation must be in [0,1] interval"); } } } /** * Generates a representation corresponding to a random permutation of * length l which can be passed to the RandomKey constructor. * * @param l * length of the permutation * @return representation of a random permutation */ public static final List randomPermutation(int l) { List repr = new ArrayList(l); for (int i=0; i identityPermutation(int l) { List repr = new ArrayList(l); for (int i=0; idata
                    sorted by comparator. The * data is not modified during the process. * * This is useful if you want to inject some permutations to the initial * population. * * @param type of the data * @param data list of data determining the order * @param comparator how the data will be compared * @return list representation of the permutation corresponding to the parameters */ public static List comparatorPermutation(List data, Comparator comparator) { List sortedData = new ArrayList (data); Collections.sort(sortedData, comparator); return inducedPermutation(data, sortedData); } /** * Generates a representation of a permutation corresponding to a * permutation which yields permutedData when applied to * originalData. * * This method can be viewed as an inverse to {@link #decode(List)}. * * @param type of the data * @param originalData the original, unpermuted data * @param permutedData the data, somehow permuted * @return representation of a permutation corresponding to the permutation originalData -> permutedData * @throws IllegalArgumentException iff the permutedData and originalData contains different data */ public static List inducedPermutation(List originalData, List permutedData) throws IllegalArgumentException { if (originalData.size() != permutedData.size()) { throw new IllegalArgumentException("originalData and permutedData must have same length"); } int l = originalData.size(); List origDataCopy = new ArrayList (originalData); Double[] res = new Double[l]; for (int i=0; i baseSequence(int l) { List baseSequence = new ArrayList (l); for (int i=0; i 1) { throw new IllegalArgumentException("crossoverRate must be between 0 and 1"); } if (mutationRate < 0 || mutationRate > 1) { throw new IllegalArgumentException("mutationRate must be between 0 and 1"); } this.crossoverPolicy = crossoverPolicy; this.crossoverRate = crossoverRate; this.mutationPolicy = mutationPolicy; this.mutationRate = mutationRate; this.selectionPolicy = selectionPolicy; } /** * Set the (static) random generator. * * @param random random generator */ public static synchronized void setRandomGenerator(RandomGenerator random) { randomGenerator = random; } /** * Returns the (static) random generator. * * @return the static random generator shared by GA implementation classes */ public static synchronized RandomGenerator getRandomGenerator() { return randomGenerator; } /** * Evolve the given population. Evolution stops when the stopping condition * is satisfied. Updates the {@link #getGenerationsEvolved() generationsEvolved} * property with the number of generations evolved before the StoppingCondition * is satisfied. * * @param initial the initial, seed population. * @param condition the stopping condition used to stop evolution. * @return the population that satisfies the stopping condition. */ public Population evolve(Population initial, StoppingCondition condition) { Population current = initial; generationsEvolved = 0; while (!condition.isSatisfied(current)) { current = nextGeneration(current); generationsEvolved++; } return current; } /** *

                    Evolve the given population into the next generation.

                    *

                      *
                    1. Get nextGeneration population to fill from current * generation, using its nextGeneration method
                    2. *
                    3. Loop until new generation is filled:
                    4. *
                      • Apply configured SelectionPolicy to select a pair of parents * from current
                      • *
                      • With probability = {@link #getCrossoverRate()}, apply * configured {@link CrossoverPolicy} to parents
                      • *
                      • With probability = {@link #getMutationRate()}, apply * configured {@link MutationPolicy} to each of the offspring
                      • *
                      • Add offspring individually to nextGeneration, * space permitting
                      • *
                      *
                    5. Return nextGeneration
                    6. *
                    *

                    * * @param current the current population. * @return the population for the next generation. */ public Population nextGeneration(Population current) { Population nextGeneration = current.nextGeneration(); RandomGenerator randGen = getRandomGenerator(); while (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { // select parent chromosomes ChromosomePair pair = getSelectionPolicy().select(current); // crossover? if (randGen.nextDouble() < getCrossoverRate()) { // apply crossover policy to create two offspring pair = getCrossoverPolicy().crossover(pair.getFirst(), pair.getSecond()); } // mutation? if (randGen.nextDouble() < getMutationRate()) { // apply mutation policy to the chromosomes pair = new ChromosomePair( getMutationPolicy().mutate(pair.getFirst()), getMutationPolicy().mutate(pair.getSecond())); } // add the first chromosome to the population nextGeneration.addChromosome(pair.getFirst()); // is there still a place for the second chromosome? if (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { // add the second chromosome to the population nextGeneration.addChromosome(pair.getSecond()); } } return nextGeneration; } /** * Returns the crossover policy. * @return crossover policy */ public CrossoverPolicy getCrossoverPolicy() { return crossoverPolicy; } /** * Returns the crossover rate. * @return crossover rate */ public double getCrossoverRate() { return crossoverRate; } /** * Returns the mutation policy. * @return mutation policy */ public MutationPolicy getMutationPolicy() { return mutationPolicy; } /** * Returns the mutation rate. * @return mutation rate */ public double getMutationRate() { return mutationRate; } /** * Returns the selection policy. * @return selection policy */ public SelectionPolicy getSelectionPolicy() { return selectionPolicy; } /** * Returns the number of generations evolved to * reach {@link StoppingCondition} in the last run. * * @return number of generations evolved * @since 2.1 */ public int getGenerationsEvolved() { return generationsEvolved; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/ChromosomePair.java100644 1750 1750 3632 11532241244 27742 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * A pair of {@link Chromosome} objects. * @since 2.0 * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class ChromosomePair { /** the first chromosome in the pair. */ private final Chromosome first; /** the second chromosome in the pair. */ private final Chromosome second; /** * Create a chromosome pair. * * @param c1 the first chromosome. * @param c2 the second chromosome. */ public ChromosomePair(final Chromosome c1, final Chromosome c2) { super(); first = c1; second = c2; } /** * Access the first chromosome. * * @return the first chromosome. */ public Chromosome getFirst() { return first; } /** * Access the second chromosome. * * @return the second chromosome. */ public Chromosome getSecond() { return second; } /** * {@inheritDoc} */ @Override public String toString() { return String.format("(%s,%s)", getFirst(), getSecond()); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/InvalidRepresentationException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/InvalidRepresentationException.j100644 1750 1750 3567 11532241244 32522 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Exception indicating that the representation of a chromosome is not valid. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public class InvalidRepresentationException extends Exception { /** Serialization version id */ private static final long serialVersionUID = 1L; /** * Constructor */ public InvalidRepresentationException() { super(); } /** * Construct an InvalidRepresentationException * @param arg0 exception message */ public InvalidRepresentationException(String arg0) { super(arg0); } /** * Construct an InvalidRepresentationException * @param arg0 cause */ public InvalidRepresentationException(Throwable arg0) { super(arg0); } /** * Construct an InvalidRepresentationException * * @param arg0 exception message * @param arg1 cause */ public InvalidRepresentationException(String arg0, Throwable arg1) { super(arg0, arg1); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/ElitisticListPopulation.java100644 1750 1750 7734 11532241244 31662 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.Collections; import java.util.List; import org.apache.commons.math.util.FastMath; /** * Population of chromosomes which uses elitism (certain percentace of the best * chromosomes is directly copied to the next generation). * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class ElitisticListPopulation extends ListPopulation { /** percentage of chromosomes copied to the next generation */ private double elitismRate = 0.9; /** * Creates a new ElitisticListPopulation instance. * * @param chromosomes * list of chromosomes in the population * @param populationLimit * maximal size of the population * @param elitismRate * how many best chromosomes will be directly transferred to the * next generation [in %] */ public ElitisticListPopulation(List chromosomes, int populationLimit, double elitismRate) { super(chromosomes, populationLimit); this.elitismRate = elitismRate; } /** * Creates a new ListPopulation instance and initializes its inner * chromosome list. * * @param populationLimit maximal size of the population * @param elitismRate * how many best chromosomes will be directly transferred to the * next generation [in %] */ public ElitisticListPopulation(int populationLimit, double elitismRate) { super(populationLimit); this.elitismRate = elitismRate; } /** * Start the population for the next generation. The * {@link #elitismRate} percents of the best * chromosomes are directly copied to the next generation. * * @return the beginnings of the next generation. */ public Population nextGeneration() { // initialize a new generation with the same parameters ElitisticListPopulation nextGeneration = new ElitisticListPopulation(this.getPopulationLimit(), this.getElitismRate()); List oldChromosomes = this.getChromosomes(); Collections.sort(oldChromosomes); // index of the last "not good enough" chromosome int boundIndex = (int) FastMath.ceil((1.0 - this.getElitismRate()) * oldChromosomes.size()); for (int i=boundIndex; i 1) throw new IllegalArgumentException("Elitism rate has to be in [0,1]"); this.elitismRate = elitismRate; } /** * Access the elitism rate. * @return the elitism rate */ public double getElitismRate() { return this.elitismRate; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/TournamentSelection.java100644 1750 1750 10175 11532241244 31035 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.List; /** * Tournament selection scheme. Each of the two selected chromosomes is selected * based on n-ary tournament -- this is done by drawing {@link #arity} random * chromosomes without replacement from the population, and then selecting the * fittest chromosome among them. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class TournamentSelection implements SelectionPolicy { /** number of chromosomes included in the tournament selections */ private int arity; /** * Creates a new TournamentSelection instance. * * @param arity * how many chromosomes will be drawn to the tournament */ public TournamentSelection(int arity) { this.arity = arity; } /** * Select two chromosomes from the population. Each of the two selected * chromosomes is selected based on n-ary tournament -- this is done by * drawing {@link #arity} random chromosomes without replacement from the * population, and then selecting the fittest chromosome among them. * * @param population * the population from which the chromosomes are choosen. * @return the selected chromosomes. */ public ChromosomePair select(Population population) { return new ChromosomePair( tournament((ListPopulation) population), tournament((ListPopulation)population) ); } /** * Helper for {@link #select(Population)}. Draw {@link #arity} random * chromosomes without replacement from the population, and then select the * fittest chromosome among them. * * @param population * the population from which the chromosomes are choosen. * @return the selected chromosome. */ private Chromosome tournament(ListPopulation population) { if (population.getPopulationSize() < this.arity) throw new IllegalArgumentException("Tournament arity cannot be bigger than population size."); // auxiliary population ListPopulation tournamentPopulation = new ListPopulation(this.arity) { public Population nextGeneration() { // not useful here return null; } }; // create a copy of the chromosome list List chromosomes = new ArrayList (population.getChromosomes()); for (int i=0; i newRepr = new ArrayList(origChrom.getRepresentation()); // randomly select a gene int geneIndex = GeneticAlgorithm.getRandomGenerator().nextInt(origChrom.getLength()); // and change it newRepr.set(geneIndex, origChrom.getRepresentation().get(geneIndex) == 0 ? 1 : 0); Chromosome newChrom = origChrom.newFixedLengthChromosome(newRepr); return newChrom; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/OnePointCrossover.java100644 1750 1750 11660 11532241244 30474 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.List; /** * One point crossover policy. A random crossover point is selected and the * first part from each parent is copied to the corresponding child, and the * second parts are copied crosswise. * * Example: *
                     * -C- denotes a crossover point
                     *                   -C-                                -C-
                     * p1 = (1 0 1 0 0 1  | 0 1 1)    X    p2 = (0 1 1 0 1 0  | 1 1 1)
                     *         \------------/ \-----/              \------------/ \-----/
                     *            ||         (*)                       ||        (**)
                     *            VV         (**)                      VV        (*)
                     *      /------------\ /-----\              /------------\ /-----\
                     * c1 = (1 0 1 0 0 1  | 1 1 1)    X    p2 = (0 1 1 0 1 0  | 0 1 1)
                     * 
                    * * This policy works only on {@link AbstractListChromosome}, and therefore it * is parametrized by T. Moreover, the chromosomes must have same lengths. * * @param generic type of the {@link AbstractListChromosome}s for crossover * @since 2.0 * @version $Revision: 903046 $ $Date: 2010-01-26 03:07:26 +0100 (mar. 26 janv. 2010) $ * */ public class OnePointCrossover implements CrossoverPolicy { /** * Performs one point crossover. A random crossover point is selected and the * first part from each parent is copied to the corresponding child, and the * second parts are copied crosswise. * * Example: * -C- denotes a crossover point * -C- -C- * p1 = (1 0 1 0 0 1 | 0 1 1) X p2 = (0 1 1 0 1 0 | 1 1 1) * \------------/ \-----/ \------------/ \-----/ * || (*) || (**) * VV (**) VV (*) * /------------\ /-----\ /------------\ /-----\ * c1 = (1 0 1 0 0 1 | 1 1 1) X p2 = (0 1 1 0 1 0 | 0 1 1) * * @param first first parent (p1) * @param second second parent (p2) * @return pair of two children (c1,c2) */ @SuppressWarnings("unchecked") // OK because of instanceof checks public ChromosomePair crossover(Chromosome first, Chromosome second) { if (! (first instanceof AbstractListChromosome && second instanceof AbstractListChromosome)) { throw new IllegalArgumentException("One point crossover works on FixedLengthChromosomes only."); } return crossover((AbstractListChromosome) first, (AbstractListChromosome) second); } /** * Helper for {@link #crossover(Chromosome, Chromosome)}. Performs the actual crossover. * * @param first the first chromosome. * @param second the second chromosome. * @return the pair of new chromosomes that resulted from the crossover. */ private ChromosomePair crossover(AbstractListChromosome first, AbstractListChromosome second) { int length = first.getLength(); if (length != second.getLength()) throw new IllegalArgumentException("Both chromosomes must have same lengths."); // array representations of the parents List parent1Rep = first.getRepresentation(); List parent2Rep = second.getRepresentation(); // and of the children ArrayList child1Rep = new ArrayList (first.getLength()); ArrayList child2Rep = new ArrayList (second.getLength()); // select a crossover point at random (0 and length makes no sense) int crossoverIndex = 1 + (GeneticAlgorithm.getRandomGenerator().nextInt(length-2)); // copy the first part for (int i = 0; i < crossoverIndex; i++) { child1Rep.add(parent1Rep.get(i)); child2Rep.add(parent2Rep.get(i)); } // and switch the second part for (int i = crossoverIndex; i < length; i++) { child1Rep.add(parent2Rep.get(i)); child2Rep.add(parent1Rep.get(i)); } return new ChromosomePair( first.newFixedLengthChromosome(child1Rep), second.newFixedLengthChromosome(child2Rep) ); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/Population.java100644 1750 1750 3446 11532241244 27150 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * A collection of chromosomes that facilitates generational evolution. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface Population extends Iterable { /** * Access the current population size. * @return the current population size. */ int getPopulationSize(); /** * Access the maximum population size. * @return the maximum population size. */ int getPopulationLimit(); /** * Start the population for the next generation. * @return the beginnings of the next generation. */ Population nextGeneration(); /** * Add the given chromosome to the population. * @param chromosome the chromosome to add. */ void addChromosome(Chromosome chromosome); /** * Access the fittest chromosome in this population. * @return the fittest chromosome. */ Chromosome getFittestChromosome(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/RandomKeyMutation.java100644 1750 1750 4257 11532241244 30431 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Mutation operator for {@link RandomKey}s. Changes a randomly chosen element * of the array representation to a random value uniformly distributed in [0,1]. * * @since 2.0 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class RandomKeyMutation implements MutationPolicy { /** * {@inheritDoc} * * @throws IllegalArgumentException if original is not a * {@link RandomKey} instance */ public Chromosome mutate(Chromosome original) { if (!(original instanceof RandomKey)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.RANDOMKEY_MUTATION_WRONG_CLASS, original.getClass().getSimpleName()); } RandomKey originalRk = (RandomKey) original; List repr = originalRk.getRepresentation(); int rInd = GeneticAlgorithm.getRandomGenerator().nextInt(repr.size()); List newRepr = new ArrayList (repr); newRepr.set(rInd, GeneticAlgorithm.getRandomGenerator().nextDouble()); return originalRk.newFixedLengthChromosome(newRepr); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/FixedGenerationCount.java100644 1750 1750 4766 11532241244 31110 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Stops after a fixed number of generations. Each time * {@link #isSatisfied(Population)} is invoked, a generation counter is * incremented. Once the counter reaches the configured * maxGenerations value, {@link #isSatisfied(Population)} returns * true. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public class FixedGenerationCount implements StoppingCondition { /** Number of generations that have passed */ private int numGenerations = 0; /** Maximum number of generations (stopping criteria) */ private final int maxGenerations; /** * Create a new FixedGenerationCount instance. * * @param maxGenerations number of generations to evolve */ public FixedGenerationCount(int maxGenerations) { if (maxGenerations <= 0) throw new IllegalArgumentException("The number of generations has to be >= 0"); this.maxGenerations = maxGenerations; } /** * Determine whether or not the given number of generations have passed. * Increments the number of generations counter if the maximum has not * been reached. * * @param population ignored (no impact on result) * @return true IFF the maximum number of generations has been exceeded */ public boolean isSatisfied(Population population) { if (this.numGenerations < this.maxGenerations) { numGenerations++; return false; } return true; } /** * @return the number of generations that have passed */ public int getNumGenerations() { return numGenerations; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/SelectionPolicy.java100644 1750 1750 2423 11532241244 30115 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Algorithm used to select a chromosome pair from a population. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface SelectionPolicy { /** * Select two chromosomes from the population. * @param population the population from which the chromosomes are choosen. * @return the selected chromosomes. */ ChromosomePair select(Population population); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/AbstractListChromosome.java100644 1750 1750 7315 11532241244 31450 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Chromosome represented by an immutable list of a fixed length. * * @param type of the representation list * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public abstract class AbstractListChromosome extends Chromosome { /** List representing the chromosome */ private final List representation; /** * Constructor. * @param representation inner representation of the chromosome */ public AbstractListChromosome(final List representation) { try { checkValidity(representation); } catch (InvalidRepresentationException e) { throw new IllegalArgumentException(String.format("Invalid representation for %s", getClass().getSimpleName()), e); } this.representation = Collections.unmodifiableList(new ArrayList (representation)); } /** * Constructor. * @param representation inner representation of the chromosome */ public AbstractListChromosome(final T[] representation) { this(Arrays.asList(representation)); } /** * * Asserts that representation can represent a valid chromosome. * @param chromosomeRepresentation representation of the chromosome * @throws InvalidRepresentationException iff the representation can not represent * a valid chromosome */ protected abstract void checkValidity(List chromosomeRepresentation) throws InvalidRepresentationException; /** * Returns the (immutable) inner representation of the chromosome. * @return the representation of the chromosome */ protected List getRepresentation() { return representation; } /** * Returns the length of the chromosome. * @return the length of the chromosome */ public int getLength() { return getRepresentation().size(); } /** * Creates a new instance of the same class as this is, with a * given arrayRepresentation. This is needed in crossover and * mutation operators, where we need a new instance of the same class, but * with different array representation. * * Usually, this method just calls a constructor of the class. * * @param chromosomeRepresentation * the inner array representation of the new chromosome. * @return new instance extended from FixedLengthChromosome with the given * arrayRepresentation */ public abstract AbstractListChromosome newFixedLengthChromosome(final List chromosomeRepresentation); /** * {@inheritDoc} */ @Override public String toString() { return String.format("(f=%s %s)", getFitness(), getRepresentation()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/package.html100644 1750 1750 1656 11532241244 26435 0ustarlucluc 0 0

                    This package provides Genetic Algorithms components and implementations.

                    commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/Chromosome.java100644 1750 1750 7577 11532241244 27142 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Individual in a population. Chromosomes are compared based on their fitness. * * The chromosomes are IMMUTABLE, and so their fitness is also immutable and * therefore it can be cached. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class Chromosome implements Comparable,Fitness { /** * Cached value of the fitness of this chromosome. */ private double fitness = Double.MIN_VALUE; /** * Access the fitness of this chromosome. The bigger the fitness, the better * the chromosome. * * Computation of fitness is usually very time-consuming task, therefore the * fitness is cached. * * @return the fitness. */ public double getFitness() { if (this.fitness == Double.MIN_VALUE) { // no cache - compute the fitness this.fitness = fitness(); } return this.fitness; } /** * Compares two chromosomes based on their fitness. The bigger the fitness, * the better the chromosome. * * @param another another chromosome to compare * @return *
                      *
                    • -1 if another is better than this
                    • *
                    • 1 if another is worse than this
                    • *
                    • 0 if the two chromosomes have the same fitness
                    • *
                    */ public int compareTo(Chromosome another) { return ((Double)this.getFitness()).compareTo(another.getFitness()); } /** * Returns true iff another has the same * representation and therefore the same fitness. By default, it returns * false -- override it in your implementation if you need it. * @param another chromosome to compare * @return true if another is equivalent to this chromosome */ protected boolean isSame(Chromosome another) { return false; } /** * Searches the population for another chromosome with the same * representation. If such chromosome is found, it is returned, if no such * chromosome exists, returns null. * * @param population * Population to search * @return Chromosome with the same representation, or null if * no such chromosome exists. */ protected Chromosome findSameChromosome(Population population) { for (Chromosome anotherChr : population) { if (this.isSame(anotherChr)) return anotherChr; } return null; } /** * Searches the population for a chromosome representing the same solution, * and if it finds one, updates the fitness to its value. * * @param population * Population to search */ public void searchForFitnessUpdate(Population population) { Chromosome sameChromosome = findSameChromosome(population); if (sameChromosome != null) { fitness = sameChromosome.getFitness(); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/CrossoverPolicy.java100644 1750 1750 2633 11532241244 30160 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Policy used to create a pair of new chromosomes by performing a crossover * operation on a source pair of chromosomes. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface CrossoverPolicy { /** * Perform a crossover operation on the given chromosomes. * * @param first the first chromosome. * @param second the second chromosome. * @return the pair of new chromosomes that resulted from the crossover. */ ChromosomePair crossover(Chromosome first, Chromosome second); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/PermutationChromosome.java100644 1750 1750 3232 11532241244 31352 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.List; /** * Interface indicating that the chromosome represents a permutation of objects. * * @param * type of the permuted objects * @since 2.0 * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface PermutationChromosome { /** * Permutes the sequence of objects of type T according to the * permutation this chromosome represents. For example, if this chromosome * represents a permutation (3,0,1,2), and the unpermuted sequence is * (a,b,c,d), this yields (d,a,b,c). * * @param sequence * the unpermuted (original) sequence of objects * @return permutation of sequence represented by this * permutation */ List decode(List sequence); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/MutationPolicy.java100644 1750 1750 2307 11532241244 27771 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; /** * Algorithm used to mutate a chrommosome. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface MutationPolicy { /** * Mutate the given chromosome. * @param original the original chromosome. * @return the mutated chromomsome. */ Chromosome mutate(Chromosome original); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/BinaryChromosome.java100644 1750 1750 5757 11532241244 30305 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.List; /** * Chromosome represented by a vector of 0s and 1s. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public abstract class BinaryChromosome extends AbstractListChromosome { /** * Constructor. * @param representation list of {0,1} values representing the chromosome */ public BinaryChromosome(List representation) { super(representation); } /** * Constructor. * @param representation array of {0,1} values representing the chromosome */ public BinaryChromosome(Integer[] representation) { super(representation); } /** * {@inheritDoc} */ @Override protected void checkValidity(List chromosomeRepresentation) throws InvalidRepresentationException { for (int i : chromosomeRepresentation) { if (i < 0 || i >1) throw new InvalidRepresentationException("Elements can be only 0 or 1."); } } /** * Returns a representation of a random binary array of length length. * @param length length of the array * @return a random binary array of length length */ public static List randomBinaryRepresentation(int length) { // random binary list List rList= new ArrayList (length); for (int j=0; jtrue if this stopping condition is met by the * given population. false otherwise. */ boolean isSatisfied(Population population); } commons-math-2.2-src/src/main/java/org/apache/commons/math/genetics/ListPopulation.java100644 1750 1750 11350 11532241244 30015 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.genetics; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NumberIsTooLargeException; /** * Population of chromosomes represented by a {@link List}. * * @since 2.0 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public abstract class ListPopulation implements Population { /** List of chromosomes */ private List chromosomes; /** maximial size of the population */ private int populationLimit; /** * Creates a new ListPopulation instance. * * @param chromosomes list of chromosomes in the population * @param populationLimit maximal size of the population */ public ListPopulation (List chromosomes, int populationLimit) { if (chromosomes.size() > populationLimit) { throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE, chromosomes.size(), populationLimit, false); } if (populationLimit < 0) { throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit); } this.chromosomes = chromosomes; this.populationLimit = populationLimit; } /** * Creates a new ListPopulation instance and initializes its inner * chromosome list. * * @param populationLimit maximal size of the population */ public ListPopulation (int populationLimit) { if (populationLimit < 0) { throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit); } this.populationLimit = populationLimit; this.chromosomes = new ArrayList(populationLimit); } /** * Sets the list of chromosomes. * @param chromosomes the list of chromosomes */ public void setChromosomes(List chromosomes) { this.chromosomes = chromosomes; } /** * Access the list of chromosomes. * @return the list of chromosomes */ public List getChromosomes() { return chromosomes; } /** * Add the given chromosome to the population. * @param chromosome the chromosome to add. */ public void addChromosome(Chromosome chromosome) { this.chromosomes.add(chromosome); } /** * Access the fittest chromosome in this population. * @return the fittest chromosome. */ public Chromosome getFittestChromosome() { // best so far Chromosome bestChromosome = this.chromosomes.get(0); for (Chromosome chromosome : this.chromosomes) { if (chromosome.compareTo(bestChromosome) > 0) { // better chromosome found bestChromosome = chromosome; } } return bestChromosome; } /** * Access the maximum population size. * @return the maximum population size. */ public int getPopulationLimit() { return this.populationLimit; } /** * Sets the maximal population size. * @param populationLimit maximal population size. */ public void setPopulationLimit(int populationLimit) { this.populationLimit = populationLimit; } /** * Access the current population size. * @return the current population size. */ public int getPopulationSize() { return this.chromosomes.size(); } /** * {@inheritDoc} */ @Override public String toString() { return this.chromosomes.toString(); } /** * Chromosome list iterator * * @return chromosome iterator */ public Iterator iterator() { return chromosomes.iterator(); } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.jav100644 1750 1750 7313 11532241246 32426 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import java.io.Serializable; import java.util.Collection; import org.apache.commons.math.util.MathUtils; /** * A simple implementation of {@link Clusterable} for points with integer coordinates. * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ * @since 2.0 */ public class EuclideanIntegerPoint implements Clusterable, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 3946024775784901369L; /** Point coordinates. */ private final int[] point; /** * Build an instance wrapping an integer array. *

                    The wrapped array is referenced, it is not copied.

                    * @param point the n-dimensional point in integer space */ public EuclideanIntegerPoint(final int[] point) { this.point = point; } /** * Get the n-dimensional point in integer space. * @return a reference (not a copy!) to the wrapped array */ public int[] getPoint() { return point; } /** {@inheritDoc} */ public double distanceFrom(final EuclideanIntegerPoint p) { return MathUtils.distance(point, p.getPoint()); } /** {@inheritDoc} */ public EuclideanIntegerPoint centroidOf(final Collection points) { int[] centroid = new int[getPoint().length]; for (EuclideanIntegerPoint p : points) { for (int i = 0; i < centroid.length; i++) { centroid[i] += p.getPoint()[i]; } } for (int i = 0; i < centroid.length; i++) { centroid[i] /= points.size(); } return new EuclideanIntegerPoint(centroid); } /** {@inheritDoc} */ @Override public boolean equals(final Object other) { if (!(other instanceof EuclideanIntegerPoint)) { return false; } final int[] otherPoint = ((EuclideanIntegerPoint) other).getPoint(); if (point.length != otherPoint.length) { return false; } for (int i = 0; i < point.length; i++) { if (point[i] != otherPoint[i]) { return false; } } return true; } /** {@inheritDoc} */ @Override public int hashCode() { int hashCode = 0; for (Integer i : point) { hashCode += i.hashCode() * 13 + 7; } return hashCode; } /** * {@inheritDoc} * @since 2.1 */ @Override public String toString() { final StringBuilder buff = new StringBuilder("("); final int[] coordinates = getPoint(); for (int i = 0; i < coordinates.length; i++) { buff.append(coordinates[i]); if (i < coordinates.length - 1) { buff.append(","); } } buff.append(")"); return buff.toString(); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.j100644 1750 1750 30521 11532241246 32452 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Random; import org.apache.commons.math.exception.ConvergenceException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.moment.Variance; /** * Clustering algorithm based on David Arthur and Sergei Vassilvitski k-means++ algorithm. * @param type of the points to cluster * @see K-means++ (wikipedia) * @version $Revision: 1054333 $ $Date: 2011-01-02 01:34:58 +0100 (dim. 02 janv. 2011) $ * @since 2.0 */ public class KMeansPlusPlusClusterer> { /** Strategies to use for replacing an empty cluster. */ public static enum EmptyClusterStrategy { /** Split the cluster with largest distance variance. */ LARGEST_VARIANCE, /** Split the cluster with largest number of points. */ LARGEST_POINTS_NUMBER, /** Create a cluster around the point farthest from its centroid. */ FARTHEST_POINT, /** Generate an error. */ ERROR } /** Random generator for choosing initial centers. */ private final Random random; /** Selected strategy for empty clusters. */ private final EmptyClusterStrategy emptyStrategy; /** Build a clusterer. *

                    * The default strategy for handling empty clusters that may appear during * algorithm iterations is to split the cluster with largest distance variance. *

                    * @param random random generator to use for choosing initial centers */ public KMeansPlusPlusClusterer(final Random random) { this(random, EmptyClusterStrategy.LARGEST_VARIANCE); } /** Build a clusterer. * @param random random generator to use for choosing initial centers * @param emptyStrategy strategy to use for handling empty clusters that * may appear during algorithm iterations * @since 2.2 */ public KMeansPlusPlusClusterer(final Random random, final EmptyClusterStrategy emptyStrategy) { this.random = random; this.emptyStrategy = emptyStrategy; } /** * Runs the K-means++ clustering algorithm. * * @param points the points to cluster * @param k the number of clusters to split the data into * @param maxIterations the maximum number of iterations to run the algorithm * for. If negative, no maximum will be used * @return a list of clusters containing the points */ public List> cluster(final Collection points, final int k, final int maxIterations) { // create the initial clusters List> clusters = chooseInitialCenters(points, k, random); assignPointsToClusters(clusters, points); // iterate through updating the centers until we're done final int max = (maxIterations < 0) ? Integer.MAX_VALUE : maxIterations; for (int count = 0; count < max; count++) { boolean clusteringChanged = false; List> newClusters = new ArrayList>(); for (final Cluster cluster : clusters) { final T newCenter; if (cluster.getPoints().isEmpty()) { switch (emptyStrategy) { case LARGEST_VARIANCE : newCenter = getPointFromLargestVarianceCluster(clusters); break; case LARGEST_POINTS_NUMBER : newCenter = getPointFromLargestNumberCluster(clusters); break; case FARTHEST_POINT : newCenter = getFarthestPoint(clusters); break; default : throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS); } clusteringChanged = true; } else { newCenter = cluster.getCenter().centroidOf(cluster.getPoints()); if (!newCenter.equals(cluster.getCenter())) { clusteringChanged = true; } } newClusters.add(new Cluster(newCenter)); } if (!clusteringChanged) { return clusters; } assignPointsToClusters(newClusters, points); clusters = newClusters; } return clusters; } /** * Adds the given points to the closest {@link Cluster}. * * @param type of the points to cluster * @param clusters the {@link Cluster}s to add the points to * @param points the points to add to the given {@link Cluster}s */ private static > void assignPointsToClusters(final Collection> clusters, final Collection points) { for (final T p : points) { Cluster cluster = getNearestCluster(clusters, p); cluster.addPoint(p); } } /** * Use K-means++ to choose the initial centers. * * @param type of the points to cluster * @param points the points to choose the initial centers from * @param k the number of centers to choose * @param random random generator to use * @return the initial centers */ private static > List> chooseInitialCenters(final Collection points, final int k, final Random random) { final List pointSet = new ArrayList(points); final List> resultSet = new ArrayList>(); // Choose one center uniformly at random from among the data points. final T firstPoint = pointSet.remove(random.nextInt(pointSet.size())); resultSet.add(new Cluster(firstPoint)); final double[] dx2 = new double[pointSet.size()]; while (resultSet.size() < k) { // For each data point x, compute D(x), the distance between x and // the nearest center that has already been chosen. int sum = 0; for (int i = 0; i < pointSet.size(); i++) { final T p = pointSet.get(i); final Cluster nearest = getNearestCluster(resultSet, p); final double d = p.distanceFrom(nearest.getCenter()); sum += d * d; dx2[i] = sum; } // Add one new data point as a center. Each point x is chosen with // probability proportional to D(x)2 final double r = random.nextDouble() * sum; for (int i = 0 ; i < dx2.length; i++) { if (dx2[i] >= r) { final T p = pointSet.remove(i); resultSet.add(new Cluster(p)); break; } } } return resultSet; } /** * Get a random point from the {@link Cluster} with the largest distance variance. * * @param clusters the {@link Cluster}s to search * @return a random point from the selected cluster */ private T getPointFromLargestVarianceCluster(final Collection> clusters) { double maxVariance = Double.NEGATIVE_INFINITY; Cluster selected = null; for (final Cluster cluster : clusters) { if (!cluster.getPoints().isEmpty()) { // compute the distance variance of the current cluster final T center = cluster.getCenter(); final Variance stat = new Variance(); for (final T point : cluster.getPoints()) { stat.increment(point.distanceFrom(center)); } final double variance = stat.getResult(); // select the cluster with the largest variance if (variance > maxVariance) { maxVariance = variance; selected = cluster; } } } // did we find at least one non-empty cluster ? if (selected == null) { throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS); } // extract a random point from the cluster final List selectedPoints = selected.getPoints(); return selectedPoints.remove(random.nextInt(selectedPoints.size())); } /** * Get a random point from the {@link Cluster} with the largest number of points * * @param clusters the {@link Cluster}s to search * @return a random point from the selected cluster */ private T getPointFromLargestNumberCluster(final Collection> clusters) { int maxNumber = 0; Cluster selected = null; for (final Cluster cluster : clusters) { // get the number of points of the current cluster final int number = cluster.getPoints().size(); // select the cluster with the largest number of points if (number > maxNumber) { maxNumber = number; selected = cluster; } } // did we find at least one non-empty cluster ? if (selected == null) { throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS); } // extract a random point from the cluster final List selectedPoints = selected.getPoints(); return selectedPoints.remove(random.nextInt(selectedPoints.size())); } /** * Get the point farthest to its cluster center * * @param clusters the {@link Cluster}s to search * @return point farthest to its cluster center */ private T getFarthestPoint(final Collection> clusters) { double maxDistance = Double.NEGATIVE_INFINITY; Cluster selectedCluster = null; int selectedPoint = -1; for (final Cluster cluster : clusters) { // get the farthest point final T center = cluster.getCenter(); final List points = cluster.getPoints(); for (int i = 0; i < points.size(); ++i) { final double distance = points.get(i).distanceFrom(center); if (distance > maxDistance) { maxDistance = distance; selectedCluster = cluster; selectedPoint = i; } } } // did we find at least one non-empty cluster ? if (selectedCluster == null) { throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS); } return selectedCluster.getPoints().remove(selectedPoint); } /** * Returns the nearest {@link Cluster} to the given point * * @param type of the points to cluster * @param clusters the {@link Cluster}s to search * @param point the point to find the nearest {@link Cluster} for * @return the nearest {@link Cluster} to the given point */ private static > Cluster getNearestCluster(final Collection> clusters, final T point) { double minDistance = Double.MAX_VALUE; Cluster minCluster = null; for (final Cluster c : clusters) { final double distance = point.distanceFrom(c.getCenter()); if (distance < minDistance) { minDistance = distance; minCluster = c; } } return minCluster; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/package.html100644 1750 1750 1652 11532241246 27764 0ustarlucluc 0 0 Clustering algorithms commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/Cluster.java100644 1750 1750 4317 11532241246 27770 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * Cluster holding a set of {@link Clusterable} points. * @param the type of points that can be clustered * @version $Revision: 771076 $ $Date: 2009-05-03 18:28:48 +0200 (dim. 03 mai 2009) $ * @since 2.0 */ public class Cluster> implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -3442297081515880464L; /** The points contained in this cluster. */ private final List points; /** Center of the cluster. */ private final T center; /** * Build a cluster centered at a specified point. * @param center the point which is to be the center of this cluster */ public Cluster(final T center) { this.center = center; points = new ArrayList(); } /** * Add a point to this cluster. * @param point point to add */ public void addPoint(final T point) { points.add(point); } /** * Get the points contained in the cluster. * @return points contained in the cluster */ public List getPoints() { return points; } /** * Get the point chosen to be the center of this cluster. * @return chosen cluster center */ public T getCenter() { return center; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/clustering/Clusterable.java100644 1750 1750 3101 11532241246 30602 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.clustering; import java.util.Collection; /** * Interface for points that can be clustered together. * @param the type of point that can be clustered * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface Clusterable { /** * Returns the distance from the given point. * * @param p the point to compute the distance from * @return the distance from the given point */ double distanceFrom(T p); /** * Returns the centroid of the given Collection of points. * * @param p the Collection of points to compute the centroid of * @return the centroid of the given Collection of Points */ T centroidOf(Collection p); } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SummaryStatistics.java100644 1750 1750 57667 11532241247 32262 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.moment.GeometricMean; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.SecondMoment; import org.apache.commons.math.stat.descriptive.moment.Variance; import org.apache.commons.math.stat.descriptive.rank.Max; import org.apache.commons.math.stat.descriptive.rank.Min; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** *

                    * Computes summary statistics for a stream of data values added using the * {@link #addValue(double) addValue} method. The data values are not stored in * memory, so this class can be used to compute statistics for very large data * streams. *

                    *

                    * The {@link StorelessUnivariateStatistic} instances used to maintain summary * state and compute statistics are configurable via setters. For example, the * default implementation for the variance can be overridden by calling * {@link #setVarianceImpl(StorelessUnivariateStatistic)}. Actual parameters to * these methods must implement the {@link StorelessUnivariateStatistic} * interface and configuration must be completed before addValue * is called. No configuration is necessary to use the default, commons-math * provided implementations. *

                    *

                    * Note: This class is not thread-safe. Use * {@link SynchronizedSummaryStatistics} if concurrent access from multiple * threads is required. *

                    * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ public class SummaryStatistics implements StatisticalSummary, Serializable { /** Serialization UID */ private static final long serialVersionUID = -2021321786743555871L; /** count of values that have been added */ protected long n = 0; /** SecondMoment is used to compute the mean and variance */ protected SecondMoment secondMoment = new SecondMoment(); /** sum of values that have been added */ protected Sum sum = new Sum(); /** sum of the square of each value that has been added */ protected SumOfSquares sumsq = new SumOfSquares(); /** min of values that have been added */ protected Min min = new Min(); /** max of values that have been added */ protected Max max = new Max(); /** sumLog of values that have been added */ protected SumOfLogs sumLog = new SumOfLogs(); /** geoMean of values that have been added */ protected GeometricMean geoMean = new GeometricMean(sumLog); /** mean of values that have been added */ protected Mean mean = new Mean(); /** variance of values that have been added */ protected Variance variance = new Variance(); /** Sum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic sumImpl = sum; /** Sum of squares statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic sumsqImpl = sumsq; /** Minimum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic minImpl = min; /** Maximum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic maxImpl = max; /** Sum of log statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic sumLogImpl = sumLog; /** Geometric mean statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic geoMeanImpl = geoMean; /** Mean statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic meanImpl = mean; /** Variance statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic varianceImpl = variance; /** * Construct a SummaryStatistics instance */ public SummaryStatistics() { } /** * A copy constructor. Creates a deep-copy of the {@code original}. * * @param original the {@code SummaryStatistics} instance to copy */ public SummaryStatistics(SummaryStatistics original) { copy(original, this); } /** * Return a {@link StatisticalSummaryValues} instance reporting current * statistics. * @return Current values of statistics */ public StatisticalSummary getSummary() { return new StatisticalSummaryValues(getMean(), getVariance(), getN(), getMax(), getMin(), getSum()); } /** * Add a value to the data * @param value the value to add */ public void addValue(double value) { sumImpl.increment(value); sumsqImpl.increment(value); minImpl.increment(value); maxImpl.increment(value); sumLogImpl.increment(value); secondMoment.increment(value); // If mean, variance or geomean have been overridden, // need to increment these if (!(meanImpl instanceof Mean)) { meanImpl.increment(value); } if (!(varianceImpl instanceof Variance)) { varianceImpl.increment(value); } if (!(geoMeanImpl instanceof GeometricMean)) { geoMeanImpl.increment(value); } n++; } /** * Returns the number of available values * @return The number of available values */ public long getN() { return n; } /** * Returns the sum of the values that have been added * @return The sum or Double.NaN if no values have been added */ public double getSum() { return sumImpl.getResult(); } /** * Returns the sum of the squares of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return The sum of squares */ public double getSumsq() { return sumsqImpl.getResult(); } /** * Returns the mean of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the mean */ public double getMean() { if (mean == meanImpl) { return new Mean(secondMoment).getResult(); } else { return meanImpl.getResult(); } } /** * Returns the standard deviation of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the standard deviation */ public double getStandardDeviation() { double stdDev = Double.NaN; if (getN() > 0) { if (getN() > 1) { stdDev = FastMath.sqrt(getVariance()); } else { stdDev = 0.0; } } return stdDev; } /** * Returns the variance of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the variance */ public double getVariance() { if (varianceImpl == variance) { return new Variance(secondMoment).getResult(); } else { return varianceImpl.getResult(); } } /** * Returns the maximum of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the maximum */ public double getMax() { return maxImpl.getResult(); } /** * Returns the minimum of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the minimum */ public double getMin() { return minImpl.getResult(); } /** * Returns the geometric mean of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the geometric mean */ public double getGeometricMean() { return geoMeanImpl.getResult(); } /** * Returns the sum of the logs of the values that have been added. *

                    * Double.NaN is returned if no values have been added. *

                    * @return the sum of logs * @since 1.2 */ public double getSumOfLogs() { return sumLogImpl.getResult(); } /** * Returns a statistic related to the Second Central Moment. Specifically, * what is returned is the sum of squared deviations from the sample mean * among the values that have been added. *

                    * Returns Double.NaN if no data values have been added and * returns 0 if there is just one value in the data set.

                    *

                    * @return second central moment statistic * @since 2.0 */ public double getSecondMoment() { return secondMoment.getResult(); } /** * Generates a text report displaying summary statistics from values that * have been added. * @return String with line feeds displaying statistics * @since 1.2 */ @Override public String toString() { StringBuilder outBuffer = new StringBuilder(); String endl = "\n"; outBuffer.append("SummaryStatistics:").append(endl); outBuffer.append("n: ").append(getN()).append(endl); outBuffer.append("min: ").append(getMin()).append(endl); outBuffer.append("max: ").append(getMax()).append(endl); outBuffer.append("mean: ").append(getMean()).append(endl); outBuffer.append("geometric mean: ").append(getGeometricMean()) .append(endl); outBuffer.append("variance: ").append(getVariance()).append(endl); outBuffer.append("sum of squares: ").append(getSumsq()).append(endl); outBuffer.append("standard deviation: ").append(getStandardDeviation()) .append(endl); outBuffer.append("sum of logs: ").append(getSumOfLogs()).append(endl); return outBuffer.toString(); } /** * Resets all statistics and storage */ public void clear() { this.n = 0; minImpl.clear(); maxImpl.clear(); sumImpl.clear(); sumLogImpl.clear(); sumsqImpl.clear(); geoMeanImpl.clear(); secondMoment.clear(); if (meanImpl != mean) { meanImpl.clear(); } if (varianceImpl != variance) { varianceImpl.clear(); } } /** * Returns true iff object is a * SummaryStatistics instance and all statistics have the * same values as this. * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(Object object) { if (object == this) { return true; } if (object instanceof SummaryStatistics == false) { return false; } SummaryStatistics stat = (SummaryStatistics)object; return MathUtils.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) && MathUtils.equalsIncludingNaN(stat.getMax(), getMax()) && MathUtils.equalsIncludingNaN(stat.getMean(), getMean()) && MathUtils.equalsIncludingNaN(stat.getMin(), getMin()) && MathUtils.equalsIncludingNaN(stat.getN(), getN()) && MathUtils.equalsIncludingNaN(stat.getSum(), getSum()) && MathUtils.equalsIncludingNaN(stat.getSumsq(), getSumsq()) && MathUtils.equalsIncludingNaN(stat.getVariance(), getVariance()); } /** * Returns hash code based on values of statistics * @return hash code */ @Override public int hashCode() { int result = 31 + MathUtils.hash(getGeometricMean()); result = result * 31 + MathUtils.hash(getGeometricMean()); result = result * 31 + MathUtils.hash(getMax()); result = result * 31 + MathUtils.hash(getMean()); result = result * 31 + MathUtils.hash(getMin()); result = result * 31 + MathUtils.hash(getN()); result = result * 31 + MathUtils.hash(getSum()); result = result * 31 + MathUtils.hash(getSumsq()); result = result * 31 + MathUtils.hash(getVariance()); return result; } // Getters and setters for statistics implementations /** * Returns the currently configured Sum implementation * @return the StorelessUnivariateStatistic implementing the sum * @since 1.2 */ public StorelessUnivariateStatistic getSumImpl() { return sumImpl; } /** *

                    * Sets the implementation for the Sum. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param sumImpl the StorelessUnivariateStatistic instance to use for * computing the Sum * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setSumImpl(StorelessUnivariateStatistic sumImpl) { checkEmpty(); this.sumImpl = sumImpl; } /** * Returns the currently configured sum of squares implementation * @return the StorelessUnivariateStatistic implementing the sum of squares * @since 1.2 */ public StorelessUnivariateStatistic getSumsqImpl() { return sumsqImpl; } /** *

                    * Sets the implementation for the sum of squares. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param sumsqImpl the StorelessUnivariateStatistic instance to use for * computing the sum of squares * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) { checkEmpty(); this.sumsqImpl = sumsqImpl; } /** * Returns the currently configured minimum implementation * @return the StorelessUnivariateStatistic implementing the minimum * @since 1.2 */ public StorelessUnivariateStatistic getMinImpl() { return minImpl; } /** *

                    * Sets the implementation for the minimum. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param minImpl the StorelessUnivariateStatistic instance to use for * computing the minimum * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setMinImpl(StorelessUnivariateStatistic minImpl) { checkEmpty(); this.minImpl = minImpl; } /** * Returns the currently configured maximum implementation * @return the StorelessUnivariateStatistic implementing the maximum * @since 1.2 */ public StorelessUnivariateStatistic getMaxImpl() { return maxImpl; } /** *

                    * Sets the implementation for the maximum. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param maxImpl the StorelessUnivariateStatistic instance to use for * computing the maximum * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setMaxImpl(StorelessUnivariateStatistic maxImpl) { checkEmpty(); this.maxImpl = maxImpl; } /** * Returns the currently configured sum of logs implementation * @return the StorelessUnivariateStatistic implementing the log sum * @since 1.2 */ public StorelessUnivariateStatistic getSumLogImpl() { return sumLogImpl; } /** *

                    * Sets the implementation for the sum of logs. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param sumLogImpl the StorelessUnivariateStatistic instance to use for * computing the log sum * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) { checkEmpty(); this.sumLogImpl = sumLogImpl; geoMean.setSumLogImpl(sumLogImpl); } /** * Returns the currently configured geometric mean implementation * @return the StorelessUnivariateStatistic implementing the geometric mean * @since 1.2 */ public StorelessUnivariateStatistic getGeoMeanImpl() { return geoMeanImpl; } /** *

                    * Sets the implementation for the geometric mean. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param geoMeanImpl the StorelessUnivariateStatistic instance to use for * computing the geometric mean * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) { checkEmpty(); this.geoMeanImpl = geoMeanImpl; } /** * Returns the currently configured mean implementation * @return the StorelessUnivariateStatistic implementing the mean * @since 1.2 */ public StorelessUnivariateStatistic getMeanImpl() { return meanImpl; } /** *

                    * Sets the implementation for the mean. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param meanImpl the StorelessUnivariateStatistic instance to use for * computing the mean * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setMeanImpl(StorelessUnivariateStatistic meanImpl) { checkEmpty(); this.meanImpl = meanImpl; } /** * Returns the currently configured variance implementation * @return the StorelessUnivariateStatistic implementing the variance * @since 1.2 */ public StorelessUnivariateStatistic getVarianceImpl() { return varianceImpl; } /** *

                    * Sets the implementation for the variance. *

                    *

                    * This method must be activated before any data has been added - i.e., * before {@link #addValue(double) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown. *

                    * @param varianceImpl the StorelessUnivariateStatistic instance to use for * computing the variance * @throws IllegalStateException if data has already been added (i.e if n > * 0) * @since 1.2 */ public void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) { checkEmpty(); this.varianceImpl = varianceImpl; } /** * Throws IllegalStateException if n > 0. */ private void checkEmpty() { if (n > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC, n); } } /** * Returns a copy of this SummaryStatistics instance with the same internal state. * * @return a copy of this */ public SummaryStatistics copy() { SummaryStatistics result = new SummaryStatistics(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source SummaryStatistics to copy * @param dest SummaryStatistics to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SummaryStatistics source, SummaryStatistics dest) { dest.maxImpl = source.maxImpl.copy(); dest.meanImpl = source.meanImpl.copy(); dest.minImpl = source.minImpl.copy(); dest.sumImpl = source.sumImpl.copy(); dest.varianceImpl = source.varianceImpl.copy(); dest.sumLogImpl = source.sumLogImpl.copy(); dest.sumsqImpl = source.sumsqImpl.copy(); if (source.getGeoMeanImpl() instanceof GeometricMean) { // Keep geoMeanImpl, sumLogImpl in synch dest.geoMeanImpl = new GeometricMean((SumOfLogs) dest.sumLogImpl); } else { dest.geoMeanImpl = source.geoMeanImpl.copy(); } SecondMoment.copy(source.secondMoment, dest.secondMoment); dest.n = source.n; // Make sure that if stat == statImpl in source, same // holds in dest; otherwise copy stat if (source.geoMean == source.geoMeanImpl) { dest.geoMean = (GeometricMean) dest.geoMeanImpl; } else { GeometricMean.copy(source.geoMean, dest.geoMean); } if (source.max == source.maxImpl) { dest.max = (Max) dest.maxImpl; } else { Max.copy(source.max, dest.max); } if (source.mean == source.meanImpl) { dest.mean = (Mean) dest.meanImpl; } else { Mean.copy(source.mean, dest.mean); } if (source.min == source.minImpl) { dest.min = (Min) dest.minImpl; } else { Min.copy(source.min, dest.min); } if (source.sum == source.sumImpl) { dest.sum = (Sum) dest.sumImpl; } else { Sum.copy(source.sum, dest.sum); } if (source.variance == source.varianceImpl) { dest.variance = (Variance) dest.varianceImpl; } else { Variance.copy(source.variance, dest.variance); } if (source.sumLog == source.sumLogImpl) { dest.sumLog = (SumOfLogs) dest.sumLogImpl; } else { SumOfLogs.copy(source.sumLog, dest.sumLog); } if (source.sumsq == source.sumsqImpl) { dest.sumsq = (SumOfSquares) dest.sumsqImpl; } else { SumOfSquares.copy(source.sumsq, dest.sumsq); } } } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveS100644 1750 1750 11325 11532241247 32613 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Implementation of * {@link org.apache.commons.math.stat.descriptive.DescriptiveStatistics} that * is safe to use in a multithreaded environment. Multiple threads can safely * operate on a single instance without causing runtime exceptions due to race * conditions. In effect, this implementation makes modification and access * methods atomic operations for a single instance. That is to say, as one * thread is computing a statistic from the instance, no other thread can modify * the instance nor compute another statistic. * * @since 1.2 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics { /** Serialization UID */ private static final long serialVersionUID = 1L; /** * Construct an instance with infinite window */ public SynchronizedDescriptiveStatistics() { this(INFINITE_WINDOW); } /** * Construct an instance with finite window * @param window the finite window size. */ public SynchronizedDescriptiveStatistics(int window) { super(window); } /** * A copy constructor. Creates a deep-copy of the {@code original}. * * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy */ public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original) { copy(original, this); } /** * {@inheritDoc} */ @Override public synchronized void addValue(double v) { super.addValue(v); } /** * {@inheritDoc} */ @Override public synchronized double apply(UnivariateStatistic stat) { return super.apply(stat); } /** * {@inheritDoc} */ @Override public synchronized void clear() { super.clear(); } /** * {@inheritDoc} */ @Override public synchronized double getElement(int index) { return super.getElement(index); } /** * {@inheritDoc} */ @Override public synchronized long getN() { return super.getN(); } /** * {@inheritDoc} */ @Override public synchronized double getStandardDeviation() { return super.getStandardDeviation(); } /** * {@inheritDoc} */ @Override public synchronized double[] getValues() { return super.getValues(); } /** * {@inheritDoc} */ @Override public synchronized int getWindowSize() { return super.getWindowSize(); } /** * {@inheritDoc} */ @Override public synchronized void setWindowSize(int windowSize) { super.setWindowSize(windowSize); } /** * {@inheritDoc} */ @Override public synchronized String toString() { return super.toString(); } /** * Returns a copy of this SynchronizedDescriptiveStatistics instance with the * same internal state. * * @return a copy of this */ @Override public synchronized SynchronizedDescriptiveStatistics copy() { SynchronizedDescriptiveStatistics result = new SynchronizedDescriptiveStatistics(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    *

                    Acquires synchronization lock on source, then dest before copying.

                    * * @param source SynchronizedDescriptiveStatistics to copy * @param dest SynchronizedDescriptiveStatistics to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SynchronizedDescriptiveStatistics source, SynchronizedDescriptiveStatistics dest) { synchronized (source) { synchronized (dest) { DescriptiveStatistics.copy(source, dest); } } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java100644 1750 1750 11556 11532241247 32110 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Returns the sum of the natural logs for this collection of values. *

                    * Uses {@link java.lang.Math#log(double)} to compute the logs. Therefore, *

                      *
                    • If any of values are < 0, the result is NaN.
                    • *
                    • If all values are non-negative and less than * Double.POSITIVE_INFINITY, but at least one value is 0, the * result is Double.NEGATIVE_INFINITY.
                    • *
                    • If both Double.POSITIVE_INFINITY and * Double.NEGATIVE_INFINITY are among the values, the result is * NaN.
                    • *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class SumOfLogs extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -370076995648386763L; /**Number of values that have been added */ private int n; /** * The currently running value */ private double value; /** * Create a SumOfLogs instance */ public SumOfLogs() { value = 0d; n = 0; } /** * Copy constructor, creates a new {@code SumOfLogs} identical * to the {@code original} * * @param original the {@code SumOfLogs} instance to copy */ public SumOfLogs(SumOfLogs original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { value += FastMath.log(d); n++; } /** * {@inheritDoc} */ @Override public double getResult() { if (n > 0) { return value; } else { return Double.NaN; } } /** * {@inheritDoc} */ public long getN() { return n; } /** * {@inheritDoc} */ @Override public void clear() { value = 0d; n = 0; } /** * Returns the sum of the natural logs of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link SumOfLogs}.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the natural logs of the values or Double.NaN if * length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { double sumLog = Double.NaN; if (test(values, begin, length)) { sumLog = 0.0; for (int i = begin; i < begin + length; i++) { sumLog += FastMath.log(values[i]); } } return sumLog; } /** * {@inheritDoc} */ @Override public SumOfLogs copy() { SumOfLogs result = new SumOfLogs(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source SumOfLogs to copy * @param dest SumOfLogs to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SumOfLogs source, SumOfLogs dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/package.html100644 1750 1750 1657 11532241247 31631 0ustarlucluc 0 0 Other summary statistics. commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java100644 1750 1750 15515 11532241246 30774 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Returns the sum of the available values. *

                    * If there are no values in the dataset, or any of the values are * NaN, then NaN is returned.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -8231831954703408316L; /** */ private long n; /** * The currently running sum. */ private double value; /** * Create a Sum instance */ public Sum() { n = 0; value = Double.NaN; } /** * Copy constructor, creates a new {@code Sum} identical * to the {@code original} * * @param original the {@code Sum} instance to copy */ public Sum(Sum original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n == 0) { value = d; } else { value += d; } n++; } /** * {@inheritDoc} */ @Override public double getResult() { return value; } /** * {@inheritDoc} */ public long getN() { return n; } /** * {@inheritDoc} */ @Override public void clear() { value = Double.NaN; n = 0; } /** * The sum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { double sum = Double.NaN; if (test(values, begin, length)) { sum = 0.0; for (int i = begin; i < begin + length; i++) { sum += values[i]; } } return sum; } /** * The weighted sum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *
                    • the start and length arguments do not determine a valid array
                    • *

                    *

                    * Uses the formula,

                         *    weighted sum = Σ(values[i] * weights[i])
                         * 

                    * * @param values the input array * @param weights the weights array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { double sum = Double.NaN; if (test(values, weights, begin, length)) { sum = 0.0; for (int i = begin; i < begin + length; i++) { sum += values[i] * weights[i]; } } return sum; } /** * The weighted sum of the entries in the the input array. *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *

                    *

                    * Uses the formula,

                         *    weighted sum = Σ(values[i] * weights[i])
                         * 

                    * * @param values the input array * @param weights the weights array * @return the sum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights) { return evaluate(values, weights, 0, values.length); } /** * {@inheritDoc} */ @Override public Sum copy() { Sum result = new Sum(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Sum to copy * @param dest Sum to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Sum source, Sum dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.jav100644 1750 1750 10573 11532241246 32463 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Returns the sum of the squares of the available values. *

                    * If there are no values in the dataset, or any of the values are * NaN, then NaN is returned.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class SumOfSquares extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 1460986908574398008L; /** */ private long n; /** * The currently running sumSq */ private double value; /** * Create a SumOfSquares instance */ public SumOfSquares() { n = 0; value = Double.NaN; } /** * Copy constructor, creates a new {@code SumOfSquares} identical * to the {@code original} * * @param original the {@code SumOfSquares} instance to copy */ public SumOfSquares(SumOfSquares original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n == 0) { value = d * d; } else { value += d * d; } n++; } /** * {@inheritDoc} */ @Override public double getResult() { return value; } /** * {@inheritDoc} */ public long getN() { return n; } /** * {@inheritDoc} */ @Override public void clear() { value = Double.NaN; n = 0; } /** * Returns the sum of the squares of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the squares of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values,final int begin, final int length) { double sumSq = Double.NaN; if (test(values, begin, length)) { sumSq = 0.0; for (int i = begin; i < begin + length; i++) { sumSq += values[i] * values[i]; } } return sumSq; } /** * {@inheritDoc} */ @Override public SumOfSquares copy() { SumOfSquares result = new SumOfSquares(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source SumOfSquares to copy * @param dest SumOfSquares to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SumOfSquares source, SumOfSquares dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java100644 1750 1750 16541 11532241246 31650 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.summary; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.WeightedEvaluation; import org.apache.commons.math.util.FastMath; /** * Returns the product of the available values. *

                    * If there are no values in the dataset, or any of the values are * NaN, then NaN is returned.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Product extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation { /** Serializable version identifier */ private static final long serialVersionUID = 2824226005990582538L; /**The number of values that have been added */ private long n; /** * The current Running Product. */ private double value; /** * Create a Product instance */ public Product() { n = 0; value = Double.NaN; } /** * Copy constructor, creates a new {@code Product} identical * to the {@code original} * * @param original the {@code Product} instance to copy */ public Product(Product original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n == 0) { value = d; } else { value *= d; } n++; } /** * {@inheritDoc} */ @Override public double getResult() { return value; } /** * {@inheritDoc} */ public long getN() { return n; } /** * {@inheritDoc} */ @Override public void clear() { value = Double.NaN; n = 0; } /** * Returns the product of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the product of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { double product = Double.NaN; if (test(values, begin, length)) { product = 1.0; for (int i = begin; i < begin + length; i++) { product *= values[i]; } } return product; } /** *

                    Returns the weighted product of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty.

                    * *

                    Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *
                    • the start and length arguments do not determine a valid array
                    • *

                    * *

                    Uses the formula,

                         *    weighted product = ∏values[i]weights[i]
                         * 
                    * that is, the weights are applied as exponents when computing the weighted product.

                    * * @param values the input array * @param weights the weights array * @param begin index of the first array element to include * @param length the number of elements to include * @return the product of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { double product = Double.NaN; if (test(values, weights, begin, length)) { product = 1.0; for (int i = begin; i < begin + length; i++) { product *= FastMath.pow(values[i], weights[i]); } } return product; } /** *

                    Returns the weighted product of the entries in the input array.

                    * *

                    Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *

                    * *

                    Uses the formula,

                         *    weighted product = ∏values[i]weights[i]
                         * 
                    * that is, the weights are applied as exponents when computing the weighted product.

                    * * @param values the input array * @param weights the weights array * @return the product of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights) { return evaluate(values, weights, 0, values.length); } /** * {@inheritDoc} */ @Override public Product copy() { Product result = new Product(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Product to copy * @param dest Product to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Product source, Product dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/Max.java100644 1750 1750 11601 11532241246 30203 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Returns the maximum of the available values. *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.POSITIVE_INFINITY, * the result is Double.POSITIVE_INFINITY.
                    • *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Max extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -5593383832225844641L; /** Number of values that have been added */ private long n; /** Current value of the statistic */ private double value; /** * Create a Max instance */ public Max() { n = 0; value = Double.NaN; } /** * Copy constructor, creates a new {@code Max} identical * to the {@code original} * * @param original the {@code Max} instance to copy */ public Max(Max original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (d > value || Double.isNaN(value)) { value = d; } n++; } /** * {@inheritDoc} */ @Override public void clear() { value = Double.NaN; n = 0; } /** * {@inheritDoc} */ @Override public double getResult() { return value; } /** * {@inheritDoc} */ public long getN() { return n; } /** * Returns the maximum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null or * the array index parameters are not valid.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.POSITIVE_INFINITY, * the result is Double.POSITIVE_INFINITY.
                    • *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the maximum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { double max = Double.NaN; if (test(values, begin, length)) { max = values[begin]; for (int i = begin; i < begin + length; i++) { if (!Double.isNaN(values[i])) { max = (max > values[i]) ? max : values[i]; } } } return max; } /** * {@inheritDoc} */ @Override public Max copy() { Max result = new Max(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Max to copy * @param dest Max to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Max source, Max dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/Percentile.java100644 1750 1750 44726 11532241246 31566 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Provides percentile computation. *

                    * There are several commonly used methods for estimating percentiles (a.k.a. * quantiles) based on sample data. For large samples, the different methods * agree closely, but when sample sizes are small, different methods will give * significantly different results. The algorithm implemented here works as follows: *

                      *
                    1. Let n be the length of the (sorted) array and * 0 < p <= 100 be the desired percentile.
                    2. *
                    3. If n = 1 return the unique array element (regardless of * the value of p); otherwise
                    4. *
                    5. Compute the estimated percentile position * pos = p * (n + 1) / 100 and the difference, d * between pos and floor(pos) (i.e. the fractional * part of pos). If pos >= n return the largest * element in the array; otherwise
                    6. *
                    7. Let lower be the element in position * floor(pos) in the array and let upper be the * next element in the array. Return lower + d * (upper - lower) *
                    8. *

                    *

                    * To compute percentiles, the data must be at least partially ordered. Input * arrays are copied and recursively partitioned using an ordering definition. * The ordering used by Arrays.sort(double[]) is the one determined * by {@link java.lang.Double#compareTo(Double)}. This ordering makes * Double.NaN larger than any other value (including * Double.POSITIVE_INFINITY). Therefore, for example, the median * (50th percentile) of * {0, 1, 2, 3, 4, Double.NaN} evaluates to 2.5.

                    *

                    * Since percentile estimation usually involves interpolation between array * elements, arrays containing NaN or infinite values will often * result in NaN or infinite values returned.

                    *

                    * Since 2.2, Percentile implementation uses only selection instead of complete * sorting and caches selection algorithm state between calls to the various * {@code evaluate} methods when several percentiles are to be computed on the same data. * This greatly improves efficiency, both for single percentile and multiple * percentiles computations. However, it also induces a need to be sure the data * at one call to {@code evaluate} is the same as the data with the cached algorithm * state from the previous calls. Percentile does this by checking the array reference * itself and a checksum of its content by default. If the user already knows he calls * {@code evaluate} on an immutable array, he can save the checking time by calling the * {@code evaluate} methods that do not *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Percentile extends AbstractUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -8091216485095130416L; /** Minimum size under which we use a simple insertion sort rather than Hoare's select. */ private static final int MIN_SELECT_SIZE = 15; /** Maximum number of partitioning pivots cached (each level double the number of pivots). */ private static final int MAX_CACHED_LEVELS = 10; /** Determines what percentile is computed when evaluate() is activated * with no quantile argument */ private double quantile = 0.0; /** Cached pivots. */ private int[] cachedPivots; /** * Constructs a Percentile with a default quantile * value of 50.0. */ public Percentile() { this(50.0); } /** * Constructs a Percentile with the specific quantile value. * @param p the quantile * @throws IllegalArgumentException if p is not greater than 0 and less * than or equal to 100 */ public Percentile(final double p) { setQuantile(p); cachedPivots = null; } /** * Copy constructor, creates a new {@code Percentile} identical * to the {@code original} * * @param original the {@code Percentile} instance to copy */ public Percentile(Percentile original) { copy(original, this); } /** {@inheritDoc} */ @Override public void setData(final double[] values) { if (values == null) { cachedPivots = null; } else { cachedPivots = new int[(0x1 << MAX_CACHED_LEVELS) - 1]; Arrays.fill(cachedPivots, -1); } super.setData(values); } /** {@inheritDoc} */ @Override public void setData(final double[] values, final int begin, final int length) { if (values == null) { cachedPivots = null; } else { cachedPivots = new int[(0x1 << MAX_CACHED_LEVELS) - 1]; Arrays.fill(cachedPivots, -1); } super.setData(values, begin, length); } /** * Returns the result of evaluating the statistic over the stored data. *

                    * The stored array is the one which was set by previous calls to *

                    * @param p the percentile value to compute * @return the value of the statistic applied to the stored data */ public double evaluate(final double p) { return evaluate(getDataRef(), p); } /** * Returns an estimate of the pth percentile of the values * in the values array. *

                    * Calls to this method do not modify the internal quantile * state of this statistic.

                    *

                    *

                      *
                    • Returns Double.NaN if values has length * 0
                    • *
                    • Returns (for any value of p) values[0] * if values has length 1
                    • *
                    • Throws IllegalArgumentException if values * is null or p is not a valid quantile value (p must be greater than 0 * and less than or equal to 100)
                    • *

                    *

                    * See {@link Percentile} for a description of the percentile estimation * algorithm used.

                    * * @param values input array of values * @param p the percentile value to compute * @return the percentile value or Double.NaN if the array is empty * @throws IllegalArgumentException if values is null * or p is invalid */ public double evaluate(final double[] values, final double p) { test(values, 0, 0); return evaluate(values, 0, values.length, p); } /** * Returns an estimate of the quantileth percentile of the * designated values in the values array. The quantile * estimated is determined by the quantile property. *

                    *

                      *
                    • Returns Double.NaN if length = 0
                    • *
                    • Returns (for any value of quantile) * values[begin] if length = 1
                    • *
                    • Throws IllegalArgumentException if values * is null, or start or length * is invalid
                    • *

                    *

                    * See {@link Percentile} for a description of the percentile estimation * algorithm used.

                    * * @param values the input array * @param start index of the first array element to include * @param length the number of elements to include * @return the percentile value * @throws IllegalArgumentException if the parameters are not valid * */ @Override public double evaluate( final double[] values, final int start, final int length) { return evaluate(values, start, length, quantile); } /** * Returns an estimate of the pth percentile of the values * in the values array, starting with the element in (0-based) * position begin in the array and including length * values. *

                    * Calls to this method do not modify the internal quantile * state of this statistic.

                    *

                    *

                      *
                    • Returns Double.NaN if length = 0
                    • *
                    • Returns (for any value of p) values[begin] * if length = 1
                    • *
                    • Throws IllegalArgumentException if values * is null , begin or length is invalid, or * p is not a valid quantile value (p must be greater than 0 * and less than or equal to 100)
                    • *

                    *

                    * See {@link Percentile} for a description of the percentile estimation * algorithm used.

                    * * @param values array of input values * @param p the percentile to compute * @param begin the first (0-based) element to include in the computation * @param length the number of array elements to include * @return the percentile value * @throws IllegalArgumentException if the parameters are not valid or the * input array is null */ public double evaluate(final double[] values, final int begin, final int length, final double p) { test(values, begin, length); if ((p > 100) || (p <= 0)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, p); } if (length == 0) { return Double.NaN; } if (length == 1) { return values[begin]; // always return single value for n = 1 } double n = length; double pos = p * (n + 1) / 100; double fpos = FastMath.floor(pos); int intPos = (int) fpos; double dif = pos - fpos; double[] work; int[] pivotsHeap; if (values == getDataRef()) { work = getDataRef(); pivotsHeap = cachedPivots; } else { work = new double[length]; System.arraycopy(values, begin, work, 0, length); pivotsHeap = new int[(0x1 << MAX_CACHED_LEVELS) - 1]; Arrays.fill(pivotsHeap, -1); } if (pos < 1) { return select(work, pivotsHeap, 0); } if (pos >= n) { return select(work, pivotsHeap, length - 1); } double lower = select(work, pivotsHeap, intPos - 1); double upper = select(work, pivotsHeap, intPos); return lower + dif * (upper - lower); } /** * Select the kth smallest element from work array * @param work work array (will be reorganized during the call) * @param pivotsHeap set of pivot index corresponding to elements that * are already at their sorted location, stored as an implicit heap * (i.e. a sorted binary tree stored in a flat array, where the * children of a node at index n are at indices 2n+1 for the left * child and 2n+2 for the right child, with 0-based indices) * @param k index of the desired element * @return kth smallest element */ private double select(final double[] work, final int[] pivotsHeap, final int k) { int begin = 0; int end = work.length; int node = 0; while (end - begin > MIN_SELECT_SIZE) { final int pivot; if ((node < pivotsHeap.length) && (pivotsHeap[node] >= 0)) { // the pivot has already been found in a previous call // and the array has already been partitioned around it pivot = pivotsHeap[node]; } else { // select a pivot and partition work array around it pivot = partition(work, begin, end, medianOf3(work, begin, end)); if (node < pivotsHeap.length) { pivotsHeap[node] = pivot; } } if (k == pivot) { // the pivot was exactly the element we wanted return work[k]; } else if (k < pivot) { // the element is in the left partition end = pivot; node = Math.min(2 * node + 1, pivotsHeap.length); // the min is here to avoid integer overflow } else { // the element is in the right partition begin = pivot + 1; node = Math.min(2 * node + 2, pivotsHeap.length); // the min is here to avoid integer overflow } } // the element is somewhere in the small sub-array // sort the sub-array using insertion sort insertionSort(work, begin, end); return work[k]; } /** Select a pivot index as the median of three * @param work data array * @param begin index of the first element of the slice * @param end index after the last element of the slice * @return the index of the median element chosen between the * first, the middle and the last element of the array slice */ int medianOf3(final double[] work, final int begin, final int end) { final int inclusiveEnd = end - 1; final int middle = begin + (inclusiveEnd - begin) / 2; final double wBegin = work[begin]; final double wMiddle = work[middle]; final double wEnd = work[inclusiveEnd]; if (wBegin < wMiddle) { if (wMiddle < wEnd) { return middle; } else { return (wBegin < wEnd) ? inclusiveEnd : begin; } } else { if (wBegin < wEnd) { return begin; } else { return (wMiddle < wEnd) ? inclusiveEnd : middle; } } } /** * Partition an array slice around a pivot *

                    * Partitioning exchanges array elements such that all elements * smaller than pivot are before it and all elements larger than * pivot are after it *

                    * @param work data array * @param begin index of the first element of the slice * @param end index after the last element of the slice * @param pivot initial index of the pivot * @return index of the pivot after partition */ private int partition(final double[] work, final int begin, final int end, final int pivot) { final double value = work[pivot]; work[pivot] = work[begin]; int i = begin + 1; int j = end - 1; while (i < j) { while ((i < j) && (work[j] >= value)) { --j; } while ((i < j) && (work[i] <= value)) { ++i; } if (i < j) { final double tmp = work[i]; work[i++] = work[j]; work[j--] = tmp; } } if ((i >= end) || (work[i] > value)) { --i; } work[begin] = work[i]; work[i] = value; return i; } /** * Sort in place a (small) array slice using insertion sort * @param work array to sort * @param begin index of the first element of the slice to sort * @param end index after the last element of the slice to sort */ private void insertionSort(final double[] work, final int begin, final int end) { for (int j = begin + 1; j < end; j++) { final double saved = work[j]; int i = j - 1; while ((i >= begin) && (saved < work[i])) { work[i + 1] = work[i]; i--; } work[i + 1] = saved; } } /** * Returns the value of the quantile field (determines what percentile is * computed when evaluate() is called with no quantile argument). * * @return quantile */ public double getQuantile() { return quantile; } /** * Sets the value of the quantile field (determines what percentile is * computed when evaluate() is called with no quantile argument). * * @param p a value between 0 < p <= 100 * @throws IllegalArgumentException if p is not greater than 0 and less * than or equal to 100 */ public void setQuantile(final double p) { if (p <= 0 || p > 100) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, p); } quantile = p; } /** * {@inheritDoc} */ @Override public Percentile copy() { Percentile result = new Percentile(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Percentile to copy * @param dest Percentile to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Percentile source, Percentile dest) { dest.setData(source.getDataRef()); if (source.cachedPivots != null) { System.arraycopy(source.cachedPivots, 0, dest.cachedPivots, 0, source.cachedPivots.length); } dest.quantile = source.quantile; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/Min.java100644 1750 1750 11600 11532241246 30200 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Returns the minimum of the available values. *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.NEGATIVE_INFINITY, * the result is Double.NEGATIVE_INFINITY.
                    • *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Min extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -2941995784909003131L; /**Number of values that have been added */ private long n; /**Current value of the statistic */ private double value; /** * Create a Min instance */ public Min() { n = 0; value = Double.NaN; } /** * Copy constructor, creates a new {@code Min} identical * to the {@code original} * * @param original the {@code Min} instance to copy */ public Min(Min original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (d < value || Double.isNaN(value)) { value = d; } n++; } /** * {@inheritDoc} */ @Override public void clear() { value = Double.NaN; n = 0; } /** * {@inheritDoc} */ @Override public double getResult() { return value; } /** * {@inheritDoc} */ public long getN() { return n; } /** * Returns the minimum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null or * the array index parameters are not valid.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.NEGATIVE_INFINITY, * the result is Double.NEGATIVE_INFINITY.
                    • *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the minimum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values,final int begin, final int length) { double min = Double.NaN; if (test(values, begin, length)) { min = values[begin]; for (int i = begin; i < begin + length; i++) { if (!Double.isNaN(values[i])) { min = (min < values[i]) ? min : values[i]; } } } return min; } /** * {@inheritDoc} */ @Override public Min copy() { Min result = new Min(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Min to copy * @param dest Min to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Min source, Min dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.value = source.value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/Median.java100644 1750 1750 3654 11532241246 30644 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.rank; import java.io.Serializable; /** * Returns the median of the available values. This is the same as the 50th percentile. * See {@link Percentile} for a description of the algorithm used. *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class Median extends Percentile implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -3961477041290915687L; /** * Default constructor. */ public Median() { super(50.0); } /** * Copy constructor, creates a new {@code Median} identical * to the {@code original} * * @param original the {@code Median} instance to copy */ public Median(Median original) { super(original); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/rank/package.html100644 1750 1750 1670 11532241246 31061 0ustarlucluc 0 0 Summary statistics based on ranks. ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStati100644 1750 1750 56627 11532241247 32656 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.stat.descriptive.moment.GeometricMean; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance; import org.apache.commons.math.stat.descriptive.rank.Max; import org.apache.commons.math.stat.descriptive.rank.Min; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** *

                    Computes summary statistics for a stream of n-tuples added using the * {@link #addValue(double[]) addValue} method. The data values are not stored * in memory, so this class can be used to compute statistics for very large * n-tuple streams.

                    * *

                    The {@link StorelessUnivariateStatistic} instances used to maintain * summary state and compute statistics are configurable via setters. * For example, the default implementation for the mean can be overridden by * calling {@link #setMeanImpl(StorelessUnivariateStatistic[])}. Actual * parameters to these methods must implement the * {@link StorelessUnivariateStatistic} interface and configuration must be * completed before addValue is called. No configuration is * necessary to use the default, commons-math provided implementations.

                    * *

                    To compute statistics for a stream of n-tuples, construct a * MultivariateStatistics instance with dimension n and then use * {@link #addValue(double[])} to add n-tuples. The getXxx * methods where Xxx is a statistic return an array of double * values, where for i = 0,...,n-1 the ith array element is the * value of the given statistic for data range consisting of the ith element of * each of the input n-tuples. For example, if addValue is called * with actual parameters {0, 1, 2}, then {3, 4, 5} and finally {6, 7, 8}, * getSum will return a three-element array with values * {0+3+6, 1+4+7, 2+5+8}

                    * *

                    Note: This class is not thread-safe. Use * {@link SynchronizedMultivariateSummaryStatistics} if concurrent access from multiple * threads is required.

                    * * @since 1.2 * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ public class MultivariateSummaryStatistics implements StatisticalMultivariateSummary, Serializable { /** Serialization UID */ private static final long serialVersionUID = 2271900808994826718L; /** Dimension of the data. */ private int k; /** Count of values that have been added */ private long n = 0; /** Sum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] sumImpl; /** Sum of squares statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] sumSqImpl; /** Minimum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] minImpl; /** Maximum statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] maxImpl; /** Sum of log statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] sumLogImpl; /** Geometric mean statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] geoMeanImpl; /** Mean statistic implementation - can be reset by setter. */ private StorelessUnivariateStatistic[] meanImpl; /** Covariance statistic implementation - cannot be reset. */ private VectorialCovariance covarianceImpl; /** * Construct a MultivariateSummaryStatistics instance * @param k dimension of the data * @param isCovarianceBiasCorrected if true, the unbiased sample * covariance is computed, otherwise the biased population covariance * is computed */ public MultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { this.k = k; sumImpl = new StorelessUnivariateStatistic[k]; sumSqImpl = new StorelessUnivariateStatistic[k]; minImpl = new StorelessUnivariateStatistic[k]; maxImpl = new StorelessUnivariateStatistic[k]; sumLogImpl = new StorelessUnivariateStatistic[k]; geoMeanImpl = new StorelessUnivariateStatistic[k]; meanImpl = new StorelessUnivariateStatistic[k]; for (int i = 0; i < k; ++i) { sumImpl[i] = new Sum(); sumSqImpl[i] = new SumOfSquares(); minImpl[i] = new Min(); maxImpl[i] = new Max(); sumLogImpl[i] = new SumOfLogs(); geoMeanImpl[i] = new GeometricMean(); meanImpl[i] = new Mean(); } covarianceImpl = new VectorialCovariance(k, isCovarianceBiasCorrected); } /** * Add an n-tuple to the data * * @param value the n-tuple to add * @throws DimensionMismatchException if the length of the array * does not match the one used at construction */ public void addValue(double[] value) throws DimensionMismatchException { checkDimension(value.length); for (int i = 0; i < k; ++i) { double v = value[i]; sumImpl[i].increment(v); sumSqImpl[i].increment(v); minImpl[i].increment(v); maxImpl[i].increment(v); sumLogImpl[i].increment(v); geoMeanImpl[i].increment(v); meanImpl[i].increment(v); } covarianceImpl.increment(value); n++; } /** * Returns the dimension of the data * @return The dimension of the data */ public int getDimension() { return k; } /** * Returns the number of available values * @return The number of available values */ public long getN() { return n; } /** * Returns an array of the results of a statistic. * @param stats univariate statistic array * @return results array */ private double[] getResults(StorelessUnivariateStatistic[] stats) { double[] results = new double[stats.length]; for (int i = 0; i < results.length; ++i) { results[i] = stats[i].getResult(); } return results; } /** * Returns an array whose ith entry is the sum of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component sums */ public double[] getSum() { return getResults(sumImpl); } /** * Returns an array whose ith entry is the sum of squares of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component sums of squares */ public double[] getSumSq() { return getResults(sumSqImpl); } /** * Returns an array whose ith entry is the sum of logs of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component log sums */ public double[] getSumLog() { return getResults(sumLogImpl); } /** * Returns an array whose ith entry is the mean of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component means */ public double[] getMean() { return getResults(meanImpl); } /** * Returns an array whose ith entry is the standard deviation of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component standard deviations */ public double[] getStandardDeviation() { double[] stdDev = new double[k]; if (getN() < 1) { Arrays.fill(stdDev, Double.NaN); } else if (getN() < 2) { Arrays.fill(stdDev, 0.0); } else { RealMatrix matrix = covarianceImpl.getResult(); for (int i = 0; i < k; ++i) { stdDev[i] = FastMath.sqrt(matrix.getEntry(i, i)); } } return stdDev; } /** * Returns the covariance matrix of the values that have been added. * * @return the covariance matrix */ public RealMatrix getCovariance() { return covarianceImpl.getResult(); } /** * Returns an array whose ith entry is the maximum of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component maxima */ public double[] getMax() { return getResults(maxImpl); } /** * Returns an array whose ith entry is the minimum of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component minima */ public double[] getMin() { return getResults(minImpl); } /** * Returns an array whose ith entry is the geometric mean of the * ith entries of the arrays that have been added using * {@link #addValue(double[])} * * @return the array of component geometric means */ public double[] getGeometricMean() { return getResults(geoMeanImpl); } /** * Generates a text report displaying * summary statistics from values that * have been added. * @return String with line feeds displaying statistics */ @Override public String toString() { final String separator = ", "; final String suffix = System.getProperty("line.separator"); StringBuilder outBuffer = new StringBuilder(); outBuffer.append("MultivariateSummaryStatistics:" + suffix); outBuffer.append("n: " + getN() + suffix); append(outBuffer, getMin(), "min: ", separator, suffix); append(outBuffer, getMax(), "max: ", separator, suffix); append(outBuffer, getMean(), "mean: ", separator, suffix); append(outBuffer, getGeometricMean(), "geometric mean: ", separator, suffix); append(outBuffer, getSumSq(), "sum of squares: ", separator, suffix); append(outBuffer, getSumLog(), "sum of logarithms: ", separator, suffix); append(outBuffer, getStandardDeviation(), "standard deviation: ", separator, suffix); outBuffer.append("covariance: " + getCovariance().toString() + suffix); return outBuffer.toString(); } /** * Append a text representation of an array to a buffer. * @param buffer buffer to fill * @param data data array * @param prefix text prefix * @param separator elements separator * @param suffix text suffix */ private void append(StringBuilder buffer, double[] data, String prefix, String separator, String suffix) { buffer.append(prefix); for (int i = 0; i < data.length; ++i) { if (i > 0) { buffer.append(separator); } buffer.append(data[i]); } buffer.append(suffix); } /** * Resets all statistics and storage */ public void clear() { this.n = 0; for (int i = 0; i < k; ++i) { minImpl[i].clear(); maxImpl[i].clear(); sumImpl[i].clear(); sumLogImpl[i].clear(); sumSqImpl[i].clear(); geoMeanImpl[i].clear(); meanImpl[i].clear(); } covarianceImpl.clear(); } /** * Returns true iff object is a MultivariateSummaryStatistics * instance and all statistics have the same values as this. * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(Object object) { if (object == this ) { return true; } if (object instanceof MultivariateSummaryStatistics == false) { return false; } MultivariateSummaryStatistics stat = (MultivariateSummaryStatistics) object; return MathUtils.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) && MathUtils.equalsIncludingNaN(stat.getMax(), getMax()) && MathUtils.equalsIncludingNaN(stat.getMean(), getMean()) && MathUtils.equalsIncludingNaN(stat.getMin(), getMin()) && MathUtils.equalsIncludingNaN(stat.getN(), getN()) && MathUtils.equalsIncludingNaN(stat.getSum(), getSum()) && MathUtils.equalsIncludingNaN(stat.getSumSq(), getSumSq()) && MathUtils.equalsIncludingNaN(stat.getSumLog(), getSumLog()) && stat.getCovariance().equals( getCovariance()); } /** * Returns hash code based on values of statistics * * @return hash code */ @Override public int hashCode() { int result = 31 + MathUtils.hash(getGeometricMean()); result = result * 31 + MathUtils.hash(getGeometricMean()); result = result * 31 + MathUtils.hash(getMax()); result = result * 31 + MathUtils.hash(getMean()); result = result * 31 + MathUtils.hash(getMin()); result = result * 31 + MathUtils.hash(getN()); result = result * 31 + MathUtils.hash(getSum()); result = result * 31 + MathUtils.hash(getSumSq()); result = result * 31 + MathUtils.hash(getSumLog()); result = result * 31 + getCovariance().hashCode(); return result; } // Getters and setters for statistics implementations /** * Sets statistics implementations. * @param newImpl new implementations for statistics * @param oldImpl old implementations for statistics * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ private void setImpl(StorelessUnivariateStatistic[] newImpl, StorelessUnivariateStatistic[] oldImpl) throws DimensionMismatchException, IllegalStateException { checkEmpty(); checkDimension(newImpl.length); System.arraycopy(newImpl, 0, oldImpl, 0, newImpl.length); } /** * Returns the currently configured Sum implementation * * @return the StorelessUnivariateStatistic implementing the sum */ public StorelessUnivariateStatistic[] getSumImpl() { return sumImpl.clone(); } /** *

                    Sets the implementation for the Sum.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param sumImpl the StorelessUnivariateStatistic instance to use * for computing the Sum * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setSumImpl(StorelessUnivariateStatistic[] sumImpl) throws DimensionMismatchException { setImpl(sumImpl, this.sumImpl); } /** * Returns the currently configured sum of squares implementation * * @return the StorelessUnivariateStatistic implementing the sum of squares */ public StorelessUnivariateStatistic[] getSumsqImpl() { return sumSqImpl.clone(); } /** *

                    Sets the implementation for the sum of squares.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param sumsqImpl the StorelessUnivariateStatistic instance to use * for computing the sum of squares * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) throws DimensionMismatchException { setImpl(sumsqImpl, this.sumSqImpl); } /** * Returns the currently configured minimum implementation * * @return the StorelessUnivariateStatistic implementing the minimum */ public StorelessUnivariateStatistic[] getMinImpl() { return minImpl.clone(); } /** *

                    Sets the implementation for the minimum.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param minImpl the StorelessUnivariateStatistic instance to use * for computing the minimum * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setMinImpl(StorelessUnivariateStatistic[] minImpl) throws DimensionMismatchException { setImpl(minImpl, this.minImpl); } /** * Returns the currently configured maximum implementation * * @return the StorelessUnivariateStatistic implementing the maximum */ public StorelessUnivariateStatistic[] getMaxImpl() { return maxImpl.clone(); } /** *

                    Sets the implementation for the maximum.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param maxImpl the StorelessUnivariateStatistic instance to use * for computing the maximum * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) throws DimensionMismatchException { setImpl(maxImpl, this.maxImpl); } /** * Returns the currently configured sum of logs implementation * * @return the StorelessUnivariateStatistic implementing the log sum */ public StorelessUnivariateStatistic[] getSumLogImpl() { return sumLogImpl.clone(); } /** *

                    Sets the implementation for the sum of logs.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param sumLogImpl the StorelessUnivariateStatistic instance to use * for computing the log sum * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) throws DimensionMismatchException { setImpl(sumLogImpl, this.sumLogImpl); } /** * Returns the currently configured geometric mean implementation * * @return the StorelessUnivariateStatistic implementing the geometric mean */ public StorelessUnivariateStatistic[] getGeoMeanImpl() { return geoMeanImpl.clone(); } /** *

                    Sets the implementation for the geometric mean.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param geoMeanImpl the StorelessUnivariateStatistic instance to use * for computing the geometric mean * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) throws DimensionMismatchException { setImpl(geoMeanImpl, this.geoMeanImpl); } /** * Returns the currently configured mean implementation * * @return the StorelessUnivariateStatistic implementing the mean */ public StorelessUnivariateStatistic[] getMeanImpl() { return meanImpl.clone(); } /** *

                    Sets the implementation for the mean.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #addValue(double[]) addValue} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param meanImpl the StorelessUnivariateStatistic instance to use * for computing the mean * @throws DimensionMismatchException if the array dimension * does not match the one used at construction * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) throws DimensionMismatchException { setImpl(meanImpl, this.meanImpl); } /** * Throws IllegalStateException if n > 0. */ private void checkEmpty() { if (n > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC, n); } } /** * Throws DimensionMismatchException if dimension != k. * @param dimension dimension to check * @throws DimensionMismatchException if dimension != k */ private void checkDimension(int dimension) throws DimensionMismatchException { if (dimension != k) { throw new DimensionMismatchException(dimension, k); } } } ././@LongLink100644 0 0 166 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivari100644 1750 1750 15436 11532241247 32623 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.util.MathUtils; /** * * Abstract implementation of the {@link StorelessUnivariateStatistic} interface. *

                    * Provides default evaluate() and incrementAll(double[]) * implementations.

                    *

                    * Note that these implementations are not synchronized.

                    * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public abstract class AbstractStorelessUnivariateStatistic extends AbstractUnivariateStatistic implements StorelessUnivariateStatistic { /** * This default implementation calls {@link #clear}, then invokes * {@link #increment} in a loop over the the input array, and then uses * {@link #getResult} to compute the return value. *

                    * Note that this implementation changes the internal state of the * statistic. Its side effects are the same as invoking {@link #clear} and * then {@link #incrementAll(double[])}.

                    *

                    * Implementations may override this method with a more efficient and * possibly more accurate implementation that works directly with the * input array.

                    *

                    * If the array is null, an IllegalArgumentException is thrown.

                    * @param values input array * @return the value of the statistic applied to the input array * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[]) */ @Override public double evaluate(final double[] values) { if (values == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } return evaluate(values, 0, values.length); } /** * This default implementation calls {@link #clear}, then invokes * {@link #increment} in a loop over the specified portion of the input * array, and then uses {@link #getResult} to compute the return value. *

                    * Note that this implementation changes the internal state of the * statistic. Its side effects are the same as invoking {@link #clear} and * then {@link #incrementAll(double[], int, int)}.

                    *

                    * Implementations may override this method with a more efficient and * possibly more accurate implementation that works directly with the * input array.

                    *

                    * If the array is null or the index parameters are not valid, an * IllegalArgumentException is thrown.

                    * @param values the input array * @param begin the index of the first element to include * @param length the number of elements to include * @return the value of the statistic applied to the included array entries * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[], int, int) */ @Override public double evaluate(final double[] values, final int begin, final int length) { if (test(values, begin, length)) { clear(); incrementAll(values, begin, length); } return getResult(); } /** * {@inheritDoc} */ @Override public abstract StorelessUnivariateStatistic copy(); /** * {@inheritDoc} */ public abstract void clear(); /** * {@inheritDoc} */ public abstract double getResult(); /** * {@inheritDoc} */ public abstract void increment(final double d); /** * This default implementation just calls {@link #increment} in a loop over * the input array. *

                    * Throws IllegalArgumentException if the input values array is null.

                    * * @param values values to add * @throws IllegalArgumentException if values is null * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[]) */ public void incrementAll(double[] values) { if (values == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } incrementAll(values, 0, values.length); } /** * This default implementation just calls {@link #increment} in a loop over * the specified portion of the input array. *

                    * Throws IllegalArgumentException if the input values array is null.

                    * * @param values array holding values to add * @param begin index of the first array element to add * @param length number of array elements to add * @throws IllegalArgumentException if values is null * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[], int, int) */ public void incrementAll(double[] values, int begin, int length) { if (test(values, begin, length)) { int k = begin + length; for (int i = begin; i < k; i++) { increment(values[i]); } } } /** * Returns true iff object is an * AbstractStorelessUnivariateStatistic returning the same * values as this for getResult() and getN() * @param object object to test equality against. * @return true if object returns the same value as this */ @Override public boolean equals(Object object) { if (object == this ) { return true; } if (object instanceof AbstractStorelessUnivariateStatistic == false) { return false; } AbstractStorelessUnivariateStatistic stat = (AbstractStorelessUnivariateStatistic) object; return MathUtils.equalsIncludingNaN(stat.getResult(), this.getResult()) && MathUtils.equalsIncludingNaN(stat.getN(), this.getN()); } /** * Returns hash code based on getResult() and getN() * * @return hash code */ @Override public int hashCode() { return 31* (31 + MathUtils.hash(getResult())) + MathUtils.hash(getN()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/package.html100644 1750 1750 4440 11532241247 30125 0ustarlucluc 0 0 Generic univariate summary statistic objects.

                    UnivariateStatistic API Usage Examples:

                    UnivariateStatistic:

                    /* evaluation approach */
                    double[] values = new double[] { 1, 2, 3, 4, 5 };
                    UnivariateStatistic stat = new Mean();
                    System.out.println("mean = " + stat.evaluate(values));

                    StorelessUnivariateStatistic:

                    /* incremental approach */
                    double[] values = new double[] { 1, 2, 3, 4, 5 };
                    StorelessUnivariateStatistic stat = new Mean();
                    System.out.println("mean before adding a value is NaN = " + stat.getResult());
                    for (int i = 0; i < values.length; i++) {
                        stat.increment(values[i]);
                        System.out.println("current mean = " + stat2.getResult());
                    }
                    stat.clear();
                    System.out.println("mean after clear is NaN = " + stat.getResult());
                    ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatisti100644 1750 1750 35372 11532241247 32610 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; /** *

                    * An aggregator for {@code SummaryStatistics} from several data sets or * data set partitions. In its simplest usage mode, the client creates an * instance via the zero-argument constructor, then uses * {@link #createContributingStatistics()} to obtain a {@code SummaryStatistics} * for each individual data set / partition. The per-set statistics objects * are used as normal, and at any time the aggregate statistics for all the * contributors can be obtained from this object. *

                    * Clients with specialized requirements can use alternative constructors to * control the statistics implementations and initial values used by the * contributing and the internal aggregate {@code SummaryStatistics} objects. *

                    * A static {@link #aggregate(Collection)} method is also included that computes * aggregate statistics directly from a Collection of SummaryStatistics instances. *

                    * When {@link #createContributingStatistics()} is used to create SummaryStatistics * instances to be aggregated concurrently, the created instances' * {@link SummaryStatistics#addValue(double)} methods must synchronize on the aggregating * instance maintained by this class. In multithreaded environments, if the functionality * provided by {@link #aggregate(Collection)} is adequate, that method should be used * to avoid unecessary computation and synchronization delays.

                    * * @since 2.0 * @version $Revision: 811833 $ $Date: 2009-09-06 18:27:50 +0200 (dim. 06 sept. 2009) $ * */ public class AggregateSummaryStatistics implements StatisticalSummary, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -8207112444016386906L; /** * A SummaryStatistics serving as a prototype for creating SummaryStatistics * contributing to this aggregate */ private final SummaryStatistics statisticsPrototype; /** * The SummaryStatistics in which aggregate statistics are accumulated. */ private final SummaryStatistics statistics; /** * Initializes a new AggregateSummaryStatistics with default statistics * implementations. * */ public AggregateSummaryStatistics() { this(new SummaryStatistics()); } /** * Initializes a new AggregateSummaryStatistics with the specified statistics * object as a prototype for contributing statistics and for the internal * aggregate statistics. This provides for customized statistics implementations * to be used by contributing and aggregate statistics. * * @param prototypeStatistics a {@code SummaryStatistics} serving as a * prototype both for the internal aggregate statistics and for * contributing statistics obtained via the * {@code createContributingStatistics()} method. Being a prototype * means that other objects are initialized by copying this object's state. * If {@code null}, a new, default statistics object is used. Any statistic * values in the prototype are propagated to contributing statistics * objects and (once) into these aggregate statistics. * @see #createContributingStatistics() */ public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics) { this(prototypeStatistics, prototypeStatistics == null ? null : new SummaryStatistics(prototypeStatistics)); } /** * Initializes a new AggregateSummaryStatistics with the specified statistics * object as a prototype for contributing statistics and for the internal * aggregate statistics. This provides for different statistics implementations * to be used by contributing and aggregate statistics and for an initial * state to be supplied for the aggregate statistics. * * @param prototypeStatistics a {@code SummaryStatistics} serving as a * prototype both for the internal aggregate statistics and for * contributing statistics obtained via the * {@code createContributingStatistics()} method. Being a prototype * means that other objects are initialized by copying this object's state. * If {@code null}, a new, default statistics object is used. Any statistic * values in the prototype are propagated to contributing statistics * objects, but not into these aggregate statistics. * @param initialStatistics a {@code SummaryStatistics} to serve as the * internal aggregate statistics object. If {@code null}, a new, default * statistics object is used. * @see #createContributingStatistics() */ public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics, SummaryStatistics initialStatistics) { this.statisticsPrototype = (prototypeStatistics == null) ? new SummaryStatistics() : prototypeStatistics; this.statistics = (initialStatistics == null) ? new SummaryStatistics() : initialStatistics; } /** * {@inheritDoc}. This version returns the maximum over all the aggregated * data. * * @see StatisticalSummary#getMax() */ public double getMax() { synchronized (statistics) { return statistics.getMax(); } } /** * {@inheritDoc}. This version returns the mean of all the aggregated data. * * @see StatisticalSummary#getMean() */ public double getMean() { synchronized (statistics) { return statistics.getMean(); } } /** * {@inheritDoc}. This version returns the minimum over all the aggregated * data. * * @see StatisticalSummary#getMin() */ public double getMin() { synchronized (statistics) { return statistics.getMin(); } } /** * {@inheritDoc}. This version returns a count of all the aggregated data. * * @see StatisticalSummary#getN() */ public long getN() { synchronized (statistics) { return statistics.getN(); } } /** * {@inheritDoc}. This version returns the standard deviation of all the * aggregated data. * * @see StatisticalSummary#getStandardDeviation() */ public double getStandardDeviation() { synchronized (statistics) { return statistics.getStandardDeviation(); } } /** * {@inheritDoc}. This version returns a sum of all the aggregated data. * * @see StatisticalSummary#getSum() */ public double getSum() { synchronized (statistics) { return statistics.getSum(); } } /** * {@inheritDoc}. This version returns the variance of all the aggregated * data. * * @see StatisticalSummary#getVariance() */ public double getVariance() { synchronized (statistics) { return statistics.getVariance(); } } /** * Returns the sum of the logs of all the aggregated data. * * @return the sum of logs * @see SummaryStatistics#getSumOfLogs() */ public double getSumOfLogs() { synchronized (statistics) { return statistics.getSumOfLogs(); } } /** * Returns the geometric mean of all the aggregated data. * * @return the geometric mean * @see SummaryStatistics#getGeometricMean() */ public double getGeometricMean() { synchronized (statistics) { return statistics.getGeometricMean(); } } /** * Returns the sum of the squares of all the aggregated data. * * @return The sum of squares * @see SummaryStatistics#getSumsq() */ public double getSumsq() { synchronized (statistics) { return statistics.getSumsq(); } } /** * Returns a statistic related to the Second Central Moment. Specifically, * what is returned is the sum of squared deviations from the sample mean * among the all of the aggregated data. * * @return second central moment statistic * @see SummaryStatistics#getSecondMoment() */ public double getSecondMoment() { synchronized (statistics) { return statistics.getSecondMoment(); } } /** * Return a {@link StatisticalSummaryValues} instance reporting current * aggregate statistics. * * @return Current values of aggregate statistics */ public StatisticalSummary getSummary() { synchronized (statistics) { return new StatisticalSummaryValues(getMean(), getVariance(), getN(), getMax(), getMin(), getSum()); } } /** * Creates and returns a {@code SummaryStatistics} whose data will be * aggregated with those of this {@code AggregateSummaryStatistics}. * * @return a {@code SummaryStatistics} whose data will be aggregated with * those of this {@code AggregateSummaryStatistics}. The initial state * is a copy of the configured prototype statistics. */ public SummaryStatistics createContributingStatistics() { SummaryStatistics contributingStatistics = new AggregatingSummaryStatistics(statistics); SummaryStatistics.copy(statisticsPrototype, contributingStatistics); return contributingStatistics; } /** * Computes aggregate summary statistics. This method can be used to combine statistics * computed over partitions or subsamples - i.e., the StatisticalSummaryValues returned * should contain the same values that would have been obtained by computing a single * StatisticalSummary over the combined dataset. *

                    * Returns null if the collection is empty or null. *

                    * * @param statistics collection of SummaryStatistics to aggregate * @return summary statistics for the combined dataset */ public static StatisticalSummaryValues aggregate(Collection statistics) { if (statistics == null) { return null; } Iterator iterator = statistics.iterator(); if (!iterator.hasNext()) { return null; } SummaryStatistics current = iterator.next(); long n = current.getN(); double min = current.getMin(); double sum = current.getSum(); double max = current.getMax(); double m2 = current.getSecondMoment(); double mean = current.getMean(); while (iterator.hasNext()) { current = iterator.next(); if (current.getMin() < min || Double.isNaN(min)) { min = current.getMin(); } if (current.getMax() > max || Double.isNaN(max)) { max = current.getMax(); } sum += current.getSum(); final double oldN = n; final double curN = current.getN(); n += curN; final double meanDiff = current.getMean() - mean; mean = sum / n; m2 = m2 + current.getSecondMoment() + meanDiff * meanDiff * oldN * curN / n; } final double variance; if (n == 0) { variance = Double.NaN; } else if (n == 1) { variance = 0d; } else { variance = m2 / (n - 1); } return new StatisticalSummaryValues(mean, variance, n, max, min, sum); } /** * A SummaryStatistics that also forwards all values added to it to a second * {@code SummaryStatistics} for aggregation. * * @since 2.0 */ private static class AggregatingSummaryStatistics extends SummaryStatistics { /** * The serialization version of this class */ private static final long serialVersionUID = 1L; /** * An additional SummaryStatistics into which values added to these * statistics (and possibly others) are aggregated */ private final SummaryStatistics aggregateStatistics; /** * Initializes a new AggregatingSummaryStatistics with the specified * aggregate statistics object * * @param aggregateStatistics a {@code SummaryStatistics} into which * values added to this statistics object should be aggregated */ public AggregatingSummaryStatistics(SummaryStatistics aggregateStatistics) { this.aggregateStatistics = aggregateStatistics; } /** * {@inheritDoc}. This version adds the provided value to the configured * aggregate after adding it to these statistics. * * @see SummaryStatistics#addValue(double) */ @Override public void addValue(double value) { super.addValue(value); synchronized (aggregateStatistics) { aggregateStatistics.addValue(value); } } /** * Returns true iff object is a * SummaryStatistics instance and all statistics have the * same values as this. * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(Object object) { if (object == this) { return true; } if (object instanceof AggregatingSummaryStatistics == false) { return false; } AggregatingSummaryStatistics stat = (AggregatingSummaryStatistics)object; return super.equals(stat) && aggregateStatistics.equals(stat.aggregateStatistics); } /** * Returns hash code based on values of statistics * @return hash code */ @Override public int hashCode() { return 123 + super.hashCode() + aggregateStatistics.hashCode(); } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/GeometricMean.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/GeometricMean.jav100644 1750 1750 15030 11532241247 32401 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; import org.apache.commons.math.util.FastMath; /** * Returns the * geometric mean of the available values. *

                    * Uses a {@link SumOfLogs} instance to compute sum of logs and returns * exp( 1/n (sum of logs) ). Therefore,

                    *
                      *
                    • If any of values are < 0, the result is NaN.
                    • *
                    • If all values are non-negative and less than * Double.POSITIVE_INFINITY, but at least one value is 0, the * result is 0.
                    • *
                    • If both Double.POSITIVE_INFINITY and * Double.NEGATIVE_INFINITY are among the values, the result is * NaN.
                    • *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class GeometricMean extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -8178734905303459453L; /** Wrapped SumOfLogs instance */ private StorelessUnivariateStatistic sumOfLogs; /** * Create a GeometricMean instance */ public GeometricMean() { sumOfLogs = new SumOfLogs(); } /** * Copy constructor, creates a new {@code GeometricMean} identical * to the {@code original} * * @param original the {@code GeometricMean} instance to copy */ public GeometricMean(GeometricMean original) { super(); copy(original, this); } /** * Create a GeometricMean instance using the given SumOfLogs instance * @param sumOfLogs sum of logs instance to use for computation */ public GeometricMean(SumOfLogs sumOfLogs) { this.sumOfLogs = sumOfLogs; } /** * {@inheritDoc} */ @Override public GeometricMean copy() { GeometricMean result = new GeometricMean(); copy(this, result); return result; } /** * {@inheritDoc} */ @Override public void increment(final double d) { sumOfLogs.increment(d); } /** * {@inheritDoc} */ @Override public double getResult() { if (sumOfLogs.getN() > 0) { return FastMath.exp(sumOfLogs.getResult() / sumOfLogs.getN()); } else { return Double.NaN; } } /** * {@inheritDoc} */ @Override public void clear() { sumOfLogs.clear(); } /** * Returns the geometric mean of the entries in the specified portion * of the input array. *

                    * See {@link GeometricMean} for details on the computing algorithm.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values input array containing the values * @param begin first array element to include * @param length the number of elements to include * @return the geometric mean or Double.NaN if length = 0 or * any of the values are <= 0. * @throws IllegalArgumentException if the input array is null or the array * index parameters are not valid */ @Override public double evaluate( final double[] values, final int begin, final int length) { return FastMath.exp( sumOfLogs.evaluate(values, begin, length) / length); } /** * {@inheritDoc} */ public long getN() { return sumOfLogs.getN(); } /** *

                    Sets the implementation for the sum of logs.

                    *

                    This method must be activated before any data has been added - i.e., * before {@link #increment(double) increment} has been used to add data; * otherwise an IllegalStateException will be thrown.

                    * * @param sumLogImpl the StorelessUnivariateStatistic instance to use * for computing the log sum * @throws IllegalStateException if data has already been added * (i.e if n > 0) */ public void setSumLogImpl( StorelessUnivariateStatistic sumLogImpl) { checkEmpty(); this.sumOfLogs = sumLogImpl; } /** * Returns the currently configured sum of logs implementation * * @return the StorelessUnivariateStatistic implementing the log sum */ public StorelessUnivariateStatistic getSumLogImpl() { return sumOfLogs; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source GeometricMean to copy * @param dest GeometricMean to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(GeometricMean source, GeometricMean dest) { dest.setData(source.getDataRef()); dest.sumOfLogs = source.sumOfLogs.copy(); } /** * Throws IllegalStateException if n > 0. */ private void checkEmpty() { if (getN() > 0) { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC, getN()); } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.jav100644 1750 1750 6152 11532241247 32400 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.DimensionMismatchException; /** * Returns the arithmetic mean of the available vectors. * @since 1.2 * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $ */ public class VectorialMean implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 8223009086481006892L; /** Means for each component. */ private final Mean[] means; /** Constructs a VectorialMean. * @param dimension vectors dimension */ public VectorialMean(int dimension) { means = new Mean[dimension]; for (int i = 0; i < dimension; ++i) { means[i] = new Mean(); } } /** * Add a new vector to the sample. * @param v vector to add * @exception DimensionMismatchException if the vector does not have the right dimension */ public void increment(double[] v) throws DimensionMismatchException { if (v.length != means.length) { throw new DimensionMismatchException(v.length, means.length); } for (int i = 0; i < v.length; ++i) { means[i].increment(v[i]); } } /** * Get the mean vector. * @return mean vector */ public double[] getResult() { double[] result = new double[means.length]; for (int i = 0; i < result.length; ++i) { result[i] = means[i].getResult(); } return result; } /** * Get the number of vectors in the sample. * @return number of vectors in the sample */ public long getN() { return (means.length == 0) ? 0 : means[0].getN(); } /** {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(means); return result; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof VectorialMean)) return false; VectorialMean other = (VectorialMean) obj; if (!Arrays.equals(means, other.means)) return false; return true; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/SecondMoment.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/SecondMoment.java100644 1750 1750 7072 11532241247 32405 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; /** * Computes a statistic related to the Second Central Moment. Specifically, * what is computed is the sum of squared deviations from the sample mean. *

                    * The following recursive updating formula is used:

                    *

                    * Let

                      *
                    • dev = (current obs - previous mean)
                    • *
                    • n = number of observations (including current obs)
                    • *
                    * Then

                    *

                    * new value = old value + dev^2 * (n -1) / n.

                    *

                    * Returns Double.NaN if no data values have been added and * returns 0 if there is just one value in the data set.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SecondMoment extends FirstMoment implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 3942403127395076445L; /** second moment of values that have been added */ protected double m2; /** * Create a SecondMoment instance */ public SecondMoment() { super(); m2 = Double.NaN; } /** * Copy constructor, creates a new {@code SecondMoment} identical * to the {@code original} * * @param original the {@code SecondMoment} instance to copy */ public SecondMoment(SecondMoment original) { super(original); this.m2 = original.m2; } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n < 1) { m1 = m2 = 0.0; } super.increment(d); m2 += ((double) n - 1) * dev * nDev; } /** * {@inheritDoc} */ @Override public void clear() { super.clear(); m2 = Double.NaN; } /** * {@inheritDoc} */ @Override public double getResult() { return m2; } /** * {@inheritDoc} */ @Override public SecondMoment copy() { SecondMoment result = new SecondMoment(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source SecondMoment to copy * @param dest SecondMoment to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SecondMoment source, SecondMoment dest) { FirstMoment.copy(source, dest); dest.m2 = source.m2; } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation100644 1750 1750 23204 11532241247 32510 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Computes the sample standard deviation. The standard deviation * is the positive square root of the variance. This implementation wraps a * {@link Variance} instance. The isBiasCorrected property of the * wrapped Variance instance is exposed, so that this class can be used to * compute both the "sample standard deviation" (the square root of the * bias-corrected "sample variance") or the "population standard deviation" * (the square root of the non-bias-corrected "population variance"). See * {@link Variance} for more information. *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class StandardDeviation extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 5728716329662425188L; /** Wrapped Variance instance */ private Variance variance = null; /** * Constructs a StandardDeviation. Sets the underlying {@link Variance} * instance's isBiasCorrected property to true. */ public StandardDeviation() { variance = new Variance(); } /** * Constructs a StandardDeviation from an external second moment. * * @param m2 the external moment */ public StandardDeviation(final SecondMoment m2) { variance = new Variance(m2); } /** * Copy constructor, creates a new {@code StandardDeviation} identical * to the {@code original} * * @param original the {@code StandardDeviation} instance to copy */ public StandardDeviation(StandardDeviation original) { copy(original, this); } /** * Contructs a StandardDeviation with the specified value for the * isBiasCorrected property. If this property is set to * true, the {@link Variance} used in computing results will * use the bias-corrected, or "sample" formula. See {@link Variance} for * details. * * @param isBiasCorrected whether or not the variance computation will use * the bias-corrected formula */ public StandardDeviation(boolean isBiasCorrected) { variance = new Variance(isBiasCorrected); } /** * Contructs a StandardDeviation with the specified value for the * isBiasCorrected property and the supplied external moment. * If isBiasCorrected is set to true, the * {@link Variance} used in computing results will use the bias-corrected, * or "sample" formula. See {@link Variance} for details. * * @param isBiasCorrected whether or not the variance computation will use * the bias-corrected formula * @param m2 the external moment */ public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) { variance = new Variance(isBiasCorrected, m2); } /** * {@inheritDoc} */ @Override public void increment(final double d) { variance.increment(d); } /** * {@inheritDoc} */ public long getN() { return variance.getN(); } /** * {@inheritDoc} */ @Override public double getResult() { return FastMath.sqrt(variance.getResult()); } /** * {@inheritDoc} */ @Override public void clear() { variance.clear(); } /** * Returns the Standard Deviation of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @return the standard deviation of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null */ @Override public double evaluate(final double[] values) { return FastMath.sqrt(variance.evaluate(values)); } /** * Returns the Standard Deviation of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the standard deviation of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { return FastMath.sqrt(variance.evaluate(values, begin, length)); } /** * Returns the Standard Deviation of the entries in the specified portion of * the input array, using the precomputed mean value. Returns * Double.NaN if the designated subarray is empty. *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * The formula used assumes that the supplied mean value is the arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param mean the precomputed mean value * @param begin index of the first array element to include * @param length the number of elements to include * @return the standard deviation of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public double evaluate(final double[] values, final double mean, final int begin, final int length) { return FastMath.sqrt(variance.evaluate(values, mean, begin, length)); } /** * Returns the Standard Deviation of the entries in the input array, using * the precomputed mean value. Returns * Double.NaN if the designated subarray is empty. *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * The formula used assumes that the supplied mean value is the arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param mean the precomputed mean value * @return the standard deviation of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null */ public double evaluate(final double[] values, final double mean) { return FastMath.sqrt(variance.evaluate(values, mean)); } /** * @return Returns the isBiasCorrected. */ public boolean isBiasCorrected() { return variance.isBiasCorrected(); } /** * @param isBiasCorrected The isBiasCorrected to set. */ public void setBiasCorrected(boolean isBiasCorrected) { variance.setBiasCorrected(isBiasCorrected); } /** * {@inheritDoc} */ @Override public StandardDeviation copy() { StandardDeviation result = new StandardDeviation(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source StandardDeviation to copy * @param dest StandardDeviation to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(StandardDeviation source, StandardDeviation dest) { dest.setData(source.getDataRef()); dest.variance = source.variance.copy(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java100644 1750 1750 23257 11532241247 30715 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.WeightedEvaluation; import org.apache.commons.math.stat.descriptive.summary.Sum; /** *

                    Computes the arithmetic mean of a set of values. Uses the definitional * formula:

                    *

                    * mean = sum(x_i) / n *

                    *

                    where n is the number of observations. *

                    *

                    When {@link #increment(double)} is used to add data incrementally from a * stream of (unstored) values, the value of the statistic that * {@link #getResult()} returns is computed using the following recursive * updating algorithm:

                    *
                      *
                    1. Initialize m = the first value
                    2. *
                    3. For each additional value, update using
                      * m = m + (new value - m) / (number of observations)
                    4. *
                    *

                    If {@link #evaluate(double[])} is used to compute the mean of an array * of stored values, a two-pass, corrected algorithm is used, starting with * the definitional formula computed using the array of stored values and then * correcting this by adding the mean deviation of the data values from the * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing * Sample Means and Variances," Robert F. Ling, Journal of the American * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866.

                    *

                    * Returns Double.NaN if the dataset is empty. *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally. * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Mean extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation { /** Serializable version identifier */ private static final long serialVersionUID = -1296043746617791564L; /** First moment on which this statistic is based. */ protected FirstMoment moment; /** * Determines whether or not this statistic can be incremented or cleared. *

                    * Statistics based on (constructed from) external moments cannot * be incremented or cleared.

                    */ protected boolean incMoment; /** Constructs a Mean. */ public Mean() { incMoment = true; moment = new FirstMoment(); } /** * Constructs a Mean with an External Moment. * * @param m1 the moment */ public Mean(final FirstMoment m1) { this.moment = m1; incMoment = false; } /** * Copy constructor, creates a new {@code Mean} identical * to the {@code original} * * @param original the {@code Mean} instance to copy */ public Mean(Mean original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (incMoment) { moment.increment(d); } } /** * {@inheritDoc} */ @Override public void clear() { if (incMoment) { moment.clear(); } } /** * {@inheritDoc} */ @Override public double getResult() { return moment.m1; } /** * {@inheritDoc} */ public long getN() { return moment.getN(); } /** * Returns the arithmetic mean of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link Mean} for details on the computing algorithm.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the mean of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values,final int begin, final int length) { if (test(values, begin, length)) { Sum sum = new Sum(); double sampleSize = length; // Compute initial estimate using definitional formula double xbar = sum.evaluate(values, begin, length) / sampleSize; // Compute correction factor in second pass double correction = 0; for (int i = begin; i < begin + length; i++) { correction += values[i] - xbar; } return xbar + (correction/sampleSize); } return Double.NaN; } /** * Returns the weighted arithmetic mean of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if either array is null.

                    *

                    * See {@link Mean} for details on the computing algorithm. The two-pass algorithm * described above is used here, with weights applied in computing both the original * estimate and the correction factor.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *
                    • the start and length arguments do not determine a valid array
                    • *

                    * * @param values the input array * @param weights the weights array * @param begin index of the first array element to include * @param length the number of elements to include * @return the mean of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { if (test(values, weights, begin, length)) { Sum sum = new Sum(); // Compute initial estimate using definitional formula double sumw = sum.evaluate(weights,begin,length); double xbarw = sum.evaluate(values, weights, begin, length) / sumw; // Compute correction factor in second pass double correction = 0; for (int i = begin; i < begin + length; i++) { correction += weights[i] * (values[i] - xbarw); } return xbarw + (correction/sumw); } return Double.NaN; } /** * Returns the weighted arithmetic mean of the entries in the input array. *

                    * Throws IllegalArgumentException if either array is null.

                    *

                    * See {@link Mean} for details on the computing algorithm. The two-pass algorithm * described above is used here, with weights applied in computing both the original * estimate and the correction factor.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *

                    * * @param values the input array * @param weights the weights array * @return the mean of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights) { return evaluate(values, weights, 0, values.length); } /** * {@inheritDoc} */ @Override public Mean copy() { Mean result = new Mean(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Mean to copy * @param dest Mean to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Mean source, Mean dest) { dest.setData(source.getDataRef()); dest.incMoment = source.incMoment; dest.moment = source.moment.copy(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.java100644 1750 1750 10115 11532241247 32254 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; /** * Computes a statistic related to the Third Central Moment. Specifically, * what is computed is the sum of cubed deviations from the sample mean. *

                    * The following recursive updating formula is used:

                    *

                    * Let

                      *
                    • dev = (current obs - previous mean)
                    • *
                    • m2 = previous value of {@link SecondMoment}
                    • *
                    • n = number of observations (including current obs)
                    • *
                    * Then

                    *

                    * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)

                    *

                    * Returns Double.NaN if no data values have been added and * returns 0 if there is just one value in the data set.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class ThirdMoment extends SecondMoment implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -7818711964045118679L; /** third moment of values that have been added */ protected double m3; /** * Square of deviation of most recently added value from previous first * moment, normalized by previous sample size. Retained to prevent * repeated computation in higher order moments. nDevSq = nDev * nDev. */ protected double nDevSq; /** * Create a FourthMoment instance */ public ThirdMoment() { super(); m3 = Double.NaN; nDevSq = Double.NaN; } /** * Copy constructor, creates a new {@code ThirdMoment} identical * to the {@code original} * * @param original the {@code ThirdMoment} instance to copy */ public ThirdMoment(ThirdMoment original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n < 1) { m3 = m2 = m1 = 0.0; } double prevM2 = m2; super.increment(d); nDevSq = nDev * nDev; double n0 = n; m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev; } /** * {@inheritDoc} */ @Override public double getResult() { return m3; } /** * {@inheritDoc} */ @Override public void clear() { super.clear(); m3 = Double.NaN; nDevSq = Double.NaN; } /** * {@inheritDoc} */ @Override public ThirdMoment copy() { ThirdMoment result = new ThirdMoment(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source ThirdMoment to copy * @param dest ThirdMoment to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(ThirdMoment source, ThirdMoment dest) { SecondMoment.copy(source, dest); dest.m3 = source.m3; dest.nDevSq = source.nDevSq; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/FirstMoment.java100644 1750 1750 10706 11532241247 32277 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Computes the first moment (arithmetic mean). Uses the definitional formula: *

                    * mean = sum(x_i) / n

                    *

                    * where n is the number of observations.

                    *

                    * To limit numeric errors, the value of the statistic is computed using the * following recursive updating algorithm:

                    *

                    *

                      *
                    1. Initialize m = the first value
                    2. *
                    3. For each additional value, update using
                      * m = m + (new value - m) / (number of observations)
                    4. *

                    *

                    * Returns Double.NaN if the dataset is empty.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class FirstMoment extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 6112755307178490473L; /** Count of values that have been added */ protected long n; /** First moment of values that have been added */ protected double m1; /** * Deviation of most recently added value from previous first moment. * Retained to prevent repeated computation in higher order moments. */ protected double dev; /** * Deviation of most recently added value from previous first moment, * normalized by previous sample size. Retained to prevent repeated * computation in higher order moments */ protected double nDev; /** * Create a FirstMoment instance */ public FirstMoment() { n = 0; m1 = Double.NaN; dev = Double.NaN; nDev = Double.NaN; } /** * Copy constructor, creates a new {@code FirstMoment} identical * to the {@code original} * * @param original the {@code FirstMoment} instance to copy */ public FirstMoment(FirstMoment original) { super(); copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n == 0) { m1 = 0.0; } n++; double n0 = n; dev = d - m1; nDev = dev / n0; m1 += nDev; } /** * {@inheritDoc} */ @Override public void clear() { m1 = Double.NaN; n = 0; dev = Double.NaN; nDev = Double.NaN; } /** * {@inheritDoc} */ @Override public double getResult() { return m1; } /** * {@inheritDoc} */ public long getN() { return n; } /** * {@inheritDoc} */ @Override public FirstMoment copy() { FirstMoment result = new FirstMoment(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source FirstMoment to copy * @param dest FirstMoment to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(FirstMoment source, FirstMoment dest) { dest.setData(source.getDataRef()); dest.n = source.n; dest.m1 = source.m1; dest.dev = source.dev; dest.nDev = source.nDev; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/Kurtosis.java100644 1750 1750 16051 11532241247 31652 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Computes the Kurtosis of the available values. *

                    * We use the following (unbiased) formula to define kurtosis:

                    *

                    * kurtosis = { [n(n+1) / (n -1)(n - 2)(n-3)] sum[(x_i - mean)^4] / std^4 } - [3(n-1)^2 / (n-2)(n-3)] *

                    * where n is the number of values, mean is the {@link Mean} and std is the * {@link StandardDeviation}

                    *

                    * Note that this statistic is undefined for n < 4. Double.Nan * is returned when there is not sufficient data to compute the statistic.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Kurtosis extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 2784465764798260919L; /**Fourth Moment on which this statistic is based */ protected FourthMoment moment; /** * Determines whether or not this statistic can be incremented or cleared. *

                    * Statistics based on (constructed from) external moments cannot * be incremented or cleared.

                    */ protected boolean incMoment; /** * Construct a Kurtosis */ public Kurtosis() { incMoment = true; moment = new FourthMoment(); } /** * Construct a Kurtosis from an external moment * * @param m4 external Moment */ public Kurtosis(final FourthMoment m4) { incMoment = false; this.moment = m4; } /** * Copy constructor, creates a new {@code Kurtosis} identical * to the {@code original} * * @param original the {@code Kurtosis} instance to copy */ public Kurtosis(Kurtosis original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (incMoment) { moment.increment(d); } else { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS); } } /** * {@inheritDoc} */ @Override public double getResult() { double kurtosis = Double.NaN; if (moment.getN() > 3) { double variance = moment.m2 / (moment.n - 1); if (moment.n <= 3 || variance < 10E-20) { kurtosis = 0.0; } else { double n = moment.n; kurtosis = (n * (n + 1) * moment.m4 - 3 * moment.m2 * moment.m2 * (n - 1)) / ((n - 1) * (n -2) * (n -3) * variance * variance); } } return kurtosis; } /** * {@inheritDoc} */ @Override public void clear() { if (incMoment) { moment.clear(); } else { throw MathRuntimeException.createIllegalStateException( LocalizedFormats.CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS); } } /** * {@inheritDoc} */ public long getN() { return moment.getN(); } /* UnvariateStatistic Approach */ /** * Returns the kurtosis of the entries in the specified portion of the * input array. *

                    * See {@link Kurtosis} for details on the computing algorithm.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the kurtosis of the values or Double.NaN if length is less than * 4 * @throws IllegalArgumentException if the input array is null or the array * index parameters are not valid */ @Override public double evaluate(final double[] values,final int begin, final int length) { // Initialize the kurtosis double kurt = Double.NaN; if (test(values, begin, length) && length > 3) { // Compute the mean and standard deviation Variance variance = new Variance(); variance.incrementAll(values, begin, length); double mean = variance.moment.m1; double stdDev = FastMath.sqrt(variance.getResult()); // Sum the ^4 of the distance from the mean divided by the // standard deviation double accum3 = 0.0; for (int i = begin; i < begin + length; i++) { accum3 += FastMath.pow(values[i] - mean, 4.0); } accum3 /= FastMath.pow(stdDev, 4.0d); // Get N double n0 = length; double coefficientOne = (n0 * (n0 + 1)) / ((n0 - 1) * (n0 - 2) * (n0 - 3)); double termTwo = (3 * FastMath.pow(n0 - 1, 2.0)) / ((n0 - 2) * (n0 - 3)); // Calculate kurtosis kurt = (coefficientOne * accum3) - termTwo; } return kurt; } /** * {@inheritDoc} */ @Override public Kurtosis copy() { Kurtosis result = new Kurtosis(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Kurtosis to copy * @param dest Kurtosis to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Kurtosis source, Kurtosis dest) { dest.setData(source.getDataRef()); dest.moment = source.moment.copy(); dest.incMoment = source.incMoment; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/package.html100644 1750 1750 1672 11532241247 31430 0ustarlucluc 0 0 Summary statistics based on moments. ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovarian100644 1750 1750 11377 11532241247 32530 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; /** * Returns the covariance matrix of the available vectors. * @since 1.2 * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $ */ public class VectorialCovariance implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 4118372414238930270L; /** Sums for each component. */ private final double[] sums; /** Sums of products for each component. */ private final double[] productsSums; /** Indicator for bias correction. */ private final boolean isBiasCorrected; /** Number of vectors in the sample. */ private long n; /** Constructs a VectorialCovariance. * @param dimension vectors dimension * @param isBiasCorrected if true, computed the unbiased sample covariance, * otherwise computes the biased population covariance */ public VectorialCovariance(int dimension, boolean isBiasCorrected) { sums = new double[dimension]; productsSums = new double[dimension * (dimension + 1) / 2]; n = 0; this.isBiasCorrected = isBiasCorrected; } /** * Add a new vector to the sample. * @param v vector to add * @exception DimensionMismatchException if the vector does not have the right dimension */ public void increment(double[] v) throws DimensionMismatchException { if (v.length != sums.length) { throw new DimensionMismatchException(v.length, sums.length); } int k = 0; for (int i = 0; i < v.length; ++i) { sums[i] += v[i]; for (int j = 0; j <= i; ++j) { productsSums[k++] += v[i] * v[j]; } } n++; } /** * Get the covariance matrix. * @return covariance matrix */ public RealMatrix getResult() { int dimension = sums.length; RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension); if (n > 1) { double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n)); int k = 0; for (int i = 0; i < dimension; ++i) { for (int j = 0; j <= i; ++j) { double e = c * (n * productsSums[k++] - sums[i] * sums[j]); result.setEntry(i, j, e); result.setEntry(j, i, e); } } } return result; } /** * Get the number of vectors in the sample. * @return number of vectors in the sample */ public long getN() { return n; } /** * Clears the internal state of the Statistic */ public void clear() { n = 0; Arrays.fill(sums, 0.0); Arrays.fill(productsSums, 0.0); } /** {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (isBiasCorrected ? 1231 : 1237); result = prime * result + (int) (n ^ (n >>> 32)); result = prime * result + Arrays.hashCode(productsSums); result = prime * result + Arrays.hashCode(sums); return result; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof VectorialCovariance)) return false; VectorialCovariance other = (VectorialCovariance) obj; if (isBiasCorrected != other.isBiasCorrected) return false; if (n != other.n) return false; if (!Arrays.equals(productsSums, other.productsSums)) return false; if (!Arrays.equals(sums, other.sums)) return false; return true; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/FourthMoment.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/FourthMoment.java100644 1750 1750 10057 11532241247 32456 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; /** * Computes a statistic related to the Fourth Central Moment. Specifically, * what is computed is the sum of *

                    * (x_i - xbar) ^ 4,

                    *

                    * where the x_i are the * sample observations and xbar is the sample mean.

                    *

                    * The following recursive updating formula is used:

                    *

                    * Let

                      *
                    • dev = (current obs - previous mean)
                    • *
                    • m2 = previous value of {@link SecondMoment}
                    • *
                    • m2 = previous value of {@link ThirdMoment}
                    • *
                    • n = number of observations (including current obs)
                    • *
                    * Then

                    *

                    * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 +
                    * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3

                    *

                    * Returns Double.NaN if no data values have been added and * returns 0 if there is just one value in the data set.

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class FourthMoment extends ThirdMoment implements Serializable{ /** Serializable version identifier */ private static final long serialVersionUID = 4763990447117157611L; /** fourth moment of values that have been added */ protected double m4; /** * Create a FourthMoment instance */ public FourthMoment() { super(); m4 = Double.NaN; } /** * Copy constructor, creates a new {@code FourthMoment} identical * to the {@code original} * * @param original the {@code FourthMoment} instance to copy */ public FourthMoment(FourthMoment original) { super(); copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (n < 1) { m4 = 0.0; m3 = 0.0; m2 = 0.0; m1 = 0.0; } double prevM3 = m3; double prevM2 = m2; super.increment(d); double n0 = n; m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 + ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0); } /** * {@inheritDoc} */ @Override public double getResult() { return m4; } /** * {@inheritDoc} */ @Override public void clear() { super.clear(); m4 = Double.NaN; } /** * {@inheritDoc} */ @Override public FourthMoment copy() { FourthMoment result = new FourthMoment(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source FourthMoment to copy * @param dest FourthMoment to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(FourthMoment source, FourthMoment dest) { ThirdMoment.copy(source, dest); dest.m4 = source.m4; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/Skewness.java100644 1750 1750 14717 11532241247 31640 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; import org.apache.commons.math.util.FastMath; /** * Computes the skewness of the available values. *

                    * We use the following (unbiased) formula to define skewness:

                    *

                    * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3

                    *

                    * where n is the number of values, mean is the {@link Mean} and std is the * {@link StandardDeviation}

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 7101857578996691352L; /** Third moment on which this statistic is based */ protected ThirdMoment moment = null; /** * Determines whether or not this statistic can be incremented or cleared. *

                    * Statistics based on (constructed from) external moments cannot * be incremented or cleared.

                    */ protected boolean incMoment; /** * Constructs a Skewness */ public Skewness() { incMoment = true; moment = new ThirdMoment(); } /** * Constructs a Skewness with an external moment * @param m3 external moment */ public Skewness(final ThirdMoment m3) { incMoment = false; this.moment = m3; } /** * Copy constructor, creates a new {@code Skewness} identical * to the {@code original} * * @param original the {@code Skewness} instance to copy */ public Skewness(Skewness original) { copy(original, this); } /** * {@inheritDoc} */ @Override public void increment(final double d) { if (incMoment) { moment.increment(d); } } /** * Returns the value of the statistic based on the values that have been added. *

                    * See {@link Skewness} for the definition used in the computation.

                    * * @return the skewness of the available values. */ @Override public double getResult() { if (moment.n < 3) { return Double.NaN; } double variance = moment.m2 / (moment.n - 1); if (variance < 10E-20) { return 0.0d; } else { double n0 = moment.getN(); return (n0 * moment.m3) / ((n0 - 1) * (n0 -2) * FastMath.sqrt(variance) * variance); } } /** * {@inheritDoc} */ public long getN() { return moment.getN(); } /** * {@inheritDoc} */ @Override public void clear() { if (incMoment) { moment.clear(); } } /** * Returns the Skewness of the entries in the specifed portion of the * input array. *

                    * See {@link Skewness} for the definition used in the computation.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin the index of the first array element to include * @param length the number of elements to include * @return the skewness of the values or Double.NaN if length is less than * 3 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values,final int begin, final int length) { // Initialize the skewness double skew = Double.NaN; if (test(values, begin, length) && length > 2 ){ Mean mean = new Mean(); // Get the mean and the standard deviation double m = mean.evaluate(values, begin, length); // Calc the std, this is implemented here instead // of using the standardDeviation method eliminate // a duplicate pass to get the mean double accum = 0.0; double accum2 = 0.0; for (int i = begin; i < begin + length; i++) { final double d = values[i] - m; accum += d * d; accum2 += d; } final double variance = (accum - (accum2 * accum2 / length)) / (length - 1); double accum3 = 0.0; for (int i = begin; i < begin + length; i++) { final double d = values[i] - m; accum3 += d * d * d; } accum3 /= variance * FastMath.sqrt(variance); // Get N double n0 = length; // Calculate skewness skew = (n0 / ((n0 - 1) * (n0 - 2))) * accum3; } return skew; } /** * {@inheritDoc} */ @Override public Skewness copy() { Skewness result = new Skewness(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Skewness to copy * @param dest Skewness to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Skewness source, Skewness dest) { dest.setData(source.getDataRef()); dest.moment = new ThirdMoment(source.moment.copy()); dest.incMoment = source.incMoment; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/SemiVariance.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/SemiVariance.java100644 1750 1750 32727 11532241247 32405 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic; /** *

                    Computes the semivariance of a set of values with respect to a given cutoff value. * We define the downside semivariance of a set of values x * against the cutoff value cutoff to be
                    * Σ (x[i] - target)2 / df
                    * where the sum is taken over all i such that x[i] < cutoff * and df is the length of x (non-bias-corrected) or * one less than this number (bias corrected). The upside semivariance * is defined similarly, with the sum taken over values of x that * exceed the cutoff value.

                    * *

                    The cutoff value defaults to the mean, bias correction defaults to true * and the "variance direction" (upside or downside) defaults to downside. The variance direction * and bias correction may be set using property setters or their values can provided as * parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.

                    * *

                    If the input array is null, evaluate methods throw * IllegalArgumentException. If the array has length 1, 0 * is returned, regardless of the value of the cutoff. * *

                    Note that this class is not intended to be threadsafe. If * multiple threads access an instance of this class concurrently, and one or * more of these threads invoke property setters, external synchronization must * be provided to ensure correct results.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ * @since 2.1 */ public class SemiVariance extends AbstractUnivariateStatistic implements Serializable { /** * The UPSIDE Direction is used to specify that the observations above the * cutoff point will be used to calculate SemiVariance. */ public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE; /** * The DOWNSIDE Direction is used to specify that the observations below * the cutoff point will be used to calculate SemiVariance */ public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE; /** Serializable version identifier */ private static final long serialVersionUID = -2653430366886024994L; /** * Determines whether or not bias correction is applied when computing the * value of the statisic. True means that bias is corrected. */ private boolean biasCorrected = true; /** * Determines whether to calculate downside or upside SemiVariance. */ private Direction varianceDirection = Direction.DOWNSIDE; /** * Constructs a SemiVariance with default (true) biasCorrected * property and default (Downside) varianceDirection property. */ public SemiVariance() { } /** * Constructs a SemiVariance with the specified biasCorrected * property and default (Downside) varianceDirection property. * * @param biasCorrected setting for bias correction - true means * bias will be corrected and is equivalent to using the argumentless * constructor */ public SemiVariance(final boolean biasCorrected) { this.biasCorrected = biasCorrected; } /** * Constructs a SemiVariance with the specified Direction property * and default (true) biasCorrected property * * @param direction setting for the direction of the SemiVariance * to calculate */ public SemiVariance(final Direction direction) { this.varianceDirection = direction; } /** * Constructs a SemiVariance with the specified isBiasCorrected * property and the specified Direction property. * * @param corrected setting for bias correction - true means * bias will be corrected and is equivalent to using the argumentless * constructor * * @param direction setting for the direction of the SemiVariance * to calculate */ public SemiVariance(final boolean corrected, final Direction direction) { this.biasCorrected = corrected; this.varianceDirection = direction; } /** * Copy constructor, creates a new {@code SemiVariance} identical * to the {@code original} * * @param original the {@code SemiVariance} instance to copy */ public SemiVariance(final SemiVariance original) { copy(original, this); } /** * {@inheritDoc} */ @Override public SemiVariance copy() { SemiVariance result = new SemiVariance(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source SemiVariance to copy * @param dest SemiVariance to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(final SemiVariance source, SemiVariance dest) { dest.setData(source.getDataRef()); dest.biasCorrected = source.biasCorrected; dest.varianceDirection = source.varianceDirection; } /** * This method calculates {@link SemiVariance} for the entire array against the mean, using * instance properties varianceDirection and biasCorrection. * * @param values the input array * @return the SemiVariance * @throws IllegalArgumentException if values is null * */ @Override public double evaluate(final double[] values) { if (values == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } return evaluate(values, 0, values.length); } /** *

                    Returns the {@link SemiVariance} of the designated values against the mean, using * instance properties varianceDirection and biasCorrection.

                    * *

                    Returns NaN if the array is empty and throws * IllegalArgumentException if the array is null.

                    * * @param values the input array * @param start index of the first array element to include * @param length the number of elements to include * @return the SemiVariance * @throws IllegalArgumentException if the parameters are not valid * */ @Override public double evaluate(final double[] values, final int start, final int length) { double m = (new Mean()).evaluate(values, start, length); return evaluate(values, m, varianceDirection, biasCorrected, 0, values.length); } /** * This method calculates {@link SemiVariance} for the entire array against the mean, using * the current value of the biasCorrection instance property. * * @param values the input array * @param direction the {@link Direction} of the semivariance * @return the SemiVariance * @throws IllegalArgumentException if values is null * */ public double evaluate(final double[] values, Direction direction) { double m = (new Mean()).evaluate(values); return evaluate (values, m, direction, biasCorrected, 0, values.length); } /** *

                    Returns the {@link SemiVariance} of the designated values against the cutoff, using * instance properties variancDirection and biasCorrection.

                    * *

                    Returns NaN if the array is empty and throws * IllegalArgumentException if the array is null.

                    * * @param values the input array * @param cutoff the reference point * @return the SemiVariance * @throws IllegalArgumentException if values is null */ public double evaluate(final double[] values, final double cutoff) { return evaluate(values, cutoff, varianceDirection, biasCorrected, 0, values.length); } /** *

                    Returns the {@link SemiVariance} of the designated values against the cutoff in the * given direction, using the current value of the biasCorrection instance property.

                    * *

                    Returns NaN if the array is empty and throws * IllegalArgumentException if the array is null.

                    * * @param values the input array * @param cutoff the reference point * @param direction the {@link Direction} of the semivariance * @return the SemiVariance * @throws IllegalArgumentException if values is null */ public double evaluate(final double[] values, final double cutoff, final Direction direction) { return evaluate(values, cutoff, direction, biasCorrected, 0, values.length); } /** *

                    Returns the {@link SemiVariance} of the designated values against the cutoff * in the given direction with the provided bias correction.

                    * *

                    Returns NaN if the array is empty and throws * IllegalArgumentException if the array is null.

                    * * @param values the input array * @param cutoff the reference point * @param direction the {@link Direction} of the semivariance * @param corrected the BiasCorrection flag * @param start index of the first array element to include * @param length the number of elements to include * @return the SemiVariance * @throws IllegalArgumentException if the parameters are not valid * */ public double evaluate (final double[] values, final double cutoff, final Direction direction, final boolean corrected, final int start, final int length) { test(values, start, length); if (values.length == 0) { return Double.NaN; } else { if (values.length == 1) { return 0.0; } else { final boolean booleanDirection = direction.getDirection(); double dev = 0.0; double sumsq = 0.0; for (int i = start; i < length; i++) { if ((values[i] > cutoff) == booleanDirection) { dev = values[i] - cutoff; sumsq += dev * dev; } } if (corrected) { return sumsq / (length - 1.0); } else { return sumsq / length; } } } } /** * Returns true iff biasCorrected property is set to true. * * @return the value of biasCorrected. */ public boolean isBiasCorrected() { return biasCorrected; } /** * Sets the biasCorrected property. * * @param biasCorrected new biasCorrected property value */ public void setBiasCorrected(boolean biasCorrected) { this.biasCorrected = biasCorrected; } /** * Returns the varianceDirection property. * * @return the varianceDirection */ public Direction getVarianceDirection () { return varianceDirection; } /** * Sets the variance direction * * @param varianceDirection the direction of the semivariance */ public void setVarianceDirection(Direction varianceDirection) { this.varianceDirection = varianceDirection; } /** * The direction of the semivariance - either upside or downside. The direction * is represented by boolean, with true corresponding to UPSIDE semivariance. */ public enum Direction { /** * The UPSIDE Direction is used to specify that the observations above the * cutoff point will be used to calculate SemiVariance */ UPSIDE (true), /** * The DOWNSIDE Direction is used to specify that the observations below * the cutoff point will be used to calculate SemiVariance */ DOWNSIDE (false); /** * boolean value UPSIDE <-> true */ private boolean direction; /** * Create a Direction with the given value. * * @param b boolean value representing the Direction. True corresponds to UPSIDE. */ Direction (boolean b) { direction = b; } /** * Returns the value of this Direction. True corresponds to UPSIDE. * * @return true if direction is UPSIDE; false otherwise */ boolean getDirection () { return direction; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java100644 1750 1750 57577 11532241247 31601 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive.moment; import java.io.Serializable; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.WeightedEvaluation; import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; /** * Computes the variance of the available values. By default, the unbiased * "sample variance" definitional formula is used: *

                    * variance = sum((x_i - mean)^2) / (n - 1)

                    *

                    * where mean is the {@link Mean} and n is the number * of sample observations.

                    *

                    * The definitional formula does not have good numerical properties, so * this implementation does not compute the statistic using the definitional * formula.

                      *
                    • The getResult method computes the variance using * updating formulas based on West's algorithm, as described in * Chan, T. F. and * J. G. Lewis 1979, Communications of the ACM, * vol. 22 no. 9, pp. 526-531.
                    • *
                    • The evaluate methods leverage the fact that they have the * full array of values in memory to execute a two-pass algorithm. * Specifically, these methods use the "corrected two-pass algorithm" from * Chan, Golub, Levesque, Algorithms for Computing the Sample Variance, * American Statistician, vol. 37, no. 3 (1983) pp. 242-247.
                    * Note that adding values using increment or * incrementAll and then executing getResult will * sometimes give a different, less accurate, result than executing * evaluate with the full array of values. The former approach * should only be used when the full array of values is not available.

                    *

                    * The "population variance" ( sum((x_i - mean)^2) / n ) can also * be computed using this statistic. The isBiasCorrected * property determines whether the "population" or "sample" value is * returned by the evaluate and getResult methods. * To compute population variances, set this property to false. *

                    *

                    * Note that this implementation is not synchronized. If * multiple threads access an instance of this class concurrently, and at least * one of the threads invokes the increment() or * clear() method, it must be synchronized externally.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation { /** Serializable version identifier */ private static final long serialVersionUID = -9111962718267217978L; /** SecondMoment is used in incremental calculation of Variance*/ protected SecondMoment moment = null; /** * Boolean test to determine if this Variance should also increment * the second moment, this evaluates to false when this Variance is * constructed with an external SecondMoment as a parameter. */ protected boolean incMoment = true; /** * Determines whether or not bias correction is applied when computing the * value of the statisic. True means that bias is corrected. See * {@link Variance} for details on the formula. */ private boolean isBiasCorrected = true; /** * Constructs a Variance with default (true) isBiasCorrected * property. */ public Variance() { moment = new SecondMoment(); } /** * Constructs a Variance based on an external second moment. * * @param m2 the SecondMoment (Third or Fourth moments work * here as well.) */ public Variance(final SecondMoment m2) { incMoment = false; this.moment = m2; } /** * Constructs a Variance with the specified isBiasCorrected * property * * @param isBiasCorrected setting for bias correction - true means * bias will be corrected and is equivalent to using the argumentless * constructor */ public Variance(boolean isBiasCorrected) { moment = new SecondMoment(); this.isBiasCorrected = isBiasCorrected; } /** * Constructs a Variance with the specified isBiasCorrected * property and the supplied external second moment. * * @param isBiasCorrected setting for bias correction - true means * bias will be corrected * @param m2 the SecondMoment (Third or Fourth moments work * here as well.) */ public Variance(boolean isBiasCorrected, SecondMoment m2) { incMoment = false; this.moment = m2; this.isBiasCorrected = isBiasCorrected; } /** * Copy constructor, creates a new {@code Variance} identical * to the {@code original} * * @param original the {@code Variance} instance to copy */ public Variance(Variance original) { copy(original, this); } /** * {@inheritDoc} *

                    If all values are available, it is more accurate to use * {@link #evaluate(double[])} rather than adding values one at a time * using this method and then executing {@link #getResult}, since * evaluate leverages the fact that is has the full * list of values together to execute a two-pass algorithm. * See {@link Variance}.

                    */ @Override public void increment(final double d) { if (incMoment) { moment.increment(d); } } /** * {@inheritDoc} */ @Override public double getResult() { if (moment.n == 0) { return Double.NaN; } else if (moment.n == 1) { return 0d; } else { if (isBiasCorrected) { return moment.m2 / (moment.n - 1d); } else { return moment.m2 / (moment.n); } } } /** * {@inheritDoc} */ public long getN() { return moment.getN(); } /** * {@inheritDoc} */ @Override public void clear() { if (incMoment) { moment.clear(); } } /** * Returns the variance of the entries in the input array, or * Double.NaN if the array is empty. *

                    * See {@link Variance} for details on the computing algorithm.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null */ @Override public double evaluate(final double[] values) { if (values == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } return evaluate(values, 0, values.length); } /** * Returns the variance of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * See {@link Variance} for details on the computing algorithm.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Does not change the internal state of the statistic.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ @Override public double evaluate(final double[] values, final int begin, final int length) { double var = Double.NaN; if (test(values, begin, length)) { clear(); if (length == 1) { var = 0.0; } else if (length > 1) { Mean mean = new Mean(); double m = mean.evaluate(values, begin, length); var = evaluate(values, m, begin, length); } } return var; } /** *

                    Returns the weighted variance of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty.

                    *

                    * Uses the formula

                         *   Σ(weights[i]*(values[i] - weightedMean)2)/(Σ(weights[i]) - 1)
                         * 
                    * where weightedMean is the weighted mean

                    *

                    * This formula will not return the same result as the unweighted variance when all * weights are equal, unless all weights are equal to 1. The formula assumes that * weights are to be treated as "expansion values," as will be the case if for example * the weights represent frequency counts. To normalize weights so that the denominator * in the variance computation equals the length of the input vector minus one, use

                         *   evaluate(values, MathUtils.normalizeArray(weights, values.length)); 
                         * 
                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *
                    • the start and length arguments do not determine a valid array
                    • *

                    *

                    * Does not change the internal state of the statistic.

                    *

                    * Throws IllegalArgumentException if either array is null.

                    * * @param values the input array * @param weights the weights array * @param begin index of the first array element to include * @param length the number of elements to include * @return the weighted variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { double var = Double.NaN; if (test(values, weights,begin, length)) { clear(); if (length == 1) { var = 0.0; } else if (length > 1) { Mean mean = new Mean(); double m = mean.evaluate(values, weights, begin, length); var = evaluate(values, weights, m, begin, length); } } return var; } /** *

                    * Returns the weighted variance of the entries in the the input array.

                    *

                    * Uses the formula

                         *   Σ(weights[i]*(values[i] - weightedMean)2)/(Σ(weights[i]) - 1)
                         * 
                    * where weightedMean is the weighted mean

                    *

                    * This formula will not return the same result as the unweighted variance when all * weights are equal, unless all weights are equal to 1. The formula assumes that * weights are to be treated as "expansion values," as will be the case if for example * the weights represent frequency counts. To normalize weights so that the denominator * in the variance computation equals the length of the input vector minus one, use

                         *   evaluate(values, MathUtils.normalizeArray(weights, values.length)); 
                         * 
                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *

                    *

                    * Does not change the internal state of the statistic.

                    *

                    * Throws IllegalArgumentException if either array is null.

                    * * @param values the input array * @param weights the weights array * @return the weighted variance of the values * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights) { return evaluate(values, weights, 0, values.length); } /** * Returns the variance of the entries in the specified portion of * the input array, using the precomputed mean value. Returns * Double.NaN if the designated subarray is empty. *

                    * See {@link Variance} for details on the computing algorithm.

                    *

                    * The formula used assumes that the supplied mean value is the arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param mean the precomputed mean value * @param begin index of the first array element to include * @param length the number of elements to include * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public double evaluate(final double[] values, final double mean, final int begin, final int length) { double var = Double.NaN; if (test(values, begin, length)) { if (length == 1) { var = 0.0; } else if (length > 1) { double accum = 0.0; double dev = 0.0; double accum2 = 0.0; for (int i = begin; i < begin + length; i++) { dev = values[i] - mean; accum += dev * dev; accum2 += dev; } double len = length; if (isBiasCorrected) { var = (accum - (accum2 * accum2 / len)) / (len - 1.0); } else { var = (accum - (accum2 * accum2 / len)) / len; } } } return var; } /** * Returns the variance of the entries in the input array, using the * precomputed mean value. Returns Double.NaN if the array * is empty. *

                    * See {@link Variance} for details on the computing algorithm.

                    *

                    * If isBiasCorrected is true the formula used * assumes that the supplied mean value is the arithmetic mean of the * sample data, not a known population parameter. If the mean is a known * population parameter, or if the "population" version of the variance is * desired, set isBiasCorrected to false before * invoking this method.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param mean the precomputed mean value * @return the variance of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public double evaluate(final double[] values, final double mean) { return evaluate(values, mean, 0, values.length); } /** * Returns the weighted variance of the entries in the specified portion of * the input array, using the precomputed weighted mean value. Returns * Double.NaN if the designated subarray is empty. *

                    * Uses the formula

                         *   Σ(weights[i]*(values[i] - mean)2)/(Σ(weights[i]) - 1)
                         * 

                    *

                    * The formula used assumes that the supplied mean value is the weighted arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * This formula will not return the same result as the unweighted variance when all * weights are equal, unless all weights are equal to 1. The formula assumes that * weights are to be treated as "expansion values," as will be the case if for example * the weights represent frequency counts. To normalize weights so that the denominator * in the variance computation equals the length of the input vector minus one, use

                         *   evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); 
                         * 
                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *
                    • the start and length arguments do not determine a valid array
                    • *

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param weights the weights array * @param mean the precomputed weighted mean value * @param begin index of the first array element to include * @param length the number of elements to include * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final double mean, final int begin, final int length) { double var = Double.NaN; if (test(values, weights, begin, length)) { if (length == 1) { var = 0.0; } else if (length > 1) { double accum = 0.0; double dev = 0.0; double accum2 = 0.0; for (int i = begin; i < begin + length; i++) { dev = values[i] - mean; accum += weights[i] * (dev * dev); accum2 += weights[i] * dev; } double sumWts = 0; for (int i = 0; i < weights.length; i++) { sumWts += weights[i]; } if (isBiasCorrected) { var = (accum - (accum2 * accum2 / sumWts)) / (sumWts - 1.0); } else { var = (accum - (accum2 * accum2 / sumWts)) / sumWts; } } } return var; } /** *

                    Returns the weighted variance of the values in the input array, using * the precomputed weighted mean value.

                    *

                    * Uses the formula

                         *   Σ(weights[i]*(values[i] - mean)2)/(Σ(weights[i]) - 1)
                         * 

                    *

                    * The formula used assumes that the supplied mean value is the weighted arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * This formula will not return the same result as the unweighted variance when all * weights are equal, unless all weights are equal to 1. The formula assumes that * weights are to be treated as "expansion values," as will be the case if for example * the weights represent frequency counts. To normalize weights so that the denominator * in the variance computation equals the length of the input vector minus one, use

                         *   evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); 
                         * 
                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if any of the following are true: *

                    • the values array is null
                    • *
                    • the weights array is null
                    • *
                    • the weights array does not have the same length as the values array
                    • *
                    • the weights array contains one or more infinite values
                    • *
                    • the weights array contains one or more NaN values
                    • *
                    • the weights array contains negative values
                    • *

                    *

                    * Does not change the internal state of the statistic.

                    * * @param values the input array * @param weights the weights array * @param mean the precomputed weighted mean value * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final double mean) { return evaluate(values, weights, mean, 0, values.length); } /** * @return Returns the isBiasCorrected. */ public boolean isBiasCorrected() { return isBiasCorrected; } /** * @param biasCorrected The isBiasCorrected to set. */ public void setBiasCorrected(boolean biasCorrected) { this.isBiasCorrected = biasCorrected; } /** * {@inheritDoc} */ @Override public Variance copy() { Variance result = new Variance(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source Variance to copy * @param dest Variance to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(Variance source, Variance dest) { if (source == null || dest == null) { throw new NullArgumentException(); } dest.setData(source.getDataRef()); dest.moment = source.moment.copy(); dest.isBiasCorrected = source.isBiasCorrected; dest.incMoment = source.incMoment; } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateS100644 1750 1750 7275 11532241247 32576 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.linear.RealMatrix; /** * Reporting interface for basic multivariate statistics. * * @since 1.2 * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface StatisticalMultivariateSummary { /** * Returns the dimension of the data * @return The dimension of the data */ int getDimension(); /** * Returns an array whose ith entry is the * mean of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component means */ double[] getMean(); /** * Returns the covariance of the available values. * @return The covariance, null if no multivariate sample * have been added or a zeroed matrix for a single value set. */ RealMatrix getCovariance(); /** * Returns an array whose ith entry is the * standard deviation of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component standard deviations */ double[] getStandardDeviation(); /** * Returns an array whose ith entry is the * maximum of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component maxima */ double[] getMax(); /** * Returns an array whose ith entry is the * minimum of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component minima */ double[] getMin(); /** * Returns the number of available values * @return The number of available values */ long getN(); /** * Returns an array whose ith entry is the * geometric mean of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component geometric means */ double[] getGeometricMean(); /** * Returns an array whose ith entry is the * sum of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component sums */ double[] getSum(); /** * Returns an array whose ith entry is the * sum of squares of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component sums of squares */ double[] getSumSq(); /** * Returns an array whose ith entry is the * sum of logs of the ith entries of the arrays * that correspond to each multivariate sample * * @return the array of component log sums */ double[] getSumLog(); } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/UnivariateStatistic.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/UnivariateStatistic.java100644 1750 1750 3524 11532241247 32510 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Base interface implemented by all statistics. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface UnivariateStatistic { /** * Returns the result of evaluating the statistic over the input array. * * @param values input array * @return the value of the statistic applied to the input array */ double evaluate(double[] values); /** * Returns the result of evaluating the statistic over the specified entries * in the input array. * * @param values the input array * @param begin the index of the first element to include * @param length the number of elements to include * @return the value of the statistic applied to the included array entries */ double evaluate(double[] values, int begin, int length); /** * Returns a copy of the statistic with the same internal state. * * @return a copy of the statistic */ UnivariateStatistic copy(); } ././@LongLink100644 0 0 173 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariate100644 1750 1750 16066 11532241247 32664 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.linear.RealMatrix; /** * Implementation of * {@link org.apache.commons.math.stat.descriptive.MultivariateSummaryStatistics} that * is safe to use in a multithreaded environment. Multiple threads can safely * operate on a single instance without causing runtime exceptions due to race * conditions. In effect, this implementation makes modification and access * methods atomic operations for a single instance. That is to say, as one * thread is computing a statistic from the instance, no other thread can modify * the instance nor compute another statistic. * @since 1.2 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SynchronizedMultivariateSummaryStatistics extends MultivariateSummaryStatistics { /** Serialization UID */ private static final long serialVersionUID = 7099834153347155363L; /** * Construct a SynchronizedMultivariateSummaryStatistics instance * @param k dimension of the data * @param isCovarianceBiasCorrected if true, the unbiased sample * covariance is computed, otherwise the biased population covariance * is computed */ public SynchronizedMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { super(k, isCovarianceBiasCorrected); } /** * {@inheritDoc} */ @Override public synchronized void addValue(double[] value) throws DimensionMismatchException { super.addValue(value); } /** * {@inheritDoc} */ @Override public synchronized int getDimension() { return super.getDimension(); } /** * {@inheritDoc} */ @Override public synchronized long getN() { return super.getN(); } /** * {@inheritDoc} */ @Override public synchronized double[] getSum() { return super.getSum(); } /** * {@inheritDoc} */ @Override public synchronized double[] getSumSq() { return super.getSumSq(); } /** * {@inheritDoc} */ @Override public synchronized double[] getSumLog() { return super.getSumLog(); } /** * {@inheritDoc} */ @Override public synchronized double[] getMean() { return super.getMean(); } /** * {@inheritDoc} */ @Override public synchronized double[] getStandardDeviation() { return super.getStandardDeviation(); } /** * {@inheritDoc} */ @Override public synchronized RealMatrix getCovariance() { return super.getCovariance(); } /** * {@inheritDoc} */ @Override public synchronized double[] getMax() { return super.getMax(); } /** * {@inheritDoc} */ @Override public synchronized double[] getMin() { return super.getMin(); } /** * {@inheritDoc} */ @Override public synchronized double[] getGeometricMean() { return super.getGeometricMean(); } /** * {@inheritDoc} */ @Override public synchronized String toString() { return super.toString(); } /** * {@inheritDoc} */ @Override public synchronized void clear() { super.clear(); } /** * {@inheritDoc} */ @Override public synchronized boolean equals(Object object) { return super.equals(object); } /** * {@inheritDoc} */ @Override public synchronized int hashCode() { return super.hashCode(); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getSumImpl() { return super.getSumImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumImpl(StorelessUnivariateStatistic[] sumImpl) throws DimensionMismatchException { super.setSumImpl(sumImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getSumsqImpl() { return super.getSumsqImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) throws DimensionMismatchException { super.setSumsqImpl(sumsqImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getMinImpl() { return super.getMinImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMinImpl(StorelessUnivariateStatistic[] minImpl) throws DimensionMismatchException { super.setMinImpl(minImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getMaxImpl() { return super.getMaxImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) throws DimensionMismatchException { super.setMaxImpl(maxImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getSumLogImpl() { return super.getSumLogImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) throws DimensionMismatchException { super.setSumLogImpl(sumLogImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getGeoMeanImpl() { return super.getGeoMeanImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) throws DimensionMismatchException { super.setGeoMeanImpl(geoMeanImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic[] getMeanImpl() { return super.getMeanImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) throws DimensionMismatchException { super.setMeanImpl(meanImpl); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java100644 1750 1750 3624 11532241247 32302 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Weighted evaluation for statistics. * * @since 2.1 * @version $Revision: 894474 $ $Date: 2009-12-29 21:02:37 +0100 (mar. 29 déc. 2009) $ */ public interface WeightedEvaluation { /** * Returns the result of evaluating the statistic over the input array, * using the supplied weights. * * @param values input array * @param weights array of weights * @return the value of the weighted statistic applied to the input array */ double evaluate(double[] values, double[] weights); /** * Returns the result of evaluating the statistic over the specified entries * in the input array, using corresponding entries in the supplied weights array. * * @param values the input array * @param weights array of weights * @param begin the index of the first element to include * @param length the number of elements to include * @return the value of the weighted statistic applied to the included array entries */ double evaluate(double[] values, double[] weights, int begin, int length); } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues100644 1750 1750 13032 11532241247 32626 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Value object representing the results of a univariate statistical summary. * * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $ */ public class StatisticalSummaryValues implements Serializable, StatisticalSummary { /** Serialization id */ private static final long serialVersionUID = -5108854841843722536L; /** The sample mean */ private final double mean; /** The sample variance */ private final double variance; /** The number of observations in the sample */ private final long n; /** The maximum value */ private final double max; /** The minimum value */ private final double min; /** The sum of the sample values */ private final double sum; /** * Constructor * * @param mean the sample mean * @param variance the sample variance * @param n the number of observations in the sample * @param max the maximum value * @param min the minimum value * @param sum the sum of the values */ public StatisticalSummaryValues(double mean, double variance, long n, double max, double min, double sum) { super(); this.mean = mean; this.variance = variance; this.n = n; this.max = max; this.min = min; this.sum = sum; } /** * @return Returns the max. */ public double getMax() { return max; } /** * @return Returns the mean. */ public double getMean() { return mean; } /** * @return Returns the min. */ public double getMin() { return min; } /** * @return Returns the number of values. */ public long getN() { return n; } /** * @return Returns the sum. */ public double getSum() { return sum; } /** * @return Returns the standard deviation */ public double getStandardDeviation() { return FastMath.sqrt(variance); } /** * @return Returns the variance. */ public double getVariance() { return variance; } /** * Returns true iff object is a * StatisticalSummaryValues instance and all statistics have * the same values as this. * * @param object the object to test equality against. * @return true if object equals this */ @Override public boolean equals(Object object) { if (object == this ) { return true; } if (object instanceof StatisticalSummaryValues == false) { return false; } StatisticalSummaryValues stat = (StatisticalSummaryValues) object; return MathUtils.equalsIncludingNaN(stat.getMax(), getMax()) && MathUtils.equalsIncludingNaN(stat.getMean(), getMean()) && MathUtils.equalsIncludingNaN(stat.getMin(), getMin()) && MathUtils.equalsIncludingNaN(stat.getN(), getN()) && MathUtils.equalsIncludingNaN(stat.getSum(), getSum()) && MathUtils.equalsIncludingNaN(stat.getVariance(), getVariance()); } /** * Returns hash code based on values of statistics * * @return hash code */ @Override public int hashCode() { int result = 31 + MathUtils.hash(getMax()); result = result * 31 + MathUtils.hash(getMean()); result = result * 31 + MathUtils.hash(getMin()); result = result * 31 + MathUtils.hash(getN()); result = result * 31 + MathUtils.hash(getSum()); result = result * 31 + MathUtils.hash(getVariance()); return result; } /** * Generates a text report displaying values of statistics. * Each statistic is displayed on a separate line. * * @return String with line feeds displaying statistics */ @Override public String toString() { StringBuilder outBuffer = new StringBuilder(); String endl = "\n"; outBuffer.append("StatisticalSummaryValues:").append(endl); outBuffer.append("n: ").append(getN()).append(endl); outBuffer.append("min: ").append(getMin()).append(endl); outBuffer.append("max: ").append(getMax()).append(endl); outBuffer.append("mean: ").append(getMean()).append(endl); outBuffer.append("std dev: ").append(getStandardDeviation()) .append(endl); outBuffer.append("variance: ").append(getVariance()).append(endl); outBuffer.append("sum: ").append(getSum()).append(endl); return outBuffer.toString(); } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStati100644 1750 1750 17452 11532241247 32660 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Implementation of * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics} that * is safe to use in a multithreaded environment. Multiple threads can safely * operate on a single instance without causing runtime exceptions due to race * conditions. In effect, this implementation makes modification and access * methods atomic operations for a single instance. That is to say, as one * thread is computing a statistic from the instance, no other thread can modify * the instance nor compute another statistic. * * @since 1.2 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class SynchronizedSummaryStatistics extends SummaryStatistics { /** Serialization UID */ private static final long serialVersionUID = 1909861009042253704L; /** * Construct a SynchronizedSummaryStatistics instance */ public SynchronizedSummaryStatistics() { super(); } /** * A copy constructor. Creates a deep-copy of the {@code original}. * * @param original the {@code SynchronizedSummaryStatistics} instance to copy */ public SynchronizedSummaryStatistics(SynchronizedSummaryStatistics original) { copy(original, this); } /** * {@inheritDoc} */ @Override public synchronized StatisticalSummary getSummary() { return super.getSummary(); } /** * {@inheritDoc} */ @Override public synchronized void addValue(double value) { super.addValue(value); } /** * {@inheritDoc} */ @Override public synchronized long getN() { return super.getN(); } /** * {@inheritDoc} */ @Override public synchronized double getSum() { return super.getSum(); } /** * {@inheritDoc} */ @Override public synchronized double getSumsq() { return super.getSumsq(); } /** * {@inheritDoc} */ @Override public synchronized double getMean() { return super.getMean(); } /** * {@inheritDoc} */ @Override public synchronized double getStandardDeviation() { return super.getStandardDeviation(); } /** * {@inheritDoc} */ @Override public synchronized double getVariance() { return super.getVariance(); } /** * {@inheritDoc} */ @Override public synchronized double getMax() { return super.getMax(); } /** * {@inheritDoc} */ @Override public synchronized double getMin() { return super.getMin(); } /** * {@inheritDoc} */ @Override public synchronized double getGeometricMean() { return super.getGeometricMean(); } /** * {@inheritDoc} */ @Override public synchronized String toString() { return super.toString(); } /** * {@inheritDoc} */ @Override public synchronized void clear() { super.clear(); } /** * {@inheritDoc} */ @Override public synchronized boolean equals(Object object) { return super.equals(object); } /** * {@inheritDoc} */ @Override public synchronized int hashCode() { return super.hashCode(); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getSumImpl() { return super.getSumImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumImpl(StorelessUnivariateStatistic sumImpl) { super.setSumImpl(sumImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getSumsqImpl() { return super.getSumsqImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) { super.setSumsqImpl(sumsqImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getMinImpl() { return super.getMinImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMinImpl(StorelessUnivariateStatistic minImpl) { super.setMinImpl(minImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getMaxImpl() { return super.getMaxImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMaxImpl(StorelessUnivariateStatistic maxImpl) { super.setMaxImpl(maxImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getSumLogImpl() { return super.getSumLogImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) { super.setSumLogImpl(sumLogImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getGeoMeanImpl() { return super.getGeoMeanImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) { super.setGeoMeanImpl(geoMeanImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getMeanImpl() { return super.getMeanImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setMeanImpl(StorelessUnivariateStatistic meanImpl) { super.setMeanImpl(meanImpl); } /** * {@inheritDoc} */ @Override public synchronized StorelessUnivariateStatistic getVarianceImpl() { return super.getVarianceImpl(); } /** * {@inheritDoc} */ @Override public synchronized void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) { super.setVarianceImpl(varianceImpl); } /** * Returns a copy of this SynchronizedSummaryStatistics instance with the * same internal state. * * @return a copy of this */ @Override public synchronized SynchronizedSummaryStatistics copy() { SynchronizedSummaryStatistics result = new SynchronizedSummaryStatistics(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    *

                    Acquires synchronization lock on source, then dest before copying.

                    * * @param source SynchronizedSummaryStatistics to copy * @param dest SynchronizedSummaryStatistics to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(SynchronizedSummaryStatistics source, SynchronizedSummaryStatistics dest) { synchronized (source) { synchronized (dest) { SummaryStatistics.copy(source, dest); } } } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.ja100644 1750 1750 61071 11532241247 32537 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.moment.GeometricMean; import org.apache.commons.math.stat.descriptive.moment.Kurtosis; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.Skewness; import org.apache.commons.math.stat.descriptive.moment.Variance; import org.apache.commons.math.stat.descriptive.rank.Max; import org.apache.commons.math.stat.descriptive.rank.Min; import org.apache.commons.math.stat.descriptive.rank.Percentile; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; import org.apache.commons.math.util.ResizableDoubleArray; import org.apache.commons.math.util.FastMath; /** * Maintains a dataset of values of a single variable and computes descriptive * statistics based on stored data. The {@link #getWindowSize() windowSize} * property sets a limit on the number of values that can be stored in the * dataset. The default value, INFINITE_WINDOW, puts no limit on the size of * the dataset. This value should be used with caution, as the backing store * will grow without bound in this case. For very large datasets, * {@link SummaryStatistics}, which does not store the dataset, should be used * instead of this class. If windowSize is not INFINITE_WINDOW and * more values are added than can be stored in the dataset, new values are * added in a "rolling" manner, with new values replacing the "oldest" values * in the dataset. * *

                    Note: this class is not threadsafe. Use * {@link SynchronizedDescriptiveStatistics} if concurrent access from multiple * threads is required.

                    * * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $ */ public class DescriptiveStatistics implements StatisticalSummary, Serializable { /** * Represents an infinite window size. When the {@link #getWindowSize()} * returns this value, there is no limit to the number of data values * that can be stored in the dataset. */ public static final int INFINITE_WINDOW = -1; /** Serialization UID */ private static final long serialVersionUID = 4133067267405273064L; /** Name of the setQuantile method. */ private static final String SET_QUANTILE_METHOD_NAME = "setQuantile"; /** hold the window size **/ protected int windowSize = INFINITE_WINDOW; /** * Stored data values */ protected ResizableDoubleArray eDA = new ResizableDoubleArray(); /** Mean statistic implementation - can be reset by setter. */ private UnivariateStatistic meanImpl = new Mean(); /** Geometric mean statistic implementation - can be reset by setter. */ private UnivariateStatistic geometricMeanImpl = new GeometricMean(); /** Kurtosis statistic implementation - can be reset by setter. */ private UnivariateStatistic kurtosisImpl = new Kurtosis(); /** Maximum statistic implementation - can be reset by setter. */ private UnivariateStatistic maxImpl = new Max(); /** Minimum statistic implementation - can be reset by setter. */ private UnivariateStatistic minImpl = new Min(); /** Percentile statistic implementation - can be reset by setter. */ private UnivariateStatistic percentileImpl = new Percentile(); /** Skewness statistic implementation - can be reset by setter. */ private UnivariateStatistic skewnessImpl = new Skewness(); /** Variance statistic implementation - can be reset by setter. */ private UnivariateStatistic varianceImpl = new Variance(); /** Sum of squares statistic implementation - can be reset by setter. */ private UnivariateStatistic sumsqImpl = new SumOfSquares(); /** Sum statistic implementation - can be reset by setter. */ private UnivariateStatistic sumImpl = new Sum(); /** * Construct a DescriptiveStatistics instance with an infinite window */ public DescriptiveStatistics() { } /** * Construct a DescriptiveStatistics instance with the specified window * * @param window the window size. */ public DescriptiveStatistics(int window) { setWindowSize(window); } /** * Construct a DescriptiveStatistics instance with an infinite window * and the initial data values in double[] initialDoubleArray. * If initialDoubleArray is null, then this constructor corresponds to * DescriptiveStatistics() * * @param initialDoubleArray the initial double[]. */ public DescriptiveStatistics(double[] initialDoubleArray) { if (initialDoubleArray != null) { eDA = new ResizableDoubleArray(initialDoubleArray); } } /** * Copy constructor. Construct a new DescriptiveStatistics instance that * is a copy of original. * * @param original DescriptiveStatistics instance to copy */ public DescriptiveStatistics(DescriptiveStatistics original) { copy(original, this); } /** * Adds the value to the dataset. If the dataset is at the maximum size * (i.e., the number of stored elements equals the currently configured * windowSize), the first (oldest) element in the dataset is discarded * to make room for the new value. * * @param v the value to be added */ public void addValue(double v) { if (windowSize != INFINITE_WINDOW) { if (getN() == windowSize) { eDA.addElementRolling(v); } else if (getN() < windowSize) { eDA.addElement(v); } } else { eDA.addElement(v); } } /** * Removes the most recent value from the dataset. */ public void removeMostRecentValue() { eDA.discardMostRecentElements(1); } /** * Replaces the most recently stored value with the given value. * There must be at least one element stored to call this method. * * @param v the value to replace the most recent stored value * @return replaced value */ public double replaceMostRecentValue(double v) { return eDA.substituteMostRecentElement(v); } /** * Returns the * arithmetic mean of the available values * @return The mean or Double.NaN if no values have been added. */ public double getMean() { return apply(meanImpl); } /** * Returns the * geometric mean of the available values * @return The geometricMean, Double.NaN if no values have been added, * or if the product of the available values is less than or equal to 0. */ public double getGeometricMean() { return apply(geometricMeanImpl); } /** * Returns the variance of the available values. * @return The variance, Double.NaN if no values have been added * or 0.0 for a single value set. */ public double getVariance() { return apply(varianceImpl); } /** * Returns the standard deviation of the available values. * @return The standard deviation, Double.NaN if no values have been added * or 0.0 for a single value set. */ public double getStandardDeviation() { double stdDev = Double.NaN; if (getN() > 0) { if (getN() > 1) { stdDev = FastMath.sqrt(getVariance()); } else { stdDev = 0.0; } } return stdDev; } /** * Returns the skewness of the available values. Skewness is a * measure of the asymmetry of a given distribution. * @return The skewness, Double.NaN if no values have been added * or 0.0 for a value set <=2. */ public double getSkewness() { return apply(skewnessImpl); } /** * Returns the Kurtosis of the available values. Kurtosis is a * measure of the "peakedness" of a distribution * @return The kurtosis, Double.NaN if no values have been added, or 0.0 * for a value set <=3. */ public double getKurtosis() { return apply(kurtosisImpl); } /** * Returns the maximum of the available values * @return The max or Double.NaN if no values have been added. */ public double getMax() { return apply(maxImpl); } /** * Returns the minimum of the available values * @return The min or Double.NaN if no values have been added. */ public double getMin() { return apply(minImpl); } /** * Returns the number of available values * @return The number of available values */ public long getN() { return eDA.getNumElements(); } /** * Returns the sum of the values that have been added to Univariate. * @return The sum or Double.NaN if no values have been added */ public double getSum() { return apply(sumImpl); } /** * Returns the sum of the squares of the available values. * @return The sum of the squares or Double.NaN if no * values have been added. */ public double getSumsq() { return apply(sumsqImpl); } /** * Resets all statistics and storage */ public void clear() { eDA.clear(); } /** * Returns the maximum number of values that can be stored in the * dataset, or INFINITE_WINDOW (-1) if there is no limit. * * @return The current window size or -1 if its Infinite. */ public int getWindowSize() { return windowSize; } /** * WindowSize controls the number of values which contribute * to the reported statistics. For example, if * windowSize is set to 3 and the values {1,2,3,4,5} * have been added in that order * then the available values are {3,4,5} and all * reported statistics will be based on these values * @param windowSize sets the size of the window. */ public void setWindowSize(int windowSize) { if (windowSize < 1) { if (windowSize != INFINITE_WINDOW) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_WINDOW_SIZE, windowSize); } } this.windowSize = windowSize; // We need to check to see if we need to discard elements // from the front of the array. If the windowSize is less than // the current number of elements. if (windowSize != INFINITE_WINDOW && windowSize < eDA.getNumElements()) { eDA.discardFrontElements(eDA.getNumElements() - windowSize); } } /** * Returns the current set of values in an array of double primitives. * The order of addition is preserved. The returned array is a fresh * copy of the underlying data -- i.e., it is not a reference to the * stored data. * * @return returns the current set of numbers in the order in which they * were added to this set */ public double[] getValues() { return eDA.getElements(); } /** * Returns the current set of values in an array of double primitives, * sorted in ascending order. The returned array is a fresh * copy of the underlying data -- i.e., it is not a reference to the * stored data. * @return returns the current set of * numbers sorted in ascending order */ public double[] getSortedValues() { double[] sort = getValues(); Arrays.sort(sort); return sort; } /** * Returns the element at the specified index * @param index The Index of the element * @return return the element at the specified index */ public double getElement(int index) { return eDA.getElement(index); } /** * Returns an estimate for the pth percentile of the stored values. *

                    * The implementation provided here follows the first estimation procedure presented * here. *

                    * Preconditions:

                      *
                    • 0 < p ≤ 100 (otherwise an * IllegalArgumentException is thrown)
                    • *
                    • at least one value must be stored (returns Double.NaN * otherwise)
                    • *

                    * * @param p the requested percentile (scaled from 0 - 100) * @return An estimate for the pth percentile of the stored data * @throws IllegalStateException if percentile implementation has been * overridden and the supplied implementation does not support setQuantile * values */ public double getPercentile(double p) { if (percentileImpl instanceof Percentile) { ((Percentile) percentileImpl).setQuantile(p); } else { try { percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME, new Class[] {Double.TYPE}).invoke(percentileImpl, new Object[] {Double.valueOf(p)}); } catch (NoSuchMethodException e1) { // Setter guard should prevent throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD, percentileImpl.getClass().getName(), SET_QUANTILE_METHOD_NAME); } catch (IllegalAccessException e2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD, SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName()); } catch (InvocationTargetException e3) { throw MathRuntimeException.createIllegalArgumentException(e3.getCause()); } } return apply(percentileImpl); } /** * Generates a text report displaying univariate statistics from values * that have been added. Each statistic is displayed on a separate * line. * * @return String with line feeds displaying statistics */ @Override public String toString() { StringBuilder outBuffer = new StringBuilder(); String endl = "\n"; outBuffer.append("DescriptiveStatistics:").append(endl); outBuffer.append("n: ").append(getN()).append(endl); outBuffer.append("min: ").append(getMin()).append(endl); outBuffer.append("max: ").append(getMax()).append(endl); outBuffer.append("mean: ").append(getMean()).append(endl); outBuffer.append("std dev: ").append(getStandardDeviation()) .append(endl); outBuffer.append("median: ").append(getPercentile(50)).append(endl); outBuffer.append("skewness: ").append(getSkewness()).append(endl); outBuffer.append("kurtosis: ").append(getKurtosis()).append(endl); return outBuffer.toString(); } /** * Apply the given statistic to the data associated with this set of statistics. * @param stat the statistic to apply * @return the computed value of the statistic. */ public double apply(UnivariateStatistic stat) { return stat.evaluate(eDA.getInternalValues(), eDA.start(), eDA.getNumElements()); } // Implementation getters and setter /** * Returns the currently configured mean implementation. * * @return the UnivariateStatistic implementing the mean * @since 1.2 */ public synchronized UnivariateStatistic getMeanImpl() { return meanImpl; } /** *

                    Sets the implementation for the mean.

                    * * @param meanImpl the UnivariateStatistic instance to use * for computing the mean * @since 1.2 */ public synchronized void setMeanImpl(UnivariateStatistic meanImpl) { this.meanImpl = meanImpl; } /** * Returns the currently configured geometric mean implementation. * * @return the UnivariateStatistic implementing the geometric mean * @since 1.2 */ public synchronized UnivariateStatistic getGeometricMeanImpl() { return geometricMeanImpl; } /** *

                    Sets the implementation for the gemoetric mean.

                    * * @param geometricMeanImpl the UnivariateStatistic instance to use * for computing the geometric mean * @since 1.2 */ public synchronized void setGeometricMeanImpl( UnivariateStatistic geometricMeanImpl) { this.geometricMeanImpl = geometricMeanImpl; } /** * Returns the currently configured kurtosis implementation. * * @return the UnivariateStatistic implementing the kurtosis * @since 1.2 */ public synchronized UnivariateStatistic getKurtosisImpl() { return kurtosisImpl; } /** *

                    Sets the implementation for the kurtosis.

                    * * @param kurtosisImpl the UnivariateStatistic instance to use * for computing the kurtosis * @since 1.2 */ public synchronized void setKurtosisImpl(UnivariateStatistic kurtosisImpl) { this.kurtosisImpl = kurtosisImpl; } /** * Returns the currently configured maximum implementation. * * @return the UnivariateStatistic implementing the maximum * @since 1.2 */ public synchronized UnivariateStatistic getMaxImpl() { return maxImpl; } /** *

                    Sets the implementation for the maximum.

                    * * @param maxImpl the UnivariateStatistic instance to use * for computing the maximum * @since 1.2 */ public synchronized void setMaxImpl(UnivariateStatistic maxImpl) { this.maxImpl = maxImpl; } /** * Returns the currently configured minimum implementation. * * @return the UnivariateStatistic implementing the minimum * @since 1.2 */ public synchronized UnivariateStatistic getMinImpl() { return minImpl; } /** *

                    Sets the implementation for the minimum.

                    * * @param minImpl the UnivariateStatistic instance to use * for computing the minimum * @since 1.2 */ public synchronized void setMinImpl(UnivariateStatistic minImpl) { this.minImpl = minImpl; } /** * Returns the currently configured percentile implementation. * * @return the UnivariateStatistic implementing the percentile * @since 1.2 */ public synchronized UnivariateStatistic getPercentileImpl() { return percentileImpl; } /** * Sets the implementation to be used by {@link #getPercentile(double)}. * The supplied UnivariateStatistic must provide a * setQuantile(double) method; otherwise * IllegalArgumentException is thrown. * * @param percentileImpl the percentileImpl to set * @throws IllegalArgumentException if the supplied implementation does not * provide a setQuantile method * @since 1.2 */ public synchronized void setPercentileImpl( UnivariateStatistic percentileImpl) { try { percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME, new Class[] {Double.TYPE}).invoke(percentileImpl, new Object[] {Double.valueOf(50.0d)}); } catch (NoSuchMethodException e1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD, percentileImpl.getClass().getName(), SET_QUANTILE_METHOD_NAME); } catch (IllegalAccessException e2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD, SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName()); } catch (InvocationTargetException e3) { throw MathRuntimeException.createIllegalArgumentException(e3.getCause()); } this.percentileImpl = percentileImpl; } /** * Returns the currently configured skewness implementation. * * @return the UnivariateStatistic implementing the skewness * @since 1.2 */ public synchronized UnivariateStatistic getSkewnessImpl() { return skewnessImpl; } /** *

                    Sets the implementation for the skewness.

                    * * @param skewnessImpl the UnivariateStatistic instance to use * for computing the skewness * @since 1.2 */ public synchronized void setSkewnessImpl( UnivariateStatistic skewnessImpl) { this.skewnessImpl = skewnessImpl; } /** * Returns the currently configured variance implementation. * * @return the UnivariateStatistic implementing the variance * @since 1.2 */ public synchronized UnivariateStatistic getVarianceImpl() { return varianceImpl; } /** *

                    Sets the implementation for the variance.

                    * * @param varianceImpl the UnivariateStatistic instance to use * for computing the variance * @since 1.2 */ public synchronized void setVarianceImpl( UnivariateStatistic varianceImpl) { this.varianceImpl = varianceImpl; } /** * Returns the currently configured sum of squares implementation. * * @return the UnivariateStatistic implementing the sum of squares * @since 1.2 */ public synchronized UnivariateStatistic getSumsqImpl() { return sumsqImpl; } /** *

                    Sets the implementation for the sum of squares.

                    * * @param sumsqImpl the UnivariateStatistic instance to use * for computing the sum of squares * @since 1.2 */ public synchronized void setSumsqImpl(UnivariateStatistic sumsqImpl) { this.sumsqImpl = sumsqImpl; } /** * Returns the currently configured sum implementation. * * @return the UnivariateStatistic implementing the sum * @since 1.2 */ public synchronized UnivariateStatistic getSumImpl() { return sumImpl; } /** *

                    Sets the implementation for the sum.

                    * * @param sumImpl the UnivariateStatistic instance to use * for computing the sum * @since 1.2 */ public synchronized void setSumImpl(UnivariateStatistic sumImpl) { this.sumImpl = sumImpl; } /** * Returns a copy of this DescriptiveStatistics instance with the same internal state. * * @return a copy of this */ public DescriptiveStatistics copy() { DescriptiveStatistics result = new DescriptiveStatistics(); copy(this, result); return result; } /** * Copies source to dest. *

                    Neither source nor dest can be null.

                    * * @param source DescriptiveStatistics to copy * @param dest DescriptiveStatistics to copy to * @throws NullPointerException if either source or dest is null */ public static void copy(DescriptiveStatistics source, DescriptiveStatistics dest) { // Copy data and window size dest.eDA = source.eDA.copy(); dest.windowSize = source.windowSize; // Copy implementations dest.maxImpl = source.maxImpl.copy(); dest.meanImpl = source.meanImpl.copy(); dest.minImpl = source.minImpl.copy(); dest.sumImpl = source.sumImpl.copy(); dest.varianceImpl = source.varianceImpl.copy(); dest.sumsqImpl = source.sumsqImpl.copy(); dest.geometricMeanImpl = source.geometricMeanImpl.copy(); dest.kurtosisImpl = source.kurtosisImpl; dest.skewnessImpl = source.skewnessImpl; dest.percentileImpl = source.percentileImpl; } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStati100644 1750 1750 6150 11532241247 32607 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Extends the definition of {@link UnivariateStatistic} with * {@link #increment} and {@link #incrementAll(double[])} methods for adding * values and updating internal state. *

                    * This interface is designed to be used for calculating statistics that can be * computed in one pass through the data without storing the full array of * sample values.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface StorelessUnivariateStatistic extends UnivariateStatistic { /** * Updates the internal state of the statistic to reflect the addition of the new value. * @param d the new value. */ void increment(double d); /** * Updates the internal state of the statistic to reflect addition of * all values in the values array. Does not clear the statistic first -- * i.e., the values are added incrementally to the dataset. * * @param values array holding the new values to add * @throws IllegalArgumentException if the array is null */ void incrementAll(double[] values); /** * Updates the internal state of the statistic to reflect addition of * the values in the designated portion of the values array. Does not * clear the statistic first -- i.e., the values are added * incrementally to the dataset. * * @param values array holding the new values to add * @param start the array index of the first value to add * @param length the number of elements to add * @throws IllegalArgumentException if the array is null or the index */ void incrementAll(double[] values, int start, int length); /** * Returns the current value of the Statistic. * @return value of the statistic, Double.NaN if it * has been cleared or just instantiated. */ double getResult(); /** * Returns the number of values that have been added. * @return the number of values. */ long getN(); /** * Clears the internal state of the Statistic */ void clear(); /** * Returns a copy of the statistic with the same internal state. * * @return a copy of the statistic */ StorelessUnivariateStatistic copy(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummary.java100644 1750 1750 4424 11532241247 32353 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; /** * Reporting interface for basic univariate statistics. * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface StatisticalSummary { /** * Returns the * arithmetic mean of the available values * @return The mean or Double.NaN if no values have been added. */ double getMean(); /** * Returns the variance of the available values. * @return The variance, Double.NaN if no values have been added * or 0.0 for a single value set. */ double getVariance(); /** * Returns the standard deviation of the available values. * @return The standard deviation, Double.NaN if no values have been added * or 0.0 for a single value set. */ double getStandardDeviation(); /** * Returns the maximum of the available values * @return The max or Double.NaN if no values have been added. */ double getMax(); /** * Returns the minimum of the available values * @return The min or Double.NaN if no values have been added. */ double getMin(); /** * Returns the number of available values * @return The number of available values */ long getN(); /** * Returns the sum of the values that have been added to Univariate. * @return The sum or Double.NaN if no values have been added */ double getSum(); } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatis100644 1750 1750 20401 11532241247 32565 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.descriptive; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Abstract base class for all implementations of the * {@link UnivariateStatistic} interface. *

                    * Provides a default implementation of evaluate(double[]), * delegating to evaluate(double[], int, int) in the natural way. *

                    *

                    * Also includes a test method that performs generic parameter * validation for the evaluate methods.

                    * * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ */ public abstract class AbstractUnivariateStatistic implements UnivariateStatistic { /** Stored data. */ private double[] storedData; /** * Set the data array. *

                    * The stored value is a copy of the parameter array, not the array itself *

                    * @param values data array to store (may be null to remove stored data) * @see #evaluate() */ public void setData(final double[] values) { storedData = (values == null) ? null : values.clone(); } /** * Get a copy of the stored data array. * @return copy of the stored data array (may be null) */ public double[] getData() { return (storedData == null) ? null : storedData.clone(); } /** * Get a reference to the stored data array. * @return reference to the stored data array (may be null) */ protected double[] getDataRef() { return storedData; } /** * Set the data array. * @param values data array to store * @param begin the index of the first element to include * @param length the number of elements to include * @see #evaluate() */ public void setData(final double[] values, final int begin, final int length) { storedData = new double[length]; System.arraycopy(values, begin, storedData, 0, length); } /** * Returns the result of evaluating the statistic over the stored data. *

                    * The stored array is the one which was set by previous calls to *

                    * @return the value of the statistic applied to the stored data */ public double evaluate() { return evaluate(storedData); } /** * {@inheritDoc} */ public double evaluate(final double[] values) { test(values, 0, 0); return evaluate(values, 0, values.length); } /** * {@inheritDoc} */ public abstract double evaluate(final double[] values, final int begin, final int length); /** * {@inheritDoc} */ public abstract UnivariateStatistic copy(); /** * This method is used by evaluate(double[], int, int) methods * to verify that the input parameters designate a subarray of positive length. *

                    *

                      *
                    • returns true iff the parameters designate a subarray of * positive length
                    • *
                    • throws IllegalArgumentException if the array is null or * or the indices are invalid
                    • *
                    • returns false
                    • if the array is non-null, but * length is 0. *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return true if the parameters are valid and designate a subarray of positive length * @throws IllegalArgumentException if the indices are invalid or the array is null */ protected boolean test( final double[] values, final int begin, final int length) { if (values == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (begin < 0) { throw new NotPositiveException(LocalizedFormats.START_POSITION, begin); } if (length < 0) { throw new NotPositiveException(LocalizedFormats.LENGTH, length); } if (begin + length > values.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END); } if (length == 0) { return false; } return true; } /** * This method is used by evaluate(double[], double[], int, int) methods * to verify that the begin and length parameters designate a subarray of positive length * and the weights are all non-negative, non-NaN, finite, and not all zero. *

                    *

                      *
                    • returns true iff the parameters designate a subarray of * positive length and the weights array contains legitimate values.
                    • *
                    • throws IllegalArgumentException if any of the following are true: *
                      • the values array is null
                      • *
                      • the weights array is null
                      • *
                      • the weights array does not have the same length as the values array
                      • *
                      • the weights array contains one or more infinite values
                      • *
                      • the weights array contains one or more NaN values
                      • *
                      • the weights array contains negative values
                      • *
                      • the start and length arguments do not determine a valid array
                      *
                    • *
                    • returns false
                    • if the array is non-null, but * length is 0. *

                    * * @param values the input array * @param weights the weights array * @param begin index of the first array element to include * @param length the number of elements to include * @return true if the parameters are valid and designate a subarray of positive length * @throws IllegalArgumentException if the indices are invalid or the array is null * @since 2.1 */ protected boolean test( final double[] values, final double[] weights, final int begin, final int length) { if (weights == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (weights.length != values.length) { throw new DimensionMismatchException(weights.length, values.length); } boolean containsPositiveWeight = false; for (int i = begin; i < begin + length; i++) { if (Double.isNaN(weights[i])) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NAN_ELEMENT_AT_INDEX, i); } if (Double.isInfinite(weights[i])) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INFINITE_ARRAY_ELEMENT, weights[i], i); } if (weights[i] < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, i, weights[i]); } if (!containsPositiveWeight && weights[i] > 0.0) { containsPositiveWeight = true; } } if (!containsPositiveWeight) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO); } return test(values, begin, length); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/Frequency.java100644 1750 1750 45362 11532241247 26157 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat; import java.io.Serializable; import java.text.NumberFormat; import java.util.Iterator; import java.util.Comparator; import java.util.TreeMap; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Maintains a frequency distribution. *

                    * Accepts int, long, char or Comparable values. New values added must be * comparable to those that have been added, otherwise the add method will * throw an IllegalArgumentException.

                    *

                    * Integer values (int, long, Integer, Long) are not distinguished by type -- * i.e. addValue(Long.valueOf(2)), addValue(2), addValue(2l) all have * the same effect (similarly for arguments to getCount, etc.).

                    *

                    * char values are converted by addValue to Character instances. * As such, these values are not comparable to integral values, so attempts * to combine integral types with chars in a frequency distribution will fail. *

                    *

                    * The values are ordered using the default (natural order), unless a * Comparator is supplied in the constructor.

                    * * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $ */ public class Frequency implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -3845586908418844111L; /** underlying collection */ private final TreeMap, Long> freqTable; /** * Default constructor. */ public Frequency() { freqTable = new TreeMap, Long>(); } /** * Constructor allowing values Comparator to be specified. * * @param comparator Comparator used to order values */ @SuppressWarnings("unchecked") // TODO is the cast OK? public Frequency(Comparator comparator) { freqTable = new TreeMap, Long>((Comparator>) comparator); } /** * Return a string representation of this frequency * distribution. * * @return a string representation. */ @Override public String toString() { NumberFormat nf = NumberFormat.getPercentInstance(); StringBuilder outBuffer = new StringBuilder(); outBuffer.append("Value \t Freq. \t Pct. \t Cum Pct. \n"); Iterator> iter = freqTable.keySet().iterator(); while (iter.hasNext()) { Comparable value = iter.next(); outBuffer.append(value); outBuffer.append('\t'); outBuffer.append(getCount(value)); outBuffer.append('\t'); outBuffer.append(nf.format(getPct(value))); outBuffer.append('\t'); outBuffer.append(nf.format(getCumPct(value))); outBuffer.append('\n'); } return outBuffer.toString(); } /** * Adds 1 to the frequency count for v. *

                    * If other objects have already been added to this Frequency, v must * be comparable to those that have already been added. *

                    * * @param v the value to add. * @throws IllegalArgumentException if v is not Comparable, * or is not comparable with previous entries * @deprecated use {@link #addValue(Comparable)} instead */ @Deprecated public void addValue(Object v) { if (v instanceof Comparable){ addValue((Comparable) v); } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CLASS_DOESNT_IMPLEMENT_COMPARABLE, v.getClass().getName()); } } /** * Adds 1 to the frequency count for v. *

                    * If other objects have already been added to this Frequency, v must * be comparable to those that have already been added. *

                    * * @param v the value to add. * @throws IllegalArgumentException if v is not comparable with previous entries */ public void addValue(Comparable v){ Comparable obj = v; if (v instanceof Integer) { obj = Long.valueOf(((Integer) v).longValue()); } try { Long count = freqTable.get(obj); if (count == null) { freqTable.put(obj, Long.valueOf(1)); } else { freqTable.put(obj, Long.valueOf(count.longValue() + 1)); } } catch (ClassCastException ex) { //TreeMap will throw ClassCastException if v is not comparable throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES, v.getClass().getName()); } } /** * Adds 1 to the frequency count for v. * * @param v the value to add. */ public void addValue(int v) { addValue(Long.valueOf(v)); } /** * Adds 1 to the frequency count for v. * * @param v the value to add. * @deprecated to be removed in math 3.0 */ @Deprecated public void addValue(Integer v) { addValue(Long.valueOf(v.longValue())); } /** * Adds 1 to the frequency count for v. * * @param v the value to add. */ public void addValue(long v) { addValue(Long.valueOf(v)); } /** * Adds 1 to the frequency count for v. * * @param v the value to add. */ public void addValue(char v) { addValue(Character.valueOf(v)); } /** Clears the frequency table */ public void clear() { freqTable.clear(); } /** * Returns an Iterator over the set of values that have been added. *

                    * If added values are integral (i.e., integers, longs, Integers, or Longs), * they are converted to Longs when they are added, so the objects returned * by the Iterator will in this case be Longs.

                    * * @return values Iterator */ public Iterator> valuesIterator() { return freqTable.keySet().iterator(); } //------------------------------------------------------------------------- /** * Returns the sum of all frequencies. * * @return the total frequency count. */ public long getSumFreq() { long result = 0; Iterator iterator = freqTable.values().iterator(); while (iterator.hasNext()) { result += iterator.next().longValue(); } return result; } /** * Returns the number of values = v. * Returns 0 if the value is not comparable. * * @param v the value to lookup. * @return the frequency of v. * @deprecated replaced by {@link #getCount(Comparable)} as of 2.0 */ @Deprecated public long getCount(Object v) { return getCount((Comparable) v); } /** * Returns the number of values = v. * Returns 0 if the value is not comparable. * * @param v the value to lookup. * @return the frequency of v. */ public long getCount(Comparable v) { if (v instanceof Integer) { return getCount(((Integer) v).longValue()); } long result = 0; try { Long count = freqTable.get(v); if (count != null) { result = count.longValue(); } } catch (ClassCastException ex) { // ignore and return 0 -- ClassCastException will be thrown if value is not comparable } return result; } /** * Returns the number of values = v. * * @param v the value to lookup. * @return the frequency of v. */ public long getCount(int v) { return getCount(Long.valueOf(v)); } /** * Returns the number of values = v. * * @param v the value to lookup. * @return the frequency of v. */ public long getCount(long v) { return getCount(Long.valueOf(v)); } /** * Returns the number of values = v. * * @param v the value to lookup. * @return the frequency of v. */ public long getCount(char v) { return getCount(Character.valueOf(v)); } /** * Returns the number of values in the frequency table. * * @return the number of unique values that have been added to the frequency table. * @see #valuesIterator() */ public int getUniqueCount(){ return freqTable.keySet().size(); } //------------------------------------------------------------- /** * Returns the percentage of values that are equal to v * (as a proportion between 0 and 1). *

                    * Returns Double.NaN if no values have been added.

                    * * @param v the value to lookup * @return the proportion of values equal to v * @deprecated replaced by {@link #getPct(Comparable)} as of 2.0 */ @Deprecated public double getPct(Object v) { return getPct((Comparable) v); } /** * Returns the percentage of values that are equal to v * (as a proportion between 0 and 1). *

                    * Returns Double.NaN if no values have been added.

                    * * @param v the value to lookup * @return the proportion of values equal to v */ public double getPct(Comparable v) { final long sumFreq = getSumFreq(); if (sumFreq == 0) { return Double.NaN; } return (double) getCount(v) / (double) sumFreq; } /** * Returns the percentage of values that are equal to v * (as a proportion between 0 and 1). * * @param v the value to lookup * @return the proportion of values equal to v */ public double getPct(int v) { return getPct(Long.valueOf(v)); } /** * Returns the percentage of values that are equal to v * (as a proportion between 0 and 1). * * @param v the value to lookup * @return the proportion of values equal to v */ public double getPct(long v) { return getPct(Long.valueOf(v)); } /** * Returns the percentage of values that are equal to v * (as a proportion between 0 and 1). * * @param v the value to lookup * @return the proportion of values equal to v */ public double getPct(char v) { return getPct(Character.valueOf(v)); } //----------------------------------------------------------------------------------------- /** * Returns the cumulative frequency of values less than or equal to v. *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup. * @return the proportion of values equal to v * @deprecated replaced by {@link #getCumFreq(Comparable)} as of 2.0 */ @Deprecated public long getCumFreq(Object v) { return getCumFreq((Comparable) v); } /** * Returns the cumulative frequency of values less than or equal to v. *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup. * @return the proportion of values equal to v */ public long getCumFreq(Comparable v) { if (getSumFreq() == 0) { return 0; } if (v instanceof Integer) { return getCumFreq(((Integer) v).longValue()); } @SuppressWarnings("unchecked") // OK, freqTable is Comparable Comparator> c = (Comparator>) freqTable.comparator(); if (c == null) { c = new NaturalComparator(); } long result = 0; try { Long value = freqTable.get(v); if (value != null) { result = value.longValue(); } } catch (ClassCastException ex) { return result; // v is not comparable } if (c.compare(v, freqTable.firstKey()) < 0) { return 0; // v is comparable, but less than first value } if (c.compare(v, freqTable.lastKey()) >= 0) { return getSumFreq(); // v is comparable, but greater than the last value } Iterator> values = valuesIterator(); while (values.hasNext()) { Comparable nextValue = values.next(); if (c.compare(v, nextValue) > 0) { result += getCount(nextValue); } else { return result; } } return result; } /** * Returns the cumulative frequency of values less than or equal to v. *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values equal to v */ public long getCumFreq(int v) { return getCumFreq(Long.valueOf(v)); } /** * Returns the cumulative frequency of values less than or equal to v. *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values equal to v */ public long getCumFreq(long v) { return getCumFreq(Long.valueOf(v)); } /** * Returns the cumulative frequency of values less than or equal to v. *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values equal to v */ public long getCumFreq(char v) { return getCumFreq(Character.valueOf(v)); } //---------------------------------------------------------------------------------------------- /** * Returns the cumulative percentage of values less than or equal to v * (as a proportion between 0 and 1). *

                    * Returns Double.NaN if no values have been added. * Returns 0 if at least one value has been added, but v is not comparable * to the values set.

                    * * @param v the value to lookup * @return the proportion of values less than or equal to v * @deprecated replaced by {@link #getCumPct(Comparable)} as of 2.0 */ @Deprecated public double getCumPct(Object v) { return getCumPct((Comparable) v); } /** * Returns the cumulative percentage of values less than or equal to v * (as a proportion between 0 and 1). *

                    * Returns Double.NaN if no values have been added. * Returns 0 if at least one value has been added, but v is not comparable * to the values set.

                    * * @param v the value to lookup * @return the proportion of values less than or equal to v */ public double getCumPct(Comparable v) { final long sumFreq = getSumFreq(); if (sumFreq == 0) { return Double.NaN; } return (double) getCumFreq(v) / (double) sumFreq; } /** * Returns the cumulative percentage of values less than or equal to v * (as a proportion between 0 and 1). *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values less than or equal to v */ public double getCumPct(int v) { return getCumPct(Long.valueOf(v)); } /** * Returns the cumulative percentage of values less than or equal to v * (as a proportion between 0 and 1). *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values less than or equal to v */ public double getCumPct(long v) { return getCumPct(Long.valueOf(v)); } /** * Returns the cumulative percentage of values less than or equal to v * (as a proportion between 0 and 1). *

                    * Returns 0 if v is not comparable to the values set.

                    * * @param v the value to lookup * @return the proportion of values less than or equal to v */ public double getCumPct(char v) { return getCumPct(Character.valueOf(v)); } /** * A Comparator that compares comparable objects using the * natural order. Copied from Commons Collections ComparableComparator. */ private static class NaturalComparator> implements Comparator>, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -3852193713161395148L; /** * Compare the two {@link Comparable Comparable} arguments. * This method is equivalent to: *
                    (({@link Comparable Comparable})o1).{@link Comparable#compareTo compareTo}(o2)
                    * * @param o1 the first object * @param o2 the second object * @return result of comparison * @throws NullPointerException when o1 is null, * or when ((Comparable)o1).compareTo(o2) does * @throws ClassCastException when o1 is not a {@link Comparable Comparable}, * or when ((Comparable)o1).compareTo(o2) does */ @SuppressWarnings("unchecked") // cast to (T) may throw ClassCastException, see Javadoc public int compare(Comparable o1, Comparable o2) { return o1.compareTo((T) o2); } } /** {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((freqTable == null) ? 0 : freqTable.hashCode()); return result; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Frequency)) return false; Frequency other = (Frequency) obj; if (freqTable == null) { if (other.freqTable != null) return false; } else if (!freqTable.equals(other.freqTable)) return false; return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/package.html100644 1750 1750 1706 11532241247 25606 0ustarlucluc 0 0 Data storage, manipulation and summary routines. ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearReg100644 1750 1750 31251 11532241246 32515 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.linear.ArrayRealVector; import org.apache.commons.math.stat.descriptive.moment.Variance; import org.apache.commons.math.util.FastMath; /** * Abstract base class for implementations of MultipleLinearRegression. * @version $Revision: 1073459 $ $Date: 2011-02-22 20:18:12 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public abstract class AbstractMultipleLinearRegression implements MultipleLinearRegression { /** X sample data. */ protected RealMatrix X; /** Y sample data. */ protected RealVector Y; /** Whether or not the regression model includes an intercept. True means no intercept. */ private boolean noIntercept = false; /** * @return true if the model has no intercept term; false otherwise * @since 2.2 */ public boolean isNoIntercept() { return noIntercept; } /** * @param noIntercept true means the model is to be estimated without an intercept term * @since 2.2 */ public void setNoIntercept(boolean noIntercept) { this.noIntercept = noIntercept; } /** *

                    Loads model x and y sample data from a flat input array, overriding any previous sample. *

                    *

                    Assumes that rows are concatenated with y values first in each row. For example, an input * data array containing the sequence of values (1, 2, 3, 4, 5, 6, 7, 8, 9) with * nobs = 3 and nvars = 2 creates a regression dataset with two * independent variables, as below: *

                         *   y   x[0]  x[1]
                         *   --------------
                         *   1     2     3
                         *   4     5     6
                         *   7     8     9
                         * 
                    *

                    *

                    Note that there is no need to add an initial unitary column (column of 1's) when * specifying a model including an intercept term. If {@link #isNoIntercept()} is true, * the X matrix will be created without an initial column of "1"s; otherwise this column will * be added. *

                    *

                    Throws IllegalArgumentException if any of the following preconditions fail: *

                    • data cannot be null
                    • *
                    • data.length = nobs * (nvars + 1)
                    • *
                    • nobs > nvars
                    *

                    * * @param data input data array * @param nobs number of observations (rows) * @param nvars number of independent variables (columns, not counting y) * @throws IllegalArgumentException if the preconditions are not met */ public void newSampleData(double[] data, int nobs, int nvars) { if (data == null) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NULL_NOT_ALLOWED); } if (data.length != nobs * (nvars + 1)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_REGRESSION_ARRAY, data.length, nobs, nvars); } if (nobs <= nvars) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS); } double[] y = new double[nobs]; final int cols = noIntercept ? nvars: nvars + 1; double[][] x = new double[nobs][cols]; int pointer = 0; for (int i = 0; i < nobs; i++) { y[i] = data[pointer++]; if (!noIntercept) { x[i][0] = 1.0d; } for (int j = noIntercept ? 0 : 1; j < cols; j++) { x[i][j] = data[pointer++]; } } this.X = new Array2DRowRealMatrix(x); this.Y = new ArrayRealVector(y); } /** * Loads new y sample data, overriding any previous data. * * @param y the array representing the y sample * @throws IllegalArgumentException if y is null or empty */ protected void newYSampleData(double[] y) { if (y == null) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NULL_NOT_ALLOWED); } if (y.length == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NO_DATA); } this.Y = new ArrayRealVector(y); } /** *

                    Loads new x sample data, overriding any previous data. *

                    * The input x array should have one row for each sample * observation, with columns corresponding to independent variables. * For example, if
                         *  x = new double[][] {{1, 2}, {3, 4}, {5, 6}} 
                    * then setXSampleData(x) results in a model with two independent * variables and 3 observations: *
                         *   x[0]  x[1]
                         *   ----------
                         *     1    2
                         *     3    4
                         *     5    6
                         * 
                    *

                    *

                    Note that there is no need to add an initial unitary column (column of 1's) when * specifying a model including an intercept term. *

                    * @param x the rectangular array representing the x sample * @throws IllegalArgumentException if x is null, empty or not rectangular */ protected void newXSampleData(double[][] x) { if (x == null) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NULL_NOT_ALLOWED); } if (x.length == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NO_DATA); } if (noIntercept) { this.X = new Array2DRowRealMatrix(x, true); } else { // Augment design matrix with initial unitary column final int nVars = x[0].length; final double[][] xAug = new double[x.length][nVars + 1]; for (int i = 0; i < x.length; i++) { if (x[i].length != nVars) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, x[i].length, nVars); } xAug[i][0] = 1.0d; System.arraycopy(x[i], 0, xAug[i], 1, nVars); } this.X = new Array2DRowRealMatrix(xAug, false); } } /** * Validates sample data. Checks that *
                    • Neither x nor y is null or empty;
                    • *
                    • The length (i.e. number of rows) of x equals the length of y
                    • *
                    • x has at least one more row than it has columns (i.e. there is * sufficient data to estimate regression coefficients for each of the * columns in x plus an intercept.
                    • *
                    * * @param x the [n,k] array representing the x data * @param y the [n,1] array representing the y data * @throws IllegalArgumentException if any of the checks fail * */ protected void validateSampleData(double[][] x, double[] y) { if ((x == null) || (y == null) || (x.length != y.length)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, (x == null) ? 0 : x.length, (y == null) ? 0 : y.length); } if (x.length == 0) { // Must be no y data either throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NO_DATA); } if (x[0].length + 1 > x.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS, x.length, x[0].length); } } /** * Validates that the x data and covariance matrix have the same * number of rows and that the covariance matrix is square. * * @param x the [n,k] array representing the x sample * @param covariance the [n,n] array representing the covariance matrix * @throws IllegalArgumentException if the number of rows in x is not equal * to the number of rows in covariance or covariance is not square. */ protected void validateCovarianceData(double[][] x, double[][] covariance) { if (x.length != covariance.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, covariance.length); } if (covariance.length > 0 && covariance.length != covariance[0].length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NON_SQUARE_MATRIX, covariance.length, covariance[0].length); } } /** * {@inheritDoc} */ public double[] estimateRegressionParameters() { RealVector b = calculateBeta(); return b.getData(); } /** * {@inheritDoc} */ public double[] estimateResiduals() { RealVector b = calculateBeta(); RealVector e = Y.subtract(X.operate(b)); return e.getData(); } /** * {@inheritDoc} */ public double[][] estimateRegressionParametersVariance() { return calculateBetaVariance().getData(); } /** * {@inheritDoc} */ public double[] estimateRegressionParametersStandardErrors() { double[][] betaVariance = estimateRegressionParametersVariance(); double sigma = calculateErrorVariance(); int length = betaVariance[0].length; double[] result = new double[length]; for (int i = 0; i < length; i++) { result[i] = FastMath.sqrt(sigma * betaVariance[i][i]); } return result; } /** * {@inheritDoc} */ public double estimateRegressandVariance() { return calculateYVariance(); } /** * Estimates the variance of the error. * * @return estimate of the error variance * @since 2.2 */ public double estimateErrorVariance() { return calculateErrorVariance(); } /** * Estimates the standard error of the regression. * * @return regression standard error * @since 2.2 */ public double estimateRegressionStandardError() { return Math.sqrt(estimateErrorVariance()); } /** * Calculates the beta of multiple linear regression in matrix notation. * * @return beta */ protected abstract RealVector calculateBeta(); /** * Calculates the beta variance of multiple linear regression in matrix * notation. * * @return beta variance */ protected abstract RealMatrix calculateBetaVariance(); /** * Calculates the variance of the y values. * * @return Y variance */ protected double calculateYVariance() { return new Variance().evaluate(Y.getData()); } /** *

                    Calculates the variance of the error term.

                    * Uses the formula
                         * var(u) = u · u / (n - k)
                         * 
                    * where n and k are the row and column dimensions of the design * matrix X. * * @return error variance estimate * @since 2.2 */ protected double calculateErrorVariance() { RealVector residuals = calculateResiduals(); return residuals.dotProduct(residuals) / (X.getRowDimension() - X.getColumnDimension()); } /** * Calculates the residuals of multiple linear regression in matrix * notation. * *
                         * u = y - X * b
                         * 
                    * * @return The residuals [n,1] matrix */ protected RealVector calculateResiduals() { RealVector b = calculateBeta(); return Y.subtract(X.operate(b)); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/package.html100644 1750 1750 1723 11532241246 27764 0ustarlucluc 0 0 Statistical routines involving multivariate data. ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressi100644 1750 1750 10355 11532241246 32447 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealVector; /** * The GLS implementation of the multiple linear regression. * * GLS assumes a general covariance matrix Omega of the error *
                     * u ~ N(0, Omega)
                     * 
                    * * Estimated by GLS, *
                     * b=(X' Omega^-1 X)^-1X'Omega^-1 y
                     * 
                    * whose variance is *
                     * Var(b)=(X' Omega^-1 X)^-1
                     * 
                    * @version $Revision: 1073460 $ $Date: 2011-02-22 20:22:39 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public class GLSMultipleLinearRegression extends AbstractMultipleLinearRegression { /** Covariance matrix. */ private RealMatrix Omega; /** Inverse of covariance matrix. */ private RealMatrix OmegaInverse; /** Replace sample data, overriding any previous sample. * @param y y values of the sample * @param x x values of the sample * @param covariance array representing the covariance matrix */ public void newSampleData(double[] y, double[][] x, double[][] covariance) { validateSampleData(x, y); newYSampleData(y); newXSampleData(x); validateCovarianceData(x, covariance); newCovarianceData(covariance); } /** * Add the covariance data. * * @param omega the [n,n] array representing the covariance */ protected void newCovarianceData(double[][] omega){ this.Omega = new Array2DRowRealMatrix(omega); this.OmegaInverse = null; } /** * Get the inverse of the covariance. *

                    The inverse of the covariance matrix is lazily evaluated and cached.

                    * @return inverse of the covariance */ protected RealMatrix getOmegaInverse() { if (OmegaInverse == null) { OmegaInverse = new LUDecompositionImpl(Omega).getSolver().getInverse(); } return OmegaInverse; } /** * Calculates beta by GLS. *
                         *  b=(X' Omega^-1 X)^-1X'Omega^-1 y
                         * 
                    * @return beta */ @Override protected RealVector calculateBeta() { RealMatrix OI = getOmegaInverse(); RealMatrix XT = X.transpose(); RealMatrix XTOIX = XT.multiply(OI).multiply(X); RealMatrix inverse = new LUDecompositionImpl(XTOIX).getSolver().getInverse(); return inverse.multiply(XT).multiply(OI).operate(Y); } /** * Calculates the variance on the beta. *
                         *  Var(b)=(X' Omega^-1 X)^-1
                         * 
                    * @return The beta variance matrix */ @Override protected RealMatrix calculateBetaVariance() { RealMatrix OI = getOmegaInverse(); RealMatrix XTOIX = X.transpose().multiply(OI).multiply(X); return new LUDecompositionImpl(XTOIX).getSolver().getInverse(); } /** * Calculates the estimated variance of the error term using the formula *
                         *  Var(u) = Tr(u' Omega^-1 u)/(n-k)
                         * 
                    * where n and k are the row and column dimensions of the design * matrix X. * * @return error variance * @since 2.2 */ @Override protected double calculateErrorVariance() { RealVector residuals = calculateResiduals(); double t = residuals.dotProduct(getOmegaInverse().operate(residuals)); return t / (X.getRowDimension() - X.getColumnDimension()); } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.100644 1750 1750 4730 11532241246 32474 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; /** * The multiple linear regression can be represented in matrix-notation. *
                     *  y=X*b+u
                     * 
                    * where y is an n-vector regressand, X is a [n,k] matrix whose k columns are called * regressors, b is k-vector of regression parameters and u is an n-vector * of error terms or residuals. * * The notation is quite standard in literature, * cf eg Davidson and MacKinnon, Econometrics Theory and Methods, 2004. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface MultipleLinearRegression { /** * Estimates the regression parameters b. * * @return The [k,1] array representing b */ double[] estimateRegressionParameters(); /** * Estimates the variance of the regression parameters, ie Var(b). * * @return The [k,k] array representing the variance of b */ double[][] estimateRegressionParametersVariance(); /** * Estimates the residuals, ie u = y - X*b. * * @return The [n,1] array representing the residuals */ double[] estimateResiduals(); /** * Returns the variance of the regressand, ie Var(y). * * @return The double representing the variance of y */ double estimateRegressandVariance(); /** * Returns the standard errors of the regression parameters. * * @return standard errors of estimated regression parameters */ double[] estimateRegressionParametersStandardErrors(); } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegressi100644 1750 1750 21634 11532241246 32461 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.QRDecomposition; import org.apache.commons.math.linear.QRDecompositionImpl; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.stat.StatUtils; import org.apache.commons.math.stat.descriptive.moment.SecondMoment; /** *

                    Implements ordinary least squares (OLS) to estimate the parameters of a * multiple linear regression model.

                    * *

                    The regression coefficients, b, satisfy the normal equations: *

                     XT X b = XT y 

                    * *

                    To solve the normal equations, this implementation uses QR decomposition * of the X matrix. (See {@link QRDecompositionImpl} for details on the * decomposition algorithm.) The X matrix, also known as the design matrix, * has rows corresponding to sample observations and columns corresponding to independent * variables. When the model is estimated using an intercept term (i.e. when * {@link #isNoIntercept() isNoIntercept} is false as it is by default), the X * matrix includes an initial column identically equal to 1. We solve the normal equations * as follows: *

                     XTX b = XT y
                     * (QR)T (QR) b = (QR)Ty
                     * RT (QTQ) R b = RT QT y
                     * RT R b = RT QT y
                     * (RT)-1 RT R b = (RT)-1 RT QT y
                     * R b = QT y 

                    * *

                    Given Q and R, the last equation is solved by back-substitution.

                    * * @version $Revision: 1073464 $ $Date: 2011-02-22 20:35:02 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public class OLSMultipleLinearRegression extends AbstractMultipleLinearRegression { /** Cached QR decomposition of X matrix */ private QRDecomposition qr = null; /** * Loads model x and y sample data, overriding any previous sample. * * Computes and caches QR decomposition of the X matrix. * @param y the [n,1] array representing the y sample * @param x the [n,k] array representing the x sample * @throws IllegalArgumentException if the x and y array data are not * compatible for the regression */ public void newSampleData(double[] y, double[][] x) { validateSampleData(x, y); newYSampleData(y); newXSampleData(x); } /** * {@inheritDoc} *

                    This implementation computes and caches the QR decomposition of the X matrix.

                    */ @Override public void newSampleData(double[] data, int nobs, int nvars) { super.newSampleData(data, nobs, nvars); qr = new QRDecompositionImpl(X); } /** *

                    Compute the "hat" matrix. *

                    *

                    The hat matrix is defined in terms of the design matrix X * by X(XTX)-1XT *

                    *

                    The implementation here uses the QR decomposition to compute the * hat matrix as Q IpQT where Ip is the * p-dimensional identity matrix augmented by 0's. This computational * formula is from "The Hat Matrix in Regression and ANOVA", * David C. Hoaglin and Roy E. Welsch, * The American Statistician, Vol. 32, No. 1 (Feb., 1978), pp. 17-22. * * @return the hat matrix */ public RealMatrix calculateHat() { // Create augmented identity matrix RealMatrix Q = qr.getQ(); final int p = qr.getR().getColumnDimension(); final int n = Q.getColumnDimension(); Array2DRowRealMatrix augI = new Array2DRowRealMatrix(n, n); double[][] augIData = augI.getDataRef(); for (int i = 0; i < n; i++) { for (int j =0; j < n; j++) { if (i == j && i < p) { augIData[i][j] = 1d; } else { augIData[i][j] = 0d; } } } // Compute and return Hat matrix return Q.multiply(augI).multiply(Q.transpose()); } /** *

                    Returns the sum of squared deviations of Y from its mean.

                    * *

                    If the model has no intercept term, 0 is used for the * mean of Y - i.e., what is returned is the sum of the squared Y values.

                    * *

                    The value returned by this method is the SSTO value used in * the {@link #calculateRSquared() R-squared} computation.

                    * * @return SSTO - the total sum of squares * @see #isNoIntercept() * @since 2.2 */ public double calculateTotalSumOfSquares() { if (isNoIntercept()) { return StatUtils.sumSq(Y.getData()); } else { return new SecondMoment().evaluate(Y.getData()); } } /** * Returns the sum of squared residuals. * * @return residual sum of squares * @since 2.2 */ public double calculateResidualSumOfSquares() { final RealVector residuals = calculateResiduals(); return residuals.dotProduct(residuals); } /** * Returns the R-Squared statistic, defined by the formula
                         * R2 = 1 - SSR / SSTO
                         * 
                    * where SSR is the {@link #calculateResidualSumOfSquares() sum of squared residuals} * and SSTO is the {@link #calculateTotalSumOfSquares() total sum of squares} * * @return R-square statistic * @since 2.2 */ public double calculateRSquared() { return 1 - calculateResidualSumOfSquares() / calculateTotalSumOfSquares(); } /** *

                    Returns the adjusted R-squared statistic, defined by the formula

                         * R2adj = 1 - [SSR (n - 1)] / [SSTO (n - p)]
                         * 
                    * where SSR is the {@link #calculateResidualSumOfSquares() sum of squared residuals}, * SSTO is the {@link #calculateTotalSumOfSquares() total sum of squares}, n is the number * of observations and p is the number of parameters estimated (including the intercept).

                    * *

                    If the regression is estimated without an intercept term, what is returned is

                         *  1 - (1 - {@link #calculateRSquared()}) * (n / (n - p)) 
                         * 

                    * * @return adjusted R-Squared statistic * @see #isNoIntercept() * @since 2.2 */ public double calculateAdjustedRSquared() { final double n = X.getRowDimension(); if (isNoIntercept()) { return 1 - (1 - calculateRSquared()) * (n / (n - X.getColumnDimension())); } else { return 1 - (calculateResidualSumOfSquares() * (n - 1)) / (calculateTotalSumOfSquares() * (n - X.getColumnDimension())); } } /** * {@inheritDoc} *

                    This implementation computes and caches the QR decomposition of the X matrix * once it is successfully loaded.

                    */ @Override protected void newXSampleData(double[][] x) { super.newXSampleData(x); qr = new QRDecompositionImpl(X); } /** * Calculates the regression coefficients using OLS. * * @return beta */ @Override protected RealVector calculateBeta() { return qr.getSolver().solve(Y); } /** *

                    Calculates the variance-covariance matrix of the regression parameters. *

                    *

                    Var(b) = (XTX)-1 *

                    *

                    Uses QR decomposition to reduce (XTX)-1 * to (RTR)-1, with only the top p rows of * R included, where p = the length of the beta vector.

                    * * @return The beta variance-covariance matrix */ @Override protected RealMatrix calculateBetaVariance() { int p = X.getColumnDimension(); RealMatrix Raug = qr.getR().getSubMatrix(0, p - 1 , 0, p - 1); RealMatrix Rinv = new LUDecompositionImpl(Raug).getSolver().getInverse(); return Rinv.multiply(Rinv.transpose()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/regression/SimpleRegression.java100644 1750 1750 54054 11532241246 31665 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.regression; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.distribution.TDistribution; import org.apache.commons.math.distribution.TDistributionImpl; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Estimates an ordinary least squares regression model * with one independent variable. *

                    * y = intercept + slope * x

                    *

                    * Standard errors for intercept and slope are * available as well as ANOVA, r-square and Pearson's r statistics.

                    *

                    * Observations (x,y pairs) can be added to the model one at a time or they * can be provided in a 2-dimensional array. The observations are not stored * in memory, so there is no limit to the number of observations that can be * added to the model.

                    *

                    * Usage Notes:

                      *
                    • When there are fewer than two observations in the model, or when * there is no variation in the x values (i.e. all x values are the same) * all statistics return NaN. At least two observations with * different x coordinates are requred to estimate a bivariate regression * model. *
                    • *
                    • getters for the statistics always compute values based on the current * set of observations -- i.e., you can get statistics, then add more data * and get updated statistics without using a new instance. There is no * "compute" method that updates all statistics. Each of the getters performs * the necessary computations to return the requested statistic.
                    • *

                    * * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ */ public class SimpleRegression implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -3004689053607543335L; /** the distribution used to compute inference statistics. */ private TDistribution distribution; /** sum of x values */ private double sumX = 0d; /** total variation in x (sum of squared deviations from xbar) */ private double sumXX = 0d; /** sum of y values */ private double sumY = 0d; /** total variation in y (sum of squared deviations from ybar) */ private double sumYY = 0d; /** sum of products */ private double sumXY = 0d; /** number of observations */ private long n = 0; /** mean of accumulated x values, used in updating formulas */ private double xbar = 0; /** mean of accumulated y values, used in updating formulas */ private double ybar = 0; // ---------------------Public methods-------------------------------------- /** * Create an empty SimpleRegression instance */ public SimpleRegression() { this(new TDistributionImpl(1.0)); } /** * Create an empty SimpleRegression using the given distribution object to * compute inference statistics. * @param t the distribution used to compute inference statistics. * @since 1.2 * @deprecated in 2.2 (to be removed in 3.0). Please use the {@link * #SimpleRegression(int) other constructor} instead. */ @Deprecated public SimpleRegression(TDistribution t) { super(); setDistribution(t); } /** * Create an empty SimpleRegression. * * @param degrees Number of degrees of freedom of the distribution * used to compute inference statistics. * @since 2.2 */ public SimpleRegression(int degrees) { setDistribution(new TDistributionImpl(degrees)); } /** * Adds the observation (x,y) to the regression data set. *

                    * Uses updating formulas for means and sums of squares defined in * "Algorithms for Computing the Sample Variance: Analysis and * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. * 1983, American Statistician, vol. 37, pp. 242-247, referenced in * Weisberg, S. "Applied Linear Regression". 2nd Ed. 1985.

                    * * * @param x independent variable value * @param y dependent variable value */ public void addData(double x, double y) { if (n == 0) { xbar = x; ybar = y; } else { double dx = x - xbar; double dy = y - ybar; sumXX += dx * dx * (double) n / (n + 1d); sumYY += dy * dy * (double) n / (n + 1d); sumXY += dx * dy * (double) n / (n + 1d); xbar += dx / (n + 1.0); ybar += dy / (n + 1.0); } sumX += x; sumY += y; n++; if (n > 2) { distribution.setDegreesOfFreedom(n - 2); } } /** * Removes the observation (x,y) from the regression data set. *

                    * Mirrors the addData method. This method permits the use of * SimpleRegression instances in streaming mode where the regression * is applied to a sliding "window" of observations, however the caller is * responsible for maintaining the set of observations in the window.

                    * * The method has no effect if there are no points of data (i.e. n=0) * * @param x independent variable value * @param y dependent variable value */ public void removeData(double x, double y) { if (n > 0) { double dx = x - xbar; double dy = y - ybar; sumXX -= dx * dx * (double) n / (n - 1d); sumYY -= dy * dy * (double) n / (n - 1d); sumXY -= dx * dy * (double) n / (n - 1d); xbar -= dx / (n - 1.0); ybar -= dy / (n - 1.0); sumX -= x; sumY -= y; n--; if (n > 2) { distribution.setDegreesOfFreedom(n - 2); } } } /** * Adds the observations represented by the elements in * data. *

                    * (data[0][0],data[0][1]) will be the first observation, then * (data[1][0],data[1][1]), etc.

                    *

                    * This method does not replace data that has already been added. The * observations represented by data are added to the existing * dataset.

                    *

                    * To replace all data, use clear() before adding the new * data.

                    * * @param data array of observations to be added */ public void addData(double[][] data) { for (int i = 0; i < data.length; i++) { addData(data[i][0], data[i][1]); } } /** * Removes observations represented by the elements in data. *

                    * If the array is larger than the current n, only the first n elements are * processed. This method permits the use of SimpleRegression instances in * streaming mode where the regression is applied to a sliding "window" of * observations, however the caller is responsible for maintaining the set * of observations in the window.

                    *

                    * To remove all data, use clear().

                    * * @param data array of observations to be removed */ public void removeData(double[][] data) { for (int i = 0; i < data.length && n > 0; i++) { removeData(data[i][0], data[i][1]); } } /** * Clears all data from the model. */ public void clear() { sumX = 0d; sumXX = 0d; sumY = 0d; sumYY = 0d; sumXY = 0d; n = 0; } /** * Returns the number of observations that have been added to the model. * * @return n number of observations that have been added. */ public long getN() { return n; } /** * Returns the "predicted" y value associated with the * supplied x value, based on the data that has been * added to the model when this method is activated. *

                    * predict(x) = intercept + slope * x

                    *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double,NaN is * returned. *

                    * * @param x input x value * @return predicted y value */ public double predict(double x) { double b1 = getSlope(); return getIntercept(b1) + b1 * x; } /** * Returns the intercept of the estimated regression line. *

                    * The least squares estimate of the intercept is computed using the * normal equations. * The intercept is sometimes denoted b0.

                    *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double,NaN is * returned. *

                    * * @return the intercept of the regression line */ public double getIntercept() { return getIntercept(getSlope()); } /** * Returns the slope of the estimated regression line. *

                    * The least squares estimate of the slope is computed using the * normal equations. * The slope is sometimes denoted b1.

                    *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double.NaN is * returned. *

                    * * @return the slope of the regression line */ public double getSlope() { if (n < 2) { return Double.NaN; //not enough data } if (FastMath.abs(sumXX) < 10 * Double.MIN_VALUE) { return Double.NaN; //not enough variation in x } return sumXY / sumXX; } /** * Returns the * sum of squared errors (SSE) associated with the regression * model. *

                    * The sum is computed using the computational formula

                    *

                    * SSE = SYY - (SXY * SXY / SXX)

                    *

                    * where SYY is the sum of the squared deviations of the y * values about their mean, SXX is similarly defined and * SXY is the sum of the products of x and y mean deviations. *

                    * The sums are accumulated using the updating algorithm referenced in * {@link #addData}.

                    *

                    * The return value is constrained to be non-negative - i.e., if due to * rounding errors the computational formula returns a negative result, * 0 is returned.

                    *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double,NaN is * returned. *

                    * * @return sum of squared errors associated with the regression model */ public double getSumSquaredErrors() { return FastMath.max(0d, sumYY - sumXY * sumXY / sumXX); } /** * Returns the sum of squared deviations of the y values about their mean. *

                    * This is defined as SSTO * here.

                    *

                    * If n < 2, this returns Double.NaN.

                    * * @return sum of squared deviations of y values */ public double getTotalSumSquares() { if (n < 2) { return Double.NaN; } return sumYY; } /** * Returns the sum of squared deviations of the x values about their mean. * * If n < 2, this returns Double.NaN.

                    * * @return sum of squared deviations of x values */ public double getXSumSquares() { if (n < 2) { return Double.NaN; } return sumXX; } /** * Returns the sum of crossproducts, xi*yi. * * @return sum of cross products */ public double getSumOfCrossProducts() { return sumXY; } /** * Returns the sum of squared deviations of the predicted y values about * their mean (which equals the mean of y). *

                    * This is usually abbreviated SSR or SSM. It is defined as SSM * here

                    *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double.NaN is * returned. *

                    * * @return sum of squared deviations of predicted y values */ public double getRegressionSumSquares() { return getRegressionSumSquares(getSlope()); } /** * Returns the sum of squared errors divided by the degrees of freedom, * usually abbreviated MSE. *

                    * If there are fewer than three data pairs in the model, * or if there is no variation in x, this returns * Double.NaN.

                    * * @return sum of squared deviations of y values */ public double getMeanSquareError() { if (n < 3) { return Double.NaN; } return getSumSquaredErrors() / (n - 2); } /** * Returns * Pearson's product moment correlation coefficient, * usually denoted r. *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double,NaN is * returned. *

                    * * @return Pearson's r */ public double getR() { double b1 = getSlope(); double result = FastMath.sqrt(getRSquare()); if (b1 < 0) { result = -result; } return result; } /** * Returns the * coefficient of determination, * usually denoted r-square. *

                    * Preconditions:

                      *
                    • At least two observations (with at least two different x values) * must have been added before invoking this method. If this method is * invoked before a model can be estimated, Double,NaN is * returned. *

                    * * @return r-square */ public double getRSquare() { double ssto = getTotalSumSquares(); return (ssto - getSumSquaredErrors()) / ssto; } /** * Returns the * standard error of the intercept estimate, * usually denoted s(b0). *

                    * If there are fewer that three observations in the * model, or if there is no variation in x, this returns * Double.NaN.

                    * * @return standard error associated with intercept estimate */ public double getInterceptStdErr() { return FastMath.sqrt( getMeanSquareError() * ((1d / (double) n) + (xbar * xbar) / sumXX)); } /** * Returns the standard * error of the slope estimate, * usually denoted s(b1). *

                    * If there are fewer that three data pairs in the model, * or if there is no variation in x, this returns Double.NaN. *

                    * * @return standard error associated with slope estimate */ public double getSlopeStdErr() { return FastMath.sqrt(getMeanSquareError() / sumXX); } /** * Returns the half-width of a 95% confidence interval for the slope * estimate. *

                    * The 95% confidence interval is

                    *

                    * (getSlope() - getSlopeConfidenceInterval(), * getSlope() + getSlopeConfidenceInterval())

                    *

                    * If there are fewer that three observations in the * model, or if there is no variation in x, this returns * Double.NaN.

                    *

                    * Usage Note:
                    * The validity of this statistic depends on the assumption that the * observations included in the model are drawn from a * * Bivariate Normal Distribution.

                    * * @return half-width of 95% confidence interval for the slope estimate * @throws MathException if the confidence interval can not be computed. */ public double getSlopeConfidenceInterval() throws MathException { return getSlopeConfidenceInterval(0.05d); } /** * Returns the half-width of a (100-100*alpha)% confidence interval for * the slope estimate. *

                    * The (100-100*alpha)% confidence interval is

                    *

                    * (getSlope() - getSlopeConfidenceInterval(), * getSlope() + getSlopeConfidenceInterval())

                    *

                    * To request, for example, a 99% confidence interval, use * alpha = .01

                    *

                    * Usage Note:
                    * The validity of this statistic depends on the assumption that the * observations included in the model are drawn from a * * Bivariate Normal Distribution.

                    *

                    * Preconditions:

                      *
                    • If there are fewer that three observations in the * model, or if there is no variation in x, this returns * Double.NaN. *
                    • *
                    • (0 < alpha < 1); otherwise an * IllegalArgumentException is thrown. *

                    * * @param alpha the desired significance level * @return half-width of 95% confidence interval for the slope estimate * @throws MathException if the confidence interval can not be computed. */ public double getSlopeConfidenceInterval(double alpha) throws MathException { if (alpha >= 1 || alpha <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0.0, 1.0); } return getSlopeStdErr() * distribution.inverseCumulativeProbability(1d - alpha / 2d); } /** * Returns the significance level of the slope (equiv) correlation. *

                    * Specifically, the returned value is the smallest alpha * such that the slope confidence interval with significance level * equal to alpha does not include 0. * On regression output, this is often denoted Prob(|t| > 0) *

                    * Usage Note:
                    * The validity of this statistic depends on the assumption that the * observations included in the model are drawn from a * * Bivariate Normal Distribution.

                    *

                    * If there are fewer that three observations in the * model, or if there is no variation in x, this returns * Double.NaN.

                    * * @return significance level for slope/correlation * @throws MathException if the significance level can not be computed. */ public double getSignificance() throws MathException { return 2d * (1.0 - distribution.cumulativeProbability( FastMath.abs(getSlope()) / getSlopeStdErr())); } // ---------------------Private methods----------------------------------- /** * Returns the intercept of the estimated regression line, given the slope. *

                    * Will return NaN if slope is NaN.

                    * * @param slope current slope * @return the intercept of the regression line */ private double getIntercept(double slope) { return (sumY - slope * sumX) / n; } /** * Computes SSR from b1. * * @param slope regression slope estimate * @return sum of squared deviations of predicted y values */ private double getRegressionSumSquares(double slope) { return slope * slope * sumXX; } /** * Modify the distribution used to compute inference statistics. * @param value the new distribution * @since 1.2 * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public void setDistribution(TDistribution value) { distribution = value; // modify degrees of freedom if (n > 2) { distribution.setDegreesOfFreedom(n - 2); } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/SpearmansCorrelation.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/SpearmansCorrelation.jav100644 1750 1750 14524 11532241246 32524 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.stat.ranking.NaturalRanking; import org.apache.commons.math.stat.ranking.RankingAlgorithm; /** *

                    Spearman's rank correlation. This implementation performs a rank * transformation on the input data and then computes {@link PearsonsCorrelation} * on the ranked data.

                    * *

                    By default, ranks are computed using {@link NaturalRanking} with default * strategies for handling NaNs and ties in the data (NaNs maximal, ties averaged). * The ranking algorithm can be set using a constructor argument.

                    * * @since 2.0 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class SpearmansCorrelation { /** Input data */ private final RealMatrix data; /** Ranking algorithm */ private final RankingAlgorithm rankingAlgorithm; /** Rank correlation */ private final PearsonsCorrelation rankCorrelation; /** * Create a SpearmansCorrelation with the given input data matrix * and ranking algorithm. * * @param dataMatrix matrix of data with columns representing * variables to correlate * @param rankingAlgorithm ranking algorithm */ public SpearmansCorrelation(final RealMatrix dataMatrix, final RankingAlgorithm rankingAlgorithm) { this.data = dataMatrix.copy(); this.rankingAlgorithm = rankingAlgorithm; rankTransform(data); rankCorrelation = new PearsonsCorrelation(data); } /** * Create a SpearmansCorrelation from the given data matrix. * * @param dataMatrix matrix of data with columns representing * variables to correlate */ public SpearmansCorrelation(final RealMatrix dataMatrix) { this(dataMatrix, new NaturalRanking()); } /** * Create a SpearmansCorrelation without data. */ public SpearmansCorrelation() { data = null; this.rankingAlgorithm = new NaturalRanking(); rankCorrelation = null; } /** * Calculate the Spearman Rank Correlation Matrix. * * @return Spearman Rank Correlation Matrix */ public RealMatrix getCorrelationMatrix() { return rankCorrelation.getCorrelationMatrix(); } /** * Returns a {@link PearsonsCorrelation} instance constructed from the * ranked input data. That is, * new SpearmansCorrelation(matrix).getRankCorrelation() * is equivalent to * new PearsonsCorrelation(rankTransform(matrix)) where * rankTransform(matrix) is the result of applying the * configured RankingAlgorithm to each of the columns of * matrix. * * @return PearsonsCorrelation among ranked column data */ public PearsonsCorrelation getRankCorrelation() { return rankCorrelation; } /** * Computes the Spearman's rank correlation matrix for the columns of the * input matrix. * * @param matrix matrix with columns representing variables to correlate * @return correlation matrix */ public RealMatrix computeCorrelationMatrix(RealMatrix matrix) { RealMatrix matrixCopy = matrix.copy(); rankTransform(matrixCopy); return new PearsonsCorrelation().computeCorrelationMatrix(matrixCopy); } /** * Computes the Spearman's rank correlation matrix for the columns of the * input rectangular array. The columns of the array represent values * of variables to be correlated. * * @param matrix matrix with columns representing variables to correlate * @return correlation matrix */ public RealMatrix computeCorrelationMatrix(double[][] matrix) { return computeCorrelationMatrix(new BlockRealMatrix(matrix)); } /** * Computes the Spearman's rank correlation coefficient between the two arrays. * *

                    Throws IllegalArgumentException if the arrays do not have the same length * or their common length is less than 2

                    * * @param xArray first data array * @param yArray second data array * @return Returns Spearman's rank correlation coefficient for the two arrays * @throws IllegalArgumentException if the arrays lengths do not match or * there is insufficient data */ public double correlation(final double[] xArray, final double[] yArray) throws IllegalArgumentException { if (xArray.length != yArray.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, xArray.length, yArray.length); } else if (xArray.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, xArray.length, 2); } else { return new PearsonsCorrelation().correlation(rankingAlgorithm.rank(xArray), rankingAlgorithm.rank(yArray)); } } /** * Applies rank transform to each of the columns of matrix * using the current rankingAlgorithm * * @param matrix matrix to transform */ private void rankTransform(RealMatrix matrix) { for (int i = 0; i < matrix.getColumnDimension(); i++) { matrix.setColumn(i, rankingAlgorithm.rank(matrix.getColumn(i))); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/package.html100644 1750 1750 1713 11532241246 30124 0ustarlucluc 0 0 Correlations/Covariance computations. ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/PearsonsCorrelation.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/PearsonsCorrelation.java100644 1750 1750 26441 11532241246 32527 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.distribution.TDistribution; import org.apache.commons.math.distribution.TDistributionImpl; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.stat.regression.SimpleRegression; import org.apache.commons.math.util.FastMath; /** * Computes Pearson's product-moment correlation coefficients for pairs of arrays * or columns of a matrix. * *

                    The constructors that take RealMatrix or * double[][] arguments generate correlation matrices. The * columns of the input matrices are assumed to represent variable values. * Correlations are given by the formula

                    * cor(X, Y) = Σ[(xi - E(X))(yi - E(Y))] / [(n - 1)s(X)s(Y)] * where E(X) is the mean of X, E(Y) * is the mean of the Y values and s(X), s(Y) are standard deviations. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class PearsonsCorrelation { /** correlation matrix */ private final RealMatrix correlationMatrix; /** number of observations */ private final int nObs; /** * Create a PearsonsCorrelation instance without data */ public PearsonsCorrelation() { super(); correlationMatrix = null; nObs = 0; } /** * Create a PearsonsCorrelation from a rectangular array * whose columns represent values of variables to be correlated. * * @param data rectangular array with columns representing variables * @throws IllegalArgumentException if the input data array is not * rectangular with at least two rows and two columns. */ public PearsonsCorrelation(double[][] data) { this(new BlockRealMatrix(data)); } /** * Create a PearsonsCorrelation from a RealMatrix whose columns * represent variables to be correlated. * * @param matrix matrix with columns representing variables to correlate */ public PearsonsCorrelation(RealMatrix matrix) { checkSufficientData(matrix); nObs = matrix.getRowDimension(); correlationMatrix = computeCorrelationMatrix(matrix); } /** * Create a PearsonsCorrelation from a {@link Covariance}. The correlation * matrix is computed by scaling the Covariance's covariance matrix. * The Covariance instance must have been created from a data matrix with * columns representing variable values. * * @param covariance Covariance instance */ public PearsonsCorrelation(Covariance covariance) { RealMatrix covarianceMatrix = covariance.getCovarianceMatrix(); if (covarianceMatrix == null) { throw new NullArgumentException(LocalizedFormats.COVARIANCE_MATRIX); } nObs = covariance.getN(); correlationMatrix = covarianceToCorrelation(covarianceMatrix); } /** * Create a PearsonsCorrelation from a covariance matrix. The correlation * matrix is computed by scaling the covariance matrix. * * @param covarianceMatrix covariance matrix * @param numberOfObservations the number of observations in the dataset used to compute * the covariance matrix */ public PearsonsCorrelation(RealMatrix covarianceMatrix, int numberOfObservations) { nObs = numberOfObservations; correlationMatrix = covarianceToCorrelation(covarianceMatrix); } /** * Returns the correlation matrix * * @return correlation matrix */ public RealMatrix getCorrelationMatrix() { return correlationMatrix; } /** * Returns a matrix of standard errors associated with the estimates * in the correlation matrix.
                    * getCorrelationStandardErrors().getEntry(i,j) is the standard * error associated with getCorrelationMatrix.getEntry(i,j) *

                    The formula used to compute the standard error is
                    * SEr = ((1 - r2) / (n - 2))1/2 * where r is the estimated correlation coefficient and * n is the number of observations in the source dataset.

                    * * @return matrix of correlation standard errors */ public RealMatrix getCorrelationStandardErrors() { int nVars = correlationMatrix.getColumnDimension(); double[][] out = new double[nVars][nVars]; for (int i = 0; i < nVars; i++) { for (int j = 0; j < nVars; j++) { double r = correlationMatrix.getEntry(i, j); out[i][j] = FastMath.sqrt((1 - r * r) /(nObs - 2)); } } return new BlockRealMatrix(out); } /** * Returns a matrix of p-values associated with the (two-sided) null * hypothesis that the corresponding correlation coefficient is zero. *

                    getCorrelationPValues().getEntry(i,j) is the probability * that a random variable distributed as tn-2 takes * a value with absolute value greater than or equal to
                    * |r|((n - 2) / (1 - r2))1/2

                    *

                    The values in the matrix are sometimes referred to as the * significance of the corresponding correlation coefficients.

                    * * @return matrix of p-values * @throws MathException if an error occurs estimating probabilities */ public RealMatrix getCorrelationPValues() throws MathException { TDistribution tDistribution = new TDistributionImpl(nObs - 2); int nVars = correlationMatrix.getColumnDimension(); double[][] out = new double[nVars][nVars]; for (int i = 0; i < nVars; i++) { for (int j = 0; j < nVars; j++) { if (i == j) { out[i][j] = 0d; } else { double r = correlationMatrix.getEntry(i, j); double t = FastMath.abs(r * FastMath.sqrt((nObs - 2)/(1 - r * r))); out[i][j] = 2 * tDistribution.cumulativeProbability(-t); } } } return new BlockRealMatrix(out); } /** * Computes the correlation matrix for the columns of the * input matrix. * * @param matrix matrix with columns representing variables to correlate * @return correlation matrix */ public RealMatrix computeCorrelationMatrix(RealMatrix matrix) { int nVars = matrix.getColumnDimension(); RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars); for (int i = 0; i < nVars; i++) { for (int j = 0; j < i; j++) { double corr = correlation(matrix.getColumn(i), matrix.getColumn(j)); outMatrix.setEntry(i, j, corr); outMatrix.setEntry(j, i, corr); } outMatrix.setEntry(i, i, 1d); } return outMatrix; } /** * Computes the correlation matrix for the columns of the * input rectangular array. The colums of the array represent values * of variables to be correlated. * * @param data matrix with columns representing variables to correlate * @return correlation matrix */ public RealMatrix computeCorrelationMatrix(double[][] data) { return computeCorrelationMatrix(new BlockRealMatrix(data)); } /** * Computes the Pearson's product-moment correlation coefficient between the two arrays. * *

                    Throws IllegalArgumentException if the arrays do not have the same length * or their common length is less than 2

                    * * @param xArray first data array * @param yArray second data array * @return Returns Pearson's correlation coefficient for the two arrays * @throws IllegalArgumentException if the arrays lengths do not match or * there is insufficient data */ public double correlation(final double[] xArray, final double[] yArray) throws IllegalArgumentException { SimpleRegression regression = new SimpleRegression(); if (xArray.length != yArray.length) { throw new DimensionMismatchException(xArray.length, yArray.length); } else if (xArray.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, xArray.length, 2); } else { for(int i=0; iUses the formula
                    * r(X,Y) = cov(X,Y)/s(X)s(Y) where * r(·,·) is the correlation coefficient and * s(·) means standard deviation.

                    * * @param covarianceMatrix the covariance matrix * @return correlation matrix */ public RealMatrix covarianceToCorrelation(RealMatrix covarianceMatrix) { int nVars = covarianceMatrix.getColumnDimension(); RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars); for (int i = 0; i < nVars; i++) { double sigma = FastMath.sqrt(covarianceMatrix.getEntry(i, i)); outMatrix.setEntry(i, i, 1d); for (int j = 0; j < i; j++) { double entry = covarianceMatrix.getEntry(i, j) / (sigma * FastMath.sqrt(covarianceMatrix.getEntry(j, j))); outMatrix.setEntry(i, j, entry); outMatrix.setEntry(j, i, entry); } } return outMatrix; } /** * Throws IllegalArgumentException of the matrix does not have at least * two columns and two rows * * @param matrix matrix to check for sufficiency */ private void checkSufficientData(final RealMatrix matrix) { int nRows = matrix.getRowDimension(); int nCols = matrix.getColumnDimension(); if (nRows < 2 || nCols < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_ROWS_AND_COLUMNS, nRows, nCols); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/correlation/Covariance.java100644 1750 1750 24350 11532241246 30602 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.correlation; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.Variance; /** * Computes covariances for pairs of arrays or columns of a matrix. * *

                    The constructors that take RealMatrix or * double[][] arguments generate covariance matrices. The * columns of the input matrices are assumed to represent variable values.

                    * *

                    The constructor argument biasCorrected determines whether or * not computed covariances are bias-corrected.

                    * *

                    Unbiased covariances are given by the formula

                    * cov(X, Y) = Σ[(xi - E(X))(yi - E(Y))] / (n - 1) * where E(X) is the mean of X and E(Y) * is the mean of the Y values. * *

                    Non-bias-corrected estimates use n in place of n - 1 * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class Covariance { /** covariance matrix */ private final RealMatrix covarianceMatrix; /** * Create an empty covariance matrix. */ /** Number of observations (length of covariate vectors) */ private final int n; /** * Create a Covariance with no data */ public Covariance() { super(); covarianceMatrix = null; n = 0; } /** * Create a Covariance matrix from a rectangular array * whose columns represent covariates. * *

                    The biasCorrected parameter determines whether or not * covariance estimates are bias-corrected.

                    * *

                    The input array must be rectangular with at least two columns * and two rows.

                    * * @param data rectangular array with columns representing covariates * @param biasCorrected true means covariances are bias-corrected * @throws IllegalArgumentException if the input data array is not * rectangular with at least two rows and two columns. */ public Covariance(double[][] data, boolean biasCorrected) { this(new BlockRealMatrix(data), biasCorrected); } /** * Create a Covariance matrix from a rectangular array * whose columns represent covariates. * *

                    The input array must be rectangular with at least two columns * and two rows

                    * * @param data rectangular array with columns representing covariates * @throws IllegalArgumentException if the input data array is not * rectangular with at least two rows and two columns. */ public Covariance(double[][] data) { this(data, true); } /** * Create a covariance matrix from a matrix whose columns * represent covariates. * *

                    The biasCorrected parameter determines whether or not * covariance estimates are bias-corrected.

                    * *

                    The matrix must have at least two columns and two rows

                    * * @param matrix matrix with columns representing covariates * @param biasCorrected true means covariances are bias-corrected * @throws IllegalArgumentException if the input matrix does not have * at least two rows and two columns */ public Covariance(RealMatrix matrix, boolean biasCorrected) { checkSufficientData(matrix); n = matrix.getRowDimension(); covarianceMatrix = computeCovarianceMatrix(matrix, biasCorrected); } /** * Create a covariance matrix from a matrix whose columns * represent covariates. * *

                    The matrix must have at least two columns and two rows

                    * * @param matrix matrix with columns representing covariates * @throws IllegalArgumentException if the input matrix does not have * at least two rows and two columns */ public Covariance(RealMatrix matrix) { this(matrix, true); } /** * Returns the covariance matrix * * @return covariance matrix */ public RealMatrix getCovarianceMatrix() { return covarianceMatrix; } /** * Returns the number of observations (length of covariate vectors) * * @return number of observations */ public int getN() { return n; } /** * Compute a covariance matrix from a matrix whose columns represent * covariates. * @param matrix input matrix (must have at least two columns and two rows) * @param biasCorrected determines whether or not covariance estimates are bias-corrected * @return covariance matrix */ protected RealMatrix computeCovarianceMatrix(RealMatrix matrix, boolean biasCorrected) { int dimension = matrix.getColumnDimension(); Variance variance = new Variance(biasCorrected); RealMatrix outMatrix = new BlockRealMatrix(dimension, dimension); for (int i = 0; i < dimension; i++) { for (int j = 0; j < i; j++) { double cov = covariance(matrix.getColumn(i), matrix.getColumn(j), biasCorrected); outMatrix.setEntry(i, j, cov); outMatrix.setEntry(j, i, cov); } outMatrix.setEntry(i, i, variance.evaluate(matrix.getColumn(i))); } return outMatrix; } /** * Create a covariance matrix from a matrix whose columns represent * covariates. Covariances are computed using the bias-corrected formula. * @param matrix input matrix (must have at least two columns and two rows) * @return covariance matrix * @see #Covariance */ protected RealMatrix computeCovarianceMatrix(RealMatrix matrix) { return computeCovarianceMatrix(matrix, true); } /** * Compute a covariance matrix from a rectangular array whose columns represent * covariates. * @param data input array (must have at least two columns and two rows) * @param biasCorrected determines whether or not covariance estimates are bias-corrected * @return covariance matrix */ protected RealMatrix computeCovarianceMatrix(double[][] data, boolean biasCorrected) { return computeCovarianceMatrix(new BlockRealMatrix(data), biasCorrected); } /** * Create a covariance matrix from a rectangual array whose columns represent * covariates. Covariances are computed using the bias-corrected formula. * @param data input array (must have at least two columns and two rows) * @return covariance matrix * @see #Covariance */ protected RealMatrix computeCovarianceMatrix(double[][] data) { return computeCovarianceMatrix(data, true); } /** * Computes the covariance between the two arrays. * *

                    Array lengths must match and the common length must be at least 2.

                    * * @param xArray first data array * @param yArray second data array * @param biasCorrected if true, returned value will be bias-corrected * @return returns the covariance for the two arrays * @throws IllegalArgumentException if the arrays lengths do not match or * there is insufficient data */ public double covariance(final double[] xArray, final double[] yArray, boolean biasCorrected) throws IllegalArgumentException { Mean mean = new Mean(); double result = 0d; int length = xArray.length; if (length != yArray.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, length, yArray.length); } else if (length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, length, 2); } else { double xMean = mean.evaluate(xArray); double yMean = mean.evaluate(yArray); for (int i = 0; i < length; i++) { double xDev = xArray[i] - xMean; double yDev = yArray[i] - yMean; result += (xDev * yDev - result) / (i + 1); } } return biasCorrected ? result * ((double) length / (double)(length - 1)) : result; } /** * Computes the covariance between the two arrays, using the bias-corrected * formula. * *

                    Array lengths must match and the common length must be at least 2.

                    * * @param xArray first data array * @param yArray second data array * @return returns the covariance for the two arrays * @throws IllegalArgumentException if the arrays lengths do not match or * there is insufficient data */ public double covariance(final double[] xArray, final double[] yArray) throws IllegalArgumentException { return covariance(xArray, yArray, true); } /** * Throws IllegalArgumentException of the matrix does not have at least * two columns and two rows * @param matrix matrix to check */ private void checkSufficientData(final RealMatrix matrix) { int nRows = matrix.getRowDimension(); int nCols = matrix.getColumnDimension(); if (nRows < 2 || nCols < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_ROWS_AND_COLUMNS, nRows, nCols); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/NaturalRanking.java100644 1750 1750 37350 11532241247 30565 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.ranking; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.math.exception.MathInternalError; import org.apache.commons.math.random.RandomData; import org.apache.commons.math.random.RandomDataImpl; import org.apache.commons.math.random.RandomGenerator; import org.apache.commons.math.util.FastMath; /** *

                    Ranking based on the natural ordering on doubles.

                    *

                    NaNs are treated according to the configured {@link NaNStrategy} and ties * are handled using the selected {@link TiesStrategy}. * Configuration settings are supplied in optional constructor arguments. * Defaults are {@link NaNStrategy#MAXIMAL} and {@link TiesStrategy#AVERAGE}, * respectively. When using {@link TiesStrategy#RANDOM}, a * {@link RandomGenerator} may be supplied as a constructor argument.

                    *

                    Examples: * * * * * * * * * * * * * * * * * * * * * * * *
                    * Input data: (20, 17, 30, 42.3, 17, 50, Double.NaN, Double.NEGATIVE_INFINITY, 17) *
                    NaNStrategyTiesStrategyrank(data)
                    default (NaNs maximal)default (ties averaged)(5, 3, 6, 7, 3, 8, 9, 1, 3)
                    default (NaNs maximal)MINIMUM(5, 2, 6, 7, 2, 8, 9, 1, 2)
                    MINIMALdefault (ties averaged)(6, 4, 7, 8, 4, 9, 1.5, 1.5, 4)
                    REMOVEDSEQUENTIAL(5, 2, 6, 7, 3, 8, 1, 4)
                    MINIMALMAXIMUM(6, 5, 7, 8, 5, 9, 2, 2, 5)

                    * * @since 2.0 * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $ */ public class NaturalRanking implements RankingAlgorithm { /** default NaN strategy */ public static final NaNStrategy DEFAULT_NAN_STRATEGY = NaNStrategy.MAXIMAL; /** default ties strategy */ public static final TiesStrategy DEFAULT_TIES_STRATEGY = TiesStrategy.AVERAGE; /** NaN strategy - defaults to NaNs maximal */ private final NaNStrategy nanStrategy; /** Ties strategy - defaults to ties averaged */ private final TiesStrategy tiesStrategy; /** Source of random data - used only when ties strategy is RANDOM */ private final RandomData randomData; /** * Create a NaturalRanking with default strategies for handling ties and NaNs. */ public NaturalRanking() { super(); tiesStrategy = DEFAULT_TIES_STRATEGY; nanStrategy = DEFAULT_NAN_STRATEGY; randomData = null; } /** * Create a NaturalRanking with the given TiesStrategy. * * @param tiesStrategy the TiesStrategy to use */ public NaturalRanking(TiesStrategy tiesStrategy) { super(); this.tiesStrategy = tiesStrategy; nanStrategy = DEFAULT_NAN_STRATEGY; randomData = new RandomDataImpl(); } /** * Create a NaturalRanking with the given NaNStrategy. * * @param nanStrategy the NaNStrategy to use */ public NaturalRanking(NaNStrategy nanStrategy) { super(); this.nanStrategy = nanStrategy; tiesStrategy = DEFAULT_TIES_STRATEGY; randomData = null; } /** * Create a NaturalRanking with the given NaNStrategy and TiesStrategy. * * @param nanStrategy NaNStrategy to use * @param tiesStrategy TiesStrategy to use */ public NaturalRanking(NaNStrategy nanStrategy, TiesStrategy tiesStrategy) { super(); this.nanStrategy = nanStrategy; this.tiesStrategy = tiesStrategy; randomData = new RandomDataImpl(); } /** * Create a NaturalRanking with TiesStrategy.RANDOM and the given * RandomGenerator as the source of random data. * * @param randomGenerator source of random data */ public NaturalRanking(RandomGenerator randomGenerator) { super(); this.tiesStrategy = TiesStrategy.RANDOM; nanStrategy = DEFAULT_NAN_STRATEGY; randomData = new RandomDataImpl(randomGenerator); } /** * Create a NaturalRanking with the given NaNStrategy, TiesStrategy.RANDOM * and the given source of random data. * * @param nanStrategy NaNStrategy to use * @param randomGenerator source of random data */ public NaturalRanking(NaNStrategy nanStrategy, RandomGenerator randomGenerator) { super(); this.nanStrategy = nanStrategy; this.tiesStrategy = TiesStrategy.RANDOM; randomData = new RandomDataImpl(randomGenerator); } /** * Return the NaNStrategy * * @return returns the NaNStrategy */ public NaNStrategy getNanStrategy() { return nanStrategy; } /** * Return the TiesStrategy * * @return the TiesStrategy */ public TiesStrategy getTiesStrategy() { return tiesStrategy; } /** * Rank data using the natural ordering on Doubles, with * NaN values handled according to nanStrategy and ties * resolved using tiesStrategy. * * @param data array to be ranked * @return array of ranks */ public double[] rank(double[] data) { // Array recording initial positions of data to be ranked IntDoublePair[] ranks = new IntDoublePair[data.length]; for (int i = 0; i < data.length; i++) { ranks[i] = new IntDoublePair(data[i], i); } // Recode, remove or record positions of NaNs List nanPositions = null; switch (nanStrategy) { case MAXIMAL: // Replace NaNs with +INFs recodeNaNs(ranks, Double.POSITIVE_INFINITY); break; case MINIMAL: // Replace NaNs with -INFs recodeNaNs(ranks, Double.NEGATIVE_INFINITY); break; case REMOVED: // Drop NaNs from data ranks = removeNaNs(ranks); break; case FIXED: // Record positions of NaNs nanPositions = getNanPositions(ranks); break; default: // this should not happen unless NaNStrategy enum is changed throw new MathInternalError(); } // Sort the IntDoublePairs Arrays.sort(ranks); // Walk the sorted array, filling output array using sorted positions, // resolving ties as we go double[] out = new double[ranks.length]; int pos = 1; // position in sorted array out[ranks[0].getPosition()] = pos; List tiesTrace = new ArrayList(); tiesTrace.add(ranks[0].getPosition()); for (int i = 1; i < ranks.length; i++) { if (Double.compare(ranks[i].getValue(), ranks[i - 1].getValue()) > 0) { // tie sequence has ended (or had length 1) pos = i + 1; if (tiesTrace.size() > 1) { // if seq is nontrivial, resolve resolveTie(out, tiesTrace); } tiesTrace = new ArrayList(); tiesTrace.add(ranks[i].getPosition()); } else { // tie sequence continues tiesTrace.add(ranks[i].getPosition()); } out[ranks[i].getPosition()] = pos; } if (tiesTrace.size() > 1) { // handle tie sequence at end resolveTie(out, tiesTrace); } if (nanStrategy == NaNStrategy.FIXED) { restoreNaNs(out, nanPositions); } return out; } /** * Returns an array that is a copy of the input array with IntDoublePairs * having NaN values removed. * * @param ranks input array * @return array with NaN-valued entries removed */ private IntDoublePair[] removeNaNs(IntDoublePair[] ranks) { if (!containsNaNs(ranks)) { return ranks; } IntDoublePair[] outRanks = new IntDoublePair[ranks.length]; int j = 0; for (int i = 0; i < ranks.length; i++) { if (Double.isNaN(ranks[i].getValue())) { // drop, but adjust original ranks of later elements for (int k = i + 1; k < ranks.length; k++) { ranks[k] = new IntDoublePair( ranks[k].getValue(), ranks[k].getPosition() - 1); } } else { outRanks[j] = new IntDoublePair( ranks[i].getValue(), ranks[i].getPosition()); j++; } } IntDoublePair[] returnRanks = new IntDoublePair[j]; System.arraycopy(outRanks, 0, returnRanks, 0, j); return returnRanks; } /** * Recodes NaN values to the given value. * * @param ranks array to recode * @param value the value to replace NaNs with */ private void recodeNaNs(IntDoublePair[] ranks, double value) { for (int i = 0; i < ranks.length; i++) { if (Double.isNaN(ranks[i].getValue())) { ranks[i] = new IntDoublePair( value, ranks[i].getPosition()); } } } /** * Checks for presence of NaNs in ranks. * * @param ranks array to be searched for NaNs * @return true iff ranks contains one or more NaNs */ private boolean containsNaNs(IntDoublePair[] ranks) { for (int i = 0; i < ranks.length; i++) { if (Double.isNaN(ranks[i].getValue())) { return true; } } return false; } /** * Resolve a sequence of ties, using the configured {@link TiesStrategy}. * The input ranks array is expected to take the same value * for all indices in tiesTrace. The common value is recoded * according to the tiesStrategy. For example, if ranks = <5,8,2,6,2,7,1,2>, * tiesTrace = <2,4,7> and tiesStrategy is MINIMUM, ranks will be unchanged. * The same array and trace with tiesStrategy AVERAGE will come out * <5,8,3,6,3,7,1,3>. * * @param ranks array of ranks * @param tiesTrace list of indices where ranks is constant * -- that is, for any i and j in TiesTrace, ranks[i] == ranks[j] * */ private void resolveTie(double[] ranks, List tiesTrace) { // constant value of ranks over tiesTrace final double c = ranks[tiesTrace.get(0)]; // length of sequence of tied ranks final int length = tiesTrace.size(); switch (tiesStrategy) { case AVERAGE: // Replace ranks with average fill(ranks, tiesTrace, (2 * c + length - 1) / 2d); break; case MAXIMUM: // Replace ranks with maximum values fill(ranks, tiesTrace, c + length - 1); break; case MINIMUM: // Replace ties with minimum fill(ranks, tiesTrace, c); break; case RANDOM: // Fill with random integral values in [c, c + length - 1] Iterator iterator = tiesTrace.iterator(); long f = FastMath.round(c); while (iterator.hasNext()) { ranks[iterator.next()] = randomData.nextLong(f, f + length - 1); } break; case SEQUENTIAL: // Fill sequentially from c to c + length - 1 // walk and fill iterator = tiesTrace.iterator(); f = FastMath.round(c); int i = 0; while (iterator.hasNext()) { ranks[iterator.next()] = f + i++; } break; default: // this should not happen unless TiesStrategy enum is changed throw new MathInternalError(); } } /** * Setsdata[i] = value for each i in tiesTrace. * * @param data array to modify * @param tiesTrace list of index values to set * @param value value to set */ private void fill(double[] data, List tiesTrace, double value) { Iterator iterator = tiesTrace.iterator(); while (iterator.hasNext()) { data[iterator.next()] = value; } } /** * Set ranks[i] = Double.NaN for each i in nanPositions. * * @param ranks array to modify * @param nanPositions list of index values to set to Double.NaN */ private void restoreNaNs(double[] ranks, List nanPositions) { if (nanPositions.size() == 0) { return; } Iterator iterator = nanPositions.iterator(); while (iterator.hasNext()) { ranks[iterator.next().intValue()] = Double.NaN; } } /** * Returns a list of indexes where ranks is NaN. * * @param ranks array to search for NaNs * @return list of indexes i such that ranks[i] = NaN */ private List getNanPositions(IntDoublePair[] ranks) { ArrayList out = new ArrayList(); for (int i = 0; i < ranks.length; i++) { if (Double.isNaN(ranks[i].getValue())) { out.add(Integer.valueOf(i)); } } return out; } /** * Represents the position of a double value in an ordering. * Comparable interface is implemented so Arrays.sort can be used * to sort an array of IntDoublePairs by value. Note that the * implicitly defined natural ordering is NOT consistent with equals. */ private static class IntDoublePair implements Comparable { /** Value of the pair */ private final double value; /** Original position of the pair */ private final int position; /** * Construct an IntDoublePair with the given value and position. * @param value the value of the pair * @param position the original position */ public IntDoublePair(double value, int position) { this.value = value; this.position = position; } /** * Compare this IntDoublePair to another pair. * Only the values are compared. * * @param other the other pair to compare this to * @return result of Double.compare(value, other.value) */ public int compareTo(IntDoublePair other) { return Double.compare(value, other.value); } /** * Returns the value of the pair. * @return value */ public double getValue() { return value; } /** * Returns the original position of the pair. * @return position */ public int getPosition() { return position; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/TiesStrategy.java100644 1750 1750 4333 11532241247 30247 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.ranking; /** * Strategies for handling tied values in rank transformations. *
                      *
                    • SEQUENTIAL - Ties are assigned ranks in order of occurrence in the original array, * for example (1,3,4,3) is ranked as (1,2,4,3)
                    • *
                    • MINIMUM - Tied values are assigned the minimum applicable rank, or the rank * of the first occurrence. For example, (1,3,4,3) is ranked as (1,2,4,2)
                    • *
                    • MAXIMUM - Tied values are assigned the maximum applicable rank, or the rank * of the last occurrence. For example, (1,3,4,3) is ranked as (1,3,4,3)
                    • *
                    • AVERAGE - Tied values are assigned the average of the applicable ranks. * For example, (1,3,4,3) is ranked as (1,2.5,4,2.5)
                    • *
                    • RANDOM - Tied values are assigned a random integer rank from among the * applicable values. The assigned rank will always be an integer, (inclusively) * between the values returned by the MINIMUM and MAXIMUM strategies.
                    • *
                    * * @since 2.0 * @version $Revision: 981332 $ $Date: 2010-08-02 00:24:31 +0200 (lun. 02 août 2010) $ */ public enum TiesStrategy { /** Ties assigned sequential ranks in order of occurrence */ SEQUENTIAL, /** Ties get the minimum applicable rank */ MINIMUM, /** Ties get the maximum applicable rank */ MAXIMUM, /** Ties get the average of applicable ranks */ AVERAGE, /** Ties get a random integral value from among applicable ranks */ RANDOM } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/package.html100644 1750 1750 1622 11532241247 27234 0ustarlucluc 0 0 Classes providing rank transformations. commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/NaNStrategy.java100644 1750 1750 3464 11532241247 30023 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.ranking; /** * Strategies for handling NaN values in rank transformations. *
                      *
                    • MINIMAL - NaNs are treated as minimal in the ordering, equivalent to * (that is, tied with) Double.NEGATIVE_INFINITY.
                    • *
                    • MAXIMAL - NaNs are treated as maximal in the ordering, equivalent to * Double.POSITIVE_INFINITY
                    • *
                    • REMOVED - NaNs are removed before the rank transform is applied
                    • *
                    • FIXED - NaNs are left "in place," that is the rank transformation is * applied to the other elements in the input array, but the NaN elements * are returned unchanged.
                    • *
                    * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public enum NaNStrategy { /** NaNs are considered minimal in the ordering */ MINIMAL, /** NaNs are considered maximal in the ordering */ MAXIMAL, /** NaNs are removed before computing ranks */ REMOVED, /** NaNs are left in place */ FIXED } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/ranking/RankingAlgorithm.java100644 1750 1750 3217 11532241247 31060 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.ranking; /** * Interface representing a rank transformation. * * @since 2.0 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface RankingAlgorithm { /** *

                    Performs a rank transformation on the input data, returning an array * of ranks.

                    * *

                    Ranks should be 1-based - that is, the smallest value * returned in an array of ranks should be greater than or equal to one, * rather than 0. Ranks should in general take integer values, though * implementations may return averages or other floating point values * to resolve ties in the input data.

                    * * @param data array of data to be ranked * @return an array of ranks corresponding to the elements of the input array */ double[] rank (double[] data); } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/StatUtils.java100644 1750 1750 64503 11532241247 26150 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; import org.apache.commons.math.stat.descriptive.moment.GeometricMean; import org.apache.commons.math.stat.descriptive.moment.Mean; import org.apache.commons.math.stat.descriptive.moment.Variance; import org.apache.commons.math.stat.descriptive.rank.Max; import org.apache.commons.math.stat.descriptive.rank.Min; import org.apache.commons.math.stat.descriptive.rank.Percentile; import org.apache.commons.math.stat.descriptive.summary.Product; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; /** * StatUtils provides static methods for computing statistics based on data * stored in double[] arrays. * * @version $Revision: 1073276 $ $Date: 2011-02-22 10:34:52 +0100 (mar. 22 févr. 2011) $ */ public final class StatUtils { /** sum */ private static final UnivariateStatistic SUM = new Sum(); /** sumSq */ private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares(); /** prod */ private static final UnivariateStatistic PRODUCT = new Product(); /** sumLog */ private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs(); /** min */ private static final UnivariateStatistic MIN = new Min(); /** max */ private static final UnivariateStatistic MAX = new Max(); /** mean */ private static final UnivariateStatistic MEAN = new Mean(); /** variance */ private static final Variance VARIANCE = new Variance(); /** percentile */ private static final Percentile PERCENTILE = new Percentile(); /** geometric mean */ private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean(); /** * Private Constructor */ private StatUtils() { } /** * Returns the sum of the values in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the input array * is null.

                    * * @param values array of values to sum * @return the sum of the values or Double.NaN if the array * is empty * @throws IllegalArgumentException if the array is null */ public static double sum(final double[] values) { return SUM.evaluate(values); } /** * Returns the sum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double sum(final double[] values, final int begin, final int length) { return SUM.evaluate(values, begin, length); } /** * Returns the sum of the squares of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values input array * @return the sum of the squared values or Double.NaN if the * array is empty * @throws IllegalArgumentException if the array is null */ public static double sumSq(final double[] values) { return SUM_OF_SQUARES.evaluate(values); } /** * Returns the sum of the squares of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the squares of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double sumSq(final double[] values, final int begin, final int length) { return SUM_OF_SQUARES.evaluate(values, begin, length); } /** * Returns the product of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @return the product of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double product(final double[] values) { return PRODUCT.evaluate(values); } /** * Returns the product of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the product of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double product(final double[] values, final int begin, final int length) { return PRODUCT.evaluate(values, begin, length); } /** * Returns the sum of the natural logs of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}. *

                    * * @param values the input array * @return the sum of the natural logs of the values or Double.NaN if * the array is empty * @throws IllegalArgumentException if the array is null */ public static double sumLog(final double[] values) { return SUM_OF_LOGS.evaluate(values); } /** * Returns the sum of the natural logs of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}. *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the sum of the natural logs of the values or Double.NaN if * length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double sumLog(final double[] values, final int begin, final int length) { return SUM_OF_LOGS.evaluate(values, begin, length); } /** * Returns the arithmetic mean of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for * details on the computing algorithm.

                    * * @param values the input array * @return the mean of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double mean(final double[] values) { return MEAN.evaluate(values); } /** * Returns the arithmetic mean of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for * details on the computing algorithm.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the mean of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double mean(final double[] values, final int begin, final int length) { return MEAN.evaluate(values, begin, length); } /** * Returns the geometric mean of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean} * for details on the computing algorithm.

                    * * @param values the input array * @return the geometric mean of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double geometricMean(final double[] values) { return GEOMETRIC_MEAN.evaluate(values); } /** * Returns the geometric mean of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean} * for details on the computing algorithm.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the geometric mean of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double geometricMean(final double[] values, final int begin, final int length) { return GEOMETRIC_MEAN.evaluate(values, begin, length); } /** * Returns the variance of the entries in the input array, or * Double.NaN if the array is empty. *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for * details on the computing algorithm.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @return the variance of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double variance(final double[] values) { return VARIANCE.evaluate(values); } /** * Returns the variance of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for * details on the computing algorithm.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null or the * array index parameters are not valid.

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double variance(final double[] values, final int begin, final int length) { return VARIANCE.evaluate(values, begin, length); } /** * Returns the variance of the entries in the specified portion of * the input array, using the precomputed mean value. Returns * Double.NaN if the designated subarray is empty. *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for * details on the computing algorithm.

                    *

                    * The formula used assumes that the supplied mean value is the arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null or the * array index parameters are not valid.

                    * * @param values the input array * @param mean the precomputed mean value * @param begin index of the first array element to include * @param length the number of elements to include * @return the variance of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double variance(final double[] values, final double mean, final int begin, final int length) { return VARIANCE.evaluate(values, mean, begin, length); } /** * Returns the variance of the entries in the input array, using the * precomputed mean value. Returns Double.NaN if the array * is empty. *

                    * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for * details on the computing algorithm.

                    *

                    * The formula used assumes that the supplied mean value is the arithmetic * mean of the sample data, not a known population parameter. This method * is supplied only to save computation when the mean has already been * computed.

                    *

                    * Returns 0 for a single-value (i.e. length = 1) sample.

                    *

                    * Throws IllegalArgumentException if the array is null.

                    * * @param values the input array * @param mean the precomputed mean value * @return the variance of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double variance(final double[] values, final double mean) { return VARIANCE.evaluate(values, mean); } /** * Returns the maximum of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.POSITIVE_INFINITY, * the result is Double.POSITIVE_INFINITY.
                    • *

                    * * @param values the input array * @return the maximum of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double max(final double[] values) { return MAX.evaluate(values); } /** * Returns the maximum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null or * the array index parameters are not valid.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.POSITIVE_INFINITY, * the result is Double.POSITIVE_INFINITY.
                    • *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the maximum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double max(final double[] values, final int begin, final int length) { return MAX.evaluate(values, begin, length); } /** * Returns the minimum of the entries in the input array, or * Double.NaN if the array is empty. *

                    * Throws IllegalArgumentException if the array is null.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.NEGATIVE_INFINITY, * the result is Double.NEGATIVE_INFINITY.
                    • *

                    * * @param values the input array * @return the minimum of the values or Double.NaN if the array is empty * @throws IllegalArgumentException if the array is null */ public static double min(final double[] values) { return MIN.evaluate(values); } /** * Returns the minimum of the entries in the specified portion of * the input array, or Double.NaN if the designated subarray * is empty. *

                    * Throws IllegalArgumentException if the array is null or * the array index parameters are not valid.

                    *

                    *

                      *
                    • The result is NaN iff all values are NaN * (i.e. NaN values have no impact on the value of the statistic).
                    • *
                    • If any of the values equals Double.NEGATIVE_INFINITY, * the result is Double.NEGATIVE_INFINITY.
                    • *

                    * * @param values the input array * @param begin index of the first array element to include * @param length the number of elements to include * @return the minimum of the values or Double.NaN if length = 0 * @throws IllegalArgumentException if the array is null or the array index * parameters are not valid */ public static double min(final double[] values, final int begin, final int length) { return MIN.evaluate(values, begin, length); } /** * Returns an estimate of the pth percentile of the values * in the values array. *

                    *

                      *
                    • Returns Double.NaN if values has length * 0
                    • *
                    • Returns (for any value of p) values[0] * if values has length 1
                    • *
                    • Throws IllegalArgumentException if values * is null or p is not a valid quantile value (p must be greater than 0 * and less than or equal to 100)
                    • *

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for * a description of the percentile estimation algorithm used.

                    * * @param values input array of values * @param p the percentile value to compute * @return the percentile value or Double.NaN if the array is empty * @throws IllegalArgumentException if values is null * or p is invalid */ public static double percentile(final double[] values, final double p) { return PERCENTILE.evaluate(values,p); } /** * Returns an estimate of the pth percentile of the values * in the values array, starting with the element in (0-based) * position begin in the array and including length * values. *

                    *

                      *
                    • Returns Double.NaN if length = 0
                    • *
                    • Returns (for any value of p) values[begin] * if length = 1
                    • *
                    • Throws IllegalArgumentException if values * is null , begin or length is invalid, or * p is not a valid quantile value (p must be greater than 0 * and less than or equal to 100)
                    • *

                    *

                    * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for * a description of the percentile estimation algorithm used.

                    * * @param values array of input values * @param p the percentile to compute * @param begin the first (0-based) element to include in the computation * @param length the number of array elements to include * @return the percentile value * @throws IllegalArgumentException if the parameters are not valid or the * input array is null */ public static double percentile(final double[] values, final int begin, final int length, final double p) { return PERCENTILE.evaluate(values, begin, length, p); } /** * Returns the sum of the (signed) differences between corresponding elements of the * input arrays -- i.e., sum(sample1[i] - sample2[i]). * * @param sample1 the first array * @param sample2 the second array * @return sum of paired differences * @throws IllegalArgumentException if the arrays do not have the same * (positive) length */ public static double sumDifference(final double[] sample1, final double[] sample2) throws IllegalArgumentException { int n = sample1.length; if (n != sample2.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, sample2.length); } if (n < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, sample2.length, 1); } double result = 0; for (int i = 0; i < n; i++) { result += sample1[i] - sample2[i]; } return result; } /** * Returns the mean of the (signed) differences between corresponding elements of the * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length. * * @param sample1 the first array * @param sample2 the second array * @return mean of paired differences * @throws IllegalArgumentException if the arrays do not have the same * (positive) length */ public static double meanDifference(final double[] sample1, final double[] sample2) throws IllegalArgumentException { return sumDifference(sample1, sample2) / sample1.length; } /** * Returns the variance of the (signed) differences between corresponding elements of the * input arrays -- i.e., var(sample1[i] - sample2[i]). * * @param sample1 the first array * @param sample2 the second array * @param meanDifference the mean difference between corresponding entries * @see #meanDifference(double[],double[]) * @return variance of paired differences * @throws IllegalArgumentException if the arrays do not have the same * length or their common length is less than 2. */ public static double varianceDifference(final double[] sample1, final double[] sample2, double meanDifference) throws IllegalArgumentException { double sum1 = 0d; double sum2 = 0d; double diff = 0d; int n = sample1.length; if (n != sample2.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, sample2.length); } if (n < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, n, 2); } for (int i = 0; i < n; i++) { diff = sample1[i] - sample2[i]; sum1 += (diff - meanDifference) *(diff - meanDifference); sum2 += diff - meanDifference; } return (sum1 - (sum2 * sum2 / n)) / (n - 1); } /** * Normalize (standardize) the series, so in the end it is having a mean of 0 and a standard deviation of 1. * * @param sample sample to normalize * @return normalized (standardized) sample * @since 2.2 */ public static double[] normalize(final double[] sample) { DescriptiveStatistics stats = new DescriptiveStatistics(); // Add the data from the series to stats for (int i = 0; i < sample.length; i++) { stats.addValue(sample[i]); } // Compute mean and standard deviation double mean = stats.getMean(); double standardDeviation = stats.getStandardDeviation(); // initialize the standardizedSample, which has the same length as the sample double[] standardizedSample = new double[sample.length]; for (int i = 0; i < sample.length; i++) { // z = (x- mean)/standardDeviation standardizedSample[i] = (sample[i] - mean) / standardDeviation; } return standardizedSample; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTestImpl.java100644 1750 1750 40137 11532241247 31515 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.distribution.ChiSquaredDistribution; import org.apache.commons.math.distribution.ChiSquaredDistributionImpl; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements Chi-Square test statistics defined in the * {@link UnknownDistributionChiSquareTest} interface. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class ChiSquareTestImpl implements UnknownDistributionChiSquareTest { /** Distribution used to compute inference statistics. */ private ChiSquaredDistribution distribution; /** * Construct a ChiSquareTestImpl */ public ChiSquareTestImpl() { this(new ChiSquaredDistributionImpl(1.0)); } /** * Create a test instance using the given distribution for computing * inference statistics. * @param x distribution used to compute inference statistics. * @since 1.2 */ public ChiSquareTestImpl(ChiSquaredDistribution x) { super(); setDistribution(x); } /** * {@inheritDoc} *

                    Note: This implementation rescales the * expected array if necessary to ensure that the sum of the * expected and observed counts are equal.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @return chi-square test statistic * @throws IllegalArgumentException if preconditions are not met * or length is less than 2 */ public double chiSquare(double[] expected, long[] observed) throws IllegalArgumentException { if (expected.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, expected.length, 2); } if (expected.length != observed.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, expected.length, observed.length); } checkPositive(expected); checkNonNegative(observed); double sumExpected = 0d; double sumObserved = 0d; for (int i = 0; i < observed.length; i++) { sumExpected += expected[i]; sumObserved += observed[i]; } double ratio = 1.0d; boolean rescale = false; if (FastMath.abs(sumExpected - sumObserved) > 10E-6) { ratio = sumObserved / sumExpected; rescale = true; } double sumSq = 0.0d; for (int i = 0; i < observed.length; i++) { if (rescale) { final double dev = observed[i] - ratio * expected[i]; sumSq += dev * dev / (ratio * expected[i]); } else { final double dev = observed[i] - expected[i]; sumSq += dev * dev / expected[i]; } } return sumSq; } /** * {@inheritDoc} *

                    Note: This implementation rescales the * expected array if necessary to ensure that the sum of the * expected and observed counts are equal.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value */ public double chiSquareTest(double[] expected, long[] observed) throws IllegalArgumentException, MathException { distribution.setDegreesOfFreedom(expected.length - 1.0); return 1.0 - distribution.cumulativeProbability( chiSquare(expected, observed)); } /** * {@inheritDoc} *

                    Note: This implementation rescales the * expected array if necessary to ensure that the sum of the * expected and observed counts are equal.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean chiSquareTest(double[] expected, long[] observed, double alpha) throws IllegalArgumentException, MathException { if ((alpha <= 0) || (alpha > 0.5)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0, 0.5); } return chiSquareTest(expected, observed) < alpha; } /** * @param counts array representation of 2-way table * @return chi-square test statistic * @throws IllegalArgumentException if preconditions are not met */ public double chiSquare(long[][] counts) throws IllegalArgumentException { checkArray(counts); int nRows = counts.length; int nCols = counts[0].length; // compute row, column and total sums double[] rowSum = new double[nRows]; double[] colSum = new double[nCols]; double total = 0.0d; for (int row = 0; row < nRows; row++) { for (int col = 0; col < nCols; col++) { rowSum[row] += counts[row][col]; colSum[col] += counts[row][col]; total += counts[row][col]; } } // compute expected counts and chi-square double sumSq = 0.0d; double expected = 0.0d; for (int row = 0; row < nRows; row++) { for (int col = 0; col < nCols; col++) { expected = (rowSum[row] * colSum[col]) / total; sumSq += ((counts[row][col] - expected) * (counts[row][col] - expected)) / expected; } } return sumSq; } /** * @param counts array representation of 2-way table * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value */ public double chiSquareTest(long[][] counts) throws IllegalArgumentException, MathException { checkArray(counts); double df = ((double) counts.length -1) * ((double) counts[0].length - 1); distribution.setDegreesOfFreedom(df); return 1 - distribution.cumulativeProbability(chiSquare(counts)); } /** * @param counts array representation of 2-way table * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean chiSquareTest(long[][] counts, double alpha) throws IllegalArgumentException, MathException { if ((alpha <= 0) || (alpha > 0.5)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0.0, 0.5); } return chiSquareTest(counts) < alpha; } /** * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @return chi-square test statistic * @throws IllegalArgumentException if preconditions are not met * @since 1.2 */ public double chiSquareDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException { // Make sure lengths are same if (observed1.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, observed1.length, 2); } if (observed1.length != observed2.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, observed1.length, observed2.length); } // Ensure non-negative counts checkNonNegative(observed1); checkNonNegative(observed2); // Compute and compare count sums long countSum1 = 0; long countSum2 = 0; boolean unequalCounts = false; double weight = 0.0; for (int i = 0; i < observed1.length; i++) { countSum1 += observed1[i]; countSum2 += observed2[i]; } // Ensure neither sample is uniformly 0 if (countSum1 == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OBSERVED_COUNTS_ALL_ZERO, 1); } if (countSum2 == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OBSERVED_COUNTS_ALL_ZERO, 2); } // Compare and compute weight only if different unequalCounts = countSum1 != countSum2; if (unequalCounts) { weight = FastMath.sqrt((double) countSum1 / (double) countSum2); } // Compute ChiSquare statistic double sumSq = 0.0d; double dev = 0.0d; double obs1 = 0.0d; double obs2 = 0.0d; for (int i = 0; i < observed1.length; i++) { if (observed1[i] == 0 && observed2[i] == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY, i); } else { obs1 = observed1[i]; obs2 = observed2[i]; if (unequalCounts) { // apply weights dev = obs1/weight - obs2 * weight; } else { dev = obs1 - obs2; } sumSq += (dev * dev) / (obs1 + obs2); } } return sumSq; } /** * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value * @since 1.2 */ public double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException, MathException { distribution.setDegreesOfFreedom((double) observed1.length - 1); return 1 - distribution.cumulativeProbability( chiSquareDataSetsComparison(observed1, observed2)); } /** * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test * @since 1.2 */ public boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, double alpha) throws IllegalArgumentException, MathException { if ((alpha <= 0) || (alpha > 0.5)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0.0, 0.5); } return chiSquareTestDataSetsComparison(observed1, observed2) < alpha; } /** * Checks to make sure that the input long[][] array is rectangular, * has at least 2 rows and 2 columns, and has all non-negative entries, * throwing IllegalArgumentException if any of these checks fail. * * @param in input 2-way table to check * @throws IllegalArgumentException if the array is not valid */ private void checkArray(long[][] in) throws IllegalArgumentException { if (in.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, in.length, 2); } if (in[0].length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, in[0].length, 2); } checkRectangular(in); checkNonNegative(in); } //--------------------- Private array methods -- should find a utility home for these /** * Throws IllegalArgumentException if the input array is not rectangular. * * @param in array to be tested * @throws NullPointerException if input array is null * @throws IllegalArgumentException if input array is not rectangular */ private void checkRectangular(long[][] in) { for (int i = 1; i < in.length; i++) { if (in[i].length != in[0].length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIFFERENT_ROWS_LENGTHS, in[i].length, in[0].length); } } } /** * Check all entries of the input array are > 0. * * @param in array to be tested * @exception IllegalArgumentException if one entry is not positive */ private void checkPositive(double[] in) throws IllegalArgumentException { for (int i = 0; i < in.length; i++) { if (in[i] <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_ELEMENT_AT_INDEX, i, in[i]); } } } /** * Check all entries of the input array are >= 0. * * @param in array to be tested * @exception IllegalArgumentException if one entry is negative */ private void checkNonNegative(long[] in) throws IllegalArgumentException { for (int i = 0; i < in.length; i++) { if (in[i] < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, i, in[i]); } } } /** * Check all entries of the input array are >= 0. * * @param in array to be tested * @exception IllegalArgumentException if one entry is negative */ private void checkNonNegative(long[][] in) throws IllegalArgumentException { for (int i = 0; i < in.length; i ++) { for (int j = 0; j < in[i].length; j++) { if (in[i][j] < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_ELEMENT_AT_2D_INDEX, i, j, in[i][j]); } } } } /** * Modify the distribution used to compute inference statistics. * * @param value * the new distribution * @since 1.2 */ public void setDistribution(ChiSquaredDistribution value) { distribution = value; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/TTest.java100644 1750 1750 106770 11532241247 27240 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; import org.apache.commons.math.stat.descriptive.StatisticalSummary; /** * An interface for Student's t-tests. *

                    * Tests can be:

                      *
                    • One-sample or two-sample
                    • *
                    • One-sided or two-sided
                    • *
                    • Paired or unpaired (for two-sample tests)
                    • *
                    • Homoscedastic (equal variance assumption) or heteroscedastic * (for two sample tests)
                    • *
                    • Fixed significance level (boolean-valued) or returning p-values. *

                    *

                    * Test statistics are available for all tests. Methods including "Test" in * in their names perform tests, all other methods return t-statistics. Among * the "Test" methods, double-valued methods return p-values; * boolean-valued methods perform fixed significance level tests. * Significance levels are always specified as numbers between 0 and 0.5 * (e.g. tests at the 95% level use alpha=0.05).

                    *

                    * Input to tests can be either double[] arrays or * {@link StatisticalSummary} instances.

                    * * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface TTest { /** * Computes a paired, 2-sample t-statistic based on the data in the input * arrays. The t-statistic returned is equivalent to what would be returned by * computing the one-sample t-statistic {@link #t(double, double[])}, with * mu = 0 and the sample array consisting of the (signed) * differences between corresponding entries in sample1 and * sample2. *

                    * Preconditions:

                      *
                    • The input arrays must have the same length and their common length * must be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met * @throws MathException if the statistic can not be computed do to a * convergence or other numerical error. */ double pairedT(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a paired, two-sample, two-tailed t-test * based on the data in the input arrays. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean of the paired * differences is 0 in favor of the two-sided alternative that the mean paired * difference is not equal to 0. For a one-sided test, divide the returned * value by 2.

                    *

                    * This test is equivalent to a one-sample t-test computed using * {@link #tTest(double, double[])} with mu = 0 and the sample * array consisting of the signed differences between corresponding elements of * sample1 and sample2.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The input array lengths must be the same and their common length must * be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double pairedTTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException; /** * Performs a paired t-test evaluating the null hypothesis that the * mean of the paired differences between sample1 and * sample2 is 0 in favor of the two-sided alternative that the * mean paired difference is not equal to 0, with significance level * alpha. *

                    * Returns true iff the null hypothesis can be rejected with * confidence 1 - alpha. To perform a 1-sided test, use * alpha * 2

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The input array lengths must be the same and their common length * must be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ boolean pairedTTest( double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException; /** * Computes a * t statistic given observed values and a comparison constant. *

                    * This statistic can be used to perform a one sample t-test for the mean. *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu comparison constant * @param observed array of values * @return t statistic * @throws IllegalArgumentException if input array length is less than 2 */ double t(double mu, double[] observed) throws IllegalArgumentException; /** * Computes a * t statistic to use in comparing the mean of the dataset described by * sampleStats to mu. *

                    * This statistic can be used to perform a one sample t-test for the mean. *

                    * Preconditions:

                      *
                    • observed.getN() > = 2. *

                    * * @param mu comparison constant * @param sampleStats DescriptiveStatistics holding sample summary statitstics * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ double t(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException; /** * Computes a 2-sample t statistic, under the hypothesis of equal * subpopulation variances. To compute a t-statistic without the * equal variances hypothesis, use {@link #t(double[], double[])}. *

                    * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

                    *

                    * The t-statisitc is

                    *

                    *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

                    * where n1 is the size of first sample; * n2 is the size of second sample; * m1 is the mean of first sample; * m2 is the mean of second sample * * and var is the pooled variance estimate: *

                    * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) *

                    * with var1 the variance of the first sample and * var2 the variance of the second sample. *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ double homoscedasticT(double[] sample1, double[] sample2) throws IllegalArgumentException; /** * Computes a 2-sample t statistic, without the hypothesis of equal * subpopulation variances. To compute a t-statistic assuming equal * variances, use {@link #homoscedasticT(double[], double[])}. *

                    * This statistic can be used to perform a two-sample t-test to compare * sample means.

                    *

                    * The t-statisitc is

                    *

                    *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

                    * where n1 is the size of the first sample * n2 is the size of the second sample; * m1 is the mean of the first sample; * m2 is the mean of the second sample; * var1 is the variance of the first sample; * var2 is the variance of the second sample; *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ double t(double[] sample1, double[] sample2) throws IllegalArgumentException; /** * Computes a 2-sample t statistic , comparing the means of the datasets * described by two {@link StatisticalSummary} instances, without the * assumption of equal subpopulation variances. Use * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to * compute a t-statistic under the equal variances assumption. *

                    * This statistic can be used to perform a two-sample t-test to compare * sample means.

                    *

                    * The returned t-statisitc is

                    *

                    *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

                    * where n1 is the size of the first sample; * n2 is the size of the second sample; * m1 is the mean of the first sample; * m2 is the mean of the second sample * var1 is the variance of the first sample; * var2 is the variance of the second sample *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ double t( StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException; /** * Computes a 2-sample t statistic, comparing the means of the datasets * described by two {@link StatisticalSummary} instances, under the * assumption of equal subpopulation variances. To compute a t-statistic * without the equal variances assumption, use * {@link #t(StatisticalSummary, StatisticalSummary)}. *

                    * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

                    *

                    * The t-statisitc returned is

                    *

                    *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

                    * where n1 is the size of first sample; * n2 is the size of second sample; * m1 is the mean of first sample; * m2 is the mean of second sample * and var is the pooled variance estimate: *

                    * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) *

                    * with var1 the variance of the first sample and * var2 the variance of the second sample. *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ double homoscedasticT( StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException; /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test * comparing the mean of the input array with the constant mu. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean equals * mu in favor of the two-sided alternative that the mean * is different from mu. For a one-sided test, divide the * returned value by 2.

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu constant value to compare sample mean against * @param sample array of sample data values * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double tTest(double mu, double[] sample) throws IllegalArgumentException, MathException; /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the population from * which sample is drawn equals mu. *

                    * Returns true iff the null hypothesis can be * rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis sample mean = mu at * the 95% level, use
                      tTest(mu, sample, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis sample mean < mu * at the 99% level, first verify that the measured sample mean is less * than mu and then use *
                      tTest(mu, sample, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the one-sample * parametric t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu constant value to compare sample mean against * @param sample array of sample data values * @param alpha significance level of the test * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error computing the p-value */ boolean tTest(double mu, double[] sample, double alpha) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test * comparing the mean of the dataset described by sampleStats * with the constant mu. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean equals * mu in favor of the two-sided alternative that the mean * is different from mu. For a one-sided test, divide the * returned value by 2.

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The sample must contain at least 2 observations. *

                    * * @param mu constant value to compare sample mean against * @param sampleStats StatisticalSummary describing sample data * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double tTest(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException, MathException; /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the * population from which the dataset described by stats is * drawn equals mu. *

                    * Returns true iff the null hypothesis can be rejected with * confidence 1 - alpha. To perform a 1-sided test, use * alpha * 2.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis sample mean = mu at * the 95% level, use
                      tTest(mu, sampleStats, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis sample mean < mu * at the 99% level, first verify that the measured sample mean is less * than mu and then use *
                      tTest(mu, sampleStats, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the one-sample * parametric t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The sample must include at least 2 observations. *

                    * * @param mu constant value to compare sample mean against * @param sampleStats StatisticalSummary describing sample data values * @param alpha significance level of the test * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ boolean tTest( double mu, StatisticalSummary sampleStats, double alpha) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the input arrays. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * The test does not assume that the underlying popuation variances are * equal and it uses approximated degrees of freedom computed from the * sample data to compute the p-value. The t-statistic used is as defined in * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation * to the degrees of freedom is used, * as described * * here. To perform the test under the assumption of equal subpopulation * variances, use {@link #homoscedasticTTest(double[], double[])}.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double tTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the input arrays, under the assumption that * the two samples are drawn from subpopulations with equal variances. * To perform the test without the equal variances assumption, use * {@link #tTest(double[], double[])}.

                    *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * A pooled variance estimate is used to compute the t-statistic. See * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes * minus 2 is used as the degrees of freedom.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double homoscedasticTTest( double[] sample1, double[] sample2) throws IllegalArgumentException, MathException; /** * Performs a * * two-sided t-test evaluating the null hypothesis that sample1 * and sample2 are drawn from populations with the same mean, * with significance level alpha. This test does not assume * that the subpopulation variances are equal. To perform the test assuming * equal variances, use * {@link #homoscedasticTTest(double[], double[], double)}. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2

                    *

                    * See {@link #t(double[], double[])} for the formula used to compute the * t-statistic. Degrees of freedom are approximated using the * * Welch-Satterthwaite approximation.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95% level, use *
                      tTest(sample1, sample2, 0.05). *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2 , * at the 99% level, first verify that the measured mean of sample 1 * is less than the mean of sample 2 and then use *
                      tTest(sample1, sample2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ boolean tTest( double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException; /** * Performs a * * two-sided t-test evaluating the null hypothesis that sample1 * and sample2 are drawn from populations with the same mean, * with significance level alpha, assuming that the * subpopulation variances are equal. Use * {@link #tTest(double[], double[], double)} to perform the test without * the assumption of equal variances. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2. To perform the test * without the assumption of equal subpopulation variances, use * {@link #tTest(double[], double[], double)}.

                    *

                    * A pooled variance estimate is used to compute the t-statistic. See * {@link #t(double[], double[])} for the formula. The sum of the sample * sizes minus 2 is used as the degrees of freedom.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95% level, use
                      tTest(sample1, sample2, 0.05). *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2, * at the 99% level, first verify that the measured mean of * sample 1 is less than the mean of sample 2 * and then use *
                      tTest(sample1, sample2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ boolean homoscedasticTTest( double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the datasets described by two StatisticalSummary * instances. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * The test does not assume that the underlying popuation variances are * equal and it uses approximated degrees of freedom computed from the * sample data to compute the p-value. To perform the test assuming * equal variances, use * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double tTest( StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException; /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the datasets described by two StatisticalSummary * instances, under the hypothesis of equal subpopulation variances. To * perform a test without the equal variances assumption, use * {@link #tTest(StatisticalSummary, StatisticalSummary)}. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * See {@link #homoscedasticT(double[], double[])} for the formula used to * compute the t-statistic. The sum of the sample sizes minus 2 is used as * the degrees of freedom.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ double homoscedasticTTest( StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException; /** * Performs a * * two-sided t-test evaluating the null hypothesis that * sampleStats1 and sampleStats2 describe * datasets drawn from populations with the same mean, with significance * level alpha. This test does not assume that the * subpopulation variances are equal. To perform the test under the equal * variances assumption, use * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2

                    *

                    * See {@link #t(double[], double[])} for the formula used to compute the * t-statistic. Degrees of freedom are approximated using the * * Welch-Satterthwaite approximation.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95%, use *
                      tTest(sampleStats1, sampleStats2, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2 * at the 99% level, first verify that the measured mean of * sample 1 is less than the mean of sample 2 * and then use *
                      tTest(sampleStats1, sampleStats2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sampleStats1 StatisticalSummary describing sample data values * @param sampleStats2 StatisticalSummary describing sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ boolean tTest( StatisticalSummary sampleStats1, StatisticalSummary sampleStats2, double alpha) throws IllegalArgumentException, MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/OneWayAnova.java100644 1750 1750 10660 11532241247 30334 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; import java.util.Collection; /** * An interface for one-way ANOVA (analysis of variance). * *

                    Tests for differences between two or more categories of univariate data * (for example, the body mass index of accountants, lawyers, doctors and * computer programmers). When two categories are given, this is equivalent to * the {@link org.apache.commons.math.stat.inference.TTest}. *

                    * * @since 1.2 * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface OneWayAnova { /** * Computes the ANOVA F-value for a collection of double[] * arrays. * *

                    Preconditions:

                      *
                    • The categoryData Collection must contain * double[] arrays.
                    • *
                    • There must be at least two double[] arrays in the * categoryData collection and each of these arrays must * contain at least two values.

                    * * @param categoryData Collection of double[] * arrays each containing data for one category * @return Fvalue * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if the statistic can not be computed do to a * convergence or other numerical error. */ double anovaFValue(Collection categoryData) throws IllegalArgumentException, MathException; /** * Computes the ANOVA P-value for a collection of double[] * arrays. * *

                    Preconditions:

                      *
                    • The categoryData Collection must contain * double[] arrays.
                    • *
                    • There must be at least two double[] arrays in the * categoryData collection and each of these arrays must * contain at least two values.

                    * * @param categoryData Collection of double[] * arrays each containing data for one category * @return Pvalue * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if the statistic can not be computed do to a * convergence or other numerical error. */ double anovaPValue(Collection categoryData) throws IllegalArgumentException, MathException; /** * Performs an ANOVA test, evaluating the null hypothesis that there * is no difference among the means of the data categories. * *

                    Preconditions:

                      *
                    • The categoryData Collection must contain * double[] arrays.
                    • *
                    • There must be at least two double[] arrays in the * categoryData collection and each of these arrays must * contain at least two values.
                    • *
                    • alpha must be strictly greater than 0 and less than or equal to 0.5. *

                    * * @param categoryData Collection of double[] * arrays each containing data for one category * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if the statistic can not be computed do to a * convergence or other numerical error. */ boolean anovaTest(Collection categoryData, double alpha) throws IllegalArgumentException, MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTest.java100644 1750 1750 23366 11532241247 30700 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; /** * An interface for Chi-Square tests. *

                    This interface handles only known distributions. If the distribution is * unknown and should be provided by a sample, then the {@link UnknownDistributionChiSquareTest * UnknownDistributionChiSquareTest} extended interface should be used instead.

                    * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface ChiSquareTest { /** * Computes the * Chi-Square statistic comparing observed and expected * frequency counts. *

                    * This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that * the observed counts follow the expected distribution.

                    *

                    * Preconditions:

                      *
                    • Expected counts must all be positive. *
                    • *
                    • Observed counts must all be >= 0. *
                    • *
                    • The observed and expected arrays must have the same length and * their common length must be at least 2. *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @return chiSquare statistic * @throws IllegalArgumentException if preconditions are not met */ double chiSquare(double[] expected, long[] observed) throws IllegalArgumentException; /** * Returns the observed significance level, or * p-value, associated with a * * Chi-square goodness of fit test comparing the observed * frequency counts to those in the expected array. *

                    * The number returned is the smallest significance level at which one can reject * the null hypothesis that the observed counts conform to the frequency distribution * described by the expected counts.

                    *

                    * Preconditions:

                      *
                    • Expected counts must all be positive. *
                    • *
                    • Observed counts must all be >= 0. *
                    • *
                    • The observed and expected arrays must have the same length and * their common length must be at least 2. *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value */ double chiSquareTest(double[] expected, long[] observed) throws IllegalArgumentException, MathException; /** * Performs a * Chi-square goodness of fit test evaluating the null hypothesis that the observed counts * conform to the frequency distribution described by the expected counts, with * significance level alpha. Returns true iff the null hypothesis can be rejected * with 100 * (1 - alpha) percent confidence. *

                    * Example:
                    * To test the hypothesis that observed follows * expected at the 99% level, use

                    * chiSquareTest(expected, observed, 0.01)

                    *

                    * Preconditions:

                      *
                    • Expected counts must all be positive. *
                    • *
                    • Observed counts must all be >= 0. *
                    • *
                    • The observed and expected arrays must have the same length and * their common length must be at least 2. *
                    • 0 < alpha < 0.5 *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed array of observed frequency counts * @param expected array of expected frequency counts * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test */ boolean chiSquareTest(double[] expected, long[] observed, double alpha) throws IllegalArgumentException, MathException; /** * Computes the Chi-Square statistic associated with a * * chi-square test of independence based on the input counts * array, viewed as a two-way table. *

                    * The rows of the 2-way table are * count[0], ... , count[count.length - 1]

                    *

                    * Preconditions:

                      *
                    • All counts must be >= 0. *
                    • *
                    • The count array must be rectangular (i.e. all count[i] subarrays * must have the same length). *
                    • *
                    • The 2-way table represented by counts must have at * least 2 columns and at least 2 rows. *
                    • *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param counts array representation of 2-way table * @return chiSquare statistic * @throws IllegalArgumentException if preconditions are not met */ double chiSquare(long[][] counts) throws IllegalArgumentException; /** * Returns the observed significance level, or * p-value, associated with a * * chi-square test of independence based on the input counts * array, viewed as a two-way table. *

                    * The rows of the 2-way table are * count[0], ... , count[count.length - 1]

                    *

                    * Preconditions:

                      *
                    • All counts must be >= 0. *
                    • *
                    • The count array must be rectangular (i.e. all count[i] subarrays must have the same length). *
                    • *
                    • The 2-way table represented by counts must have at least 2 columns and * at least 2 rows. *
                    • *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param counts array representation of 2-way table * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value */ double chiSquareTest(long[][] counts) throws IllegalArgumentException, MathException; /** * Performs a * chi-square test of independence evaluating the null hypothesis that the classifications * represented by the counts in the columns of the input 2-way table are independent of the rows, * with significance level alpha. Returns true iff the null hypothesis can be rejected * with 100 * (1 - alpha) percent confidence. *

                    * The rows of the 2-way table are * count[0], ... , count[count.length - 1]

                    *

                    * Example:
                    * To test the null hypothesis that the counts in * count[0], ... , count[count.length - 1] * all correspond to the same underlying probability distribution at the 99% level, use

                    * chiSquareTest(counts, 0.01)

                    *

                    * Preconditions:

                      *
                    • All counts must be >= 0. *
                    • *
                    • The count array must be rectangular (i.e. all count[i] subarrays must have the same length). *
                    • *
                    • The 2-way table represented by counts must have at least 2 columns and * at least 2 rows. *
                    • *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param counts array representation of 2-way table * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test */ boolean chiSquareTest(long[][] counts, double alpha) throws IllegalArgumentException, MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java100644 1750 1750 133735 11532241247 30063 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.distribution.TDistribution; import org.apache.commons.math.distribution.TDistributionImpl; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.StatUtils; import org.apache.commons.math.stat.descriptive.StatisticalSummary; import org.apache.commons.math.util.FastMath; /** * Implements t-test statistics defined in the {@link TTest} interface. *

                    * Uses commons-math {@link org.apache.commons.math.distribution.TDistributionImpl} * implementation to estimate exact p-values.

                    * * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ */ public class TTestImpl implements TTest { /** Distribution used to compute inference statistics. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated private TDistribution distribution; /** * Default constructor. */ public TTestImpl() { this(new TDistributionImpl(1.0)); } /** * Create a test instance using the given distribution for computing * inference statistics. * @param t distribution used to compute inference statistics. * @since 1.2 * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public TTestImpl(TDistribution t) { super(); setDistribution(t); } /** * Computes a paired, 2-sample t-statistic based on the data in the input * arrays. The t-statistic returned is equivalent to what would be returned by * computing the one-sample t-statistic {@link #t(double, double[])}, with * mu = 0 and the sample array consisting of the (signed) * differences between corresponding entries in sample1 and * sample2. *

                    * Preconditions:

                      *
                    • The input arrays must have the same length and their common length * must be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met * @throws MathException if the statistic can not be computed do to a * convergence or other numerical error. */ public double pairedT(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { checkSampleData(sample1); checkSampleData(sample2); double meanDifference = StatUtils.meanDifference(sample1, sample2); return t(meanDifference, 0, StatUtils.varianceDifference(sample1, sample2, meanDifference), sample1.length); } /** * Returns the observed significance level, or * p-value, associated with a paired, two-sample, two-tailed t-test * based on the data in the input arrays. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean of the paired * differences is 0 in favor of the two-sided alternative that the mean paired * difference is not equal to 0. For a one-sided test, divide the returned * value by 2.

                    *

                    * This test is equivalent to a one-sample t-test computed using * {@link #tTest(double, double[])} with mu = 0 and the sample * array consisting of the signed differences between corresponding elements of * sample1 and sample2.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The input array lengths must be the same and their common length must * be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double pairedTTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { double meanDifference = StatUtils.meanDifference(sample1, sample2); return tTest(meanDifference, 0, StatUtils.varianceDifference(sample1, sample2, meanDifference), sample1.length); } /** * Performs a paired t-test evaluating the null hypothesis that the * mean of the paired differences between sample1 and * sample2 is 0 in favor of the two-sided alternative that the * mean paired difference is not equal to 0, with significance level * alpha. *

                    * Returns true iff the null hypothesis can be rejected with * confidence 1 - alpha. To perform a 1-sided test, use * alpha * 2

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The input array lengths must be the same and their common length * must be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean pairedTTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return pairedTTest(sample1, sample2) < alpha; } /** * Computes a * t statistic given observed values and a comparison constant. *

                    * This statistic can be used to perform a one sample t-test for the mean. *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu comparison constant * @param observed array of values * @return t statistic * @throws IllegalArgumentException if input array length is less than 2 */ public double t(double mu, double[] observed) throws IllegalArgumentException { checkSampleData(observed); return t(StatUtils.mean(observed), mu, StatUtils.variance(observed), observed.length); } /** * Computes a * t statistic to use in comparing the mean of the dataset described by * sampleStats to mu. *

                    * This statistic can be used to perform a one sample t-test for the mean. *

                    * Preconditions:

                      *
                    • observed.getN() > = 2. *

                    * * @param mu comparison constant * @param sampleStats DescriptiveStatistics holding sample summary statitstics * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ public double t(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException { checkSampleData(sampleStats); return t(sampleStats.getMean(), mu, sampleStats.getVariance(), sampleStats.getN()); } /** * Computes a 2-sample t statistic, under the hypothesis of equal * subpopulation variances. To compute a t-statistic without the * equal variances hypothesis, use {@link #t(double[], double[])}. *

                    * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

                    *

                    * The t-statisitc is

                    *

                    *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

                    * where n1 is the size of first sample; * n2 is the size of second sample; * m1 is the mean of first sample; * m2 is the mean of second sample * * and var is the pooled variance estimate: *

                    * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) *

                    * with var1 the variance of the first sample and * var2 the variance of the second sample. *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ public double homoscedasticT(double[] sample1, double[] sample2) throws IllegalArgumentException { checkSampleData(sample1); checkSampleData(sample2); return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2), StatUtils.variance(sample1), StatUtils.variance(sample2), sample1.length, sample2.length); } /** * Computes a 2-sample t statistic, without the hypothesis of equal * subpopulation variances. To compute a t-statistic assuming equal * variances, use {@link #homoscedasticT(double[], double[])}. *

                    * This statistic can be used to perform a two-sample t-test to compare * sample means.

                    *

                    * The t-statisitc is

                    *

                    *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

                    * where n1 is the size of the first sample * n2 is the size of the second sample; * m1 is the mean of the first sample; * m2 is the mean of the second sample; * var1 is the variance of the first sample; * var2 is the variance of the second sample; *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ public double t(double[] sample1, double[] sample2) throws IllegalArgumentException { checkSampleData(sample1); checkSampleData(sample2); return t(StatUtils.mean(sample1), StatUtils.mean(sample2), StatUtils.variance(sample1), StatUtils.variance(sample2), sample1.length, sample2.length); } /** * Computes a 2-sample t statistic , comparing the means of the datasets * described by two {@link StatisticalSummary} instances, without the * assumption of equal subpopulation variances. Use * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to * compute a t-statistic under the equal variances assumption. *

                    * This statistic can be used to perform a two-sample t-test to compare * sample means.

                    *

                    * The returned t-statisitc is

                    *

                    *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

                    * where n1 is the size of the first sample; * n2 is the size of the second sample; * m1 is the mean of the first sample; * m2 is the mean of the second sample * var1 is the variance of the first sample; * var2 is the variance of the second sample *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ public double t(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException { checkSampleData(sampleStats1); checkSampleData(sampleStats2); return t(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), sampleStats2.getVariance(), sampleStats1.getN(), sampleStats2.getN()); } /** * Computes a 2-sample t statistic, comparing the means of the datasets * described by two {@link StatisticalSummary} instances, under the * assumption of equal subpopulation variances. To compute a t-statistic * without the equal variances assumption, use * {@link #t(StatisticalSummary, StatisticalSummary)}. *

                    * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

                    *

                    * The t-statisitc returned is

                    *

                    *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

                    * where n1 is the size of first sample; * n2 is the size of second sample; * m1 is the mean of first sample; * m2 is the mean of second sample * and var is the pooled variance estimate: *

                    * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) *

                    * with var1 the variance of the first sample and * var2 the variance of the second sample. *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic * @throws IllegalArgumentException if the precondition is not met */ public double homoscedasticT(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException { checkSampleData(sampleStats1); checkSampleData(sampleStats2); return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), sampleStats2.getVariance(), sampleStats1.getN(), sampleStats2.getN()); } /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test * comparing the mean of the input array with the constant mu. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean equals * mu in favor of the two-sided alternative that the mean * is different from mu. For a one-sided test, divide the * returned value by 2.

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu constant value to compare sample mean against * @param sample array of sample data values * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double tTest(double mu, double[] sample) throws IllegalArgumentException, MathException { checkSampleData(sample); return tTest( StatUtils.mean(sample), mu, StatUtils.variance(sample), sample.length); } /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the population from * which sample is drawn equals mu. *

                    * Returns true iff the null hypothesis can be * rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2 *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis sample mean = mu at * the 95% level, use
                      tTest(mu, sample, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis sample mean < mu * at the 99% level, first verify that the measured sample mean is less * than mu and then use *
                      tTest(mu, sample, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the one-sample * parametric t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The observed array length must be at least 2. *

                    * * @param mu constant value to compare sample mean against * @param sample array of sample data values * @param alpha significance level of the test * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error computing the p-value */ public boolean tTest(double mu, double[] sample, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return tTest(mu, sample) < alpha; } /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test * comparing the mean of the dataset described by sampleStats * with the constant mu. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the mean equals * mu in favor of the two-sided alternative that the mean * is different from mu. For a one-sided test, divide the * returned value by 2.

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The sample must contain at least 2 observations. *

                    * * @param mu constant value to compare sample mean against * @param sampleStats StatisticalSummary describing sample data * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double tTest(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException, MathException { checkSampleData(sampleStats); return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(), sampleStats.getN()); } /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the * population from which the dataset described by stats is * drawn equals mu. *

                    * Returns true iff the null hypothesis can be rejected with * confidence 1 - alpha. To perform a 1-sided test, use * alpha * 2.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis sample mean = mu at * the 95% level, use
                      tTest(mu, sampleStats, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis sample mean < mu * at the 99% level, first verify that the measured sample mean is less * than mu and then use *
                      tTest(mu, sampleStats, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the one-sample * parametric t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The sample must include at least 2 observations. *

                    * * @param mu constant value to compare sample mean against * @param sampleStats StatisticalSummary describing sample data values * @param alpha significance level of the test * @return p-value * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public boolean tTest( double mu, StatisticalSummary sampleStats, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return tTest(mu, sampleStats) < alpha; } /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the input arrays. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * The test does not assume that the underlying popuation variances are * equal and it uses approximated degrees of freedom computed from the * sample data to compute the p-value. The t-statistic used is as defined in * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation * to the degrees of freedom is used, * as described * * here. To perform the test under the assumption of equal subpopulation * variances, use {@link #homoscedasticTTest(double[], double[])}.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double tTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { checkSampleData(sample1); checkSampleData(sample2); return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2), StatUtils.variance(sample1), StatUtils.variance(sample2), sample1.length, sample2.length); } /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the input arrays, under the assumption that * the two samples are drawn from subpopulations with equal variances. * To perform the test without the equal variances assumption, use * {@link #tTest(double[], double[])}. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * A pooled variance estimate is used to compute the t-statistic. See * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes * minus 2 is used as the degrees of freedom.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double homoscedasticTTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { checkSampleData(sample1); checkSampleData(sample2); return homoscedasticTTest(StatUtils.mean(sample1), StatUtils.mean(sample2), StatUtils.variance(sample1), StatUtils.variance(sample2), sample1.length, sample2.length); } /** * Performs a * * two-sided t-test evaluating the null hypothesis that sample1 * and sample2 are drawn from populations with the same mean, * with significance level alpha. This test does not assume * that the subpopulation variances are equal. To perform the test assuming * equal variances, use * {@link #homoscedasticTTest(double[], double[], double)}. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha / 2

                    *

                    * See {@link #t(double[], double[])} for the formula used to compute the * t-statistic. Degrees of freedom are approximated using the * * Welch-Satterthwaite approximation.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95% level, use *
                      tTest(sample1, sample2, 0.05). *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2 at * the 99% level, first verify that the measured mean of sample 1 * is less than the mean of sample 2 and then use *
                      tTest(sample1, sample2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean tTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return tTest(sample1, sample2) < alpha; } /** * Performs a * * two-sided t-test evaluating the null hypothesis that sample1 * and sample2 are drawn from populations with the same mean, * with significance level alpha, assuming that the * subpopulation variances are equal. Use * {@link #tTest(double[], double[], double)} to perform the test without * the assumption of equal variances. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2. To perform the test * without the assumption of equal subpopulation variances, use * {@link #tTest(double[], double[], double)}.

                    *

                    * A pooled variance estimate is used to compute the t-statistic. See * {@link #t(double[], double[])} for the formula. The sum of the sample * sizes minus 2 is used as the degrees of freedom.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95% level, use
                      tTest(sample1, sample2, 0.05). *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2, * at the 99% level, first verify that the measured mean of * sample 1 is less than the mean of sample 2 * and then use *
                      tTest(sample1, sample2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The observed array lengths must both be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sample1 array of sample data values * @param sample2 array of sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean homoscedasticTTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return homoscedasticTTest(sample1, sample2) < alpha; } /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the datasets described by two StatisticalSummary * instances. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * The test does not assume that the underlying popuation variances are * equal and it uses approximated degrees of freedom computed from the * sample data to compute the p-value. To perform the test assuming * equal variances, use * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException { checkSampleData(sampleStats1); checkSampleData(sampleStats2); return tTest(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), sampleStats2.getVariance(), sampleStats1.getN(), sampleStats2.getN()); } /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test * comparing the means of the datasets described by two StatisticalSummary * instances, under the hypothesis of equal subpopulation variances. To * perform a test without the equal variances assumption, use * {@link #tTest(StatisticalSummary, StatisticalSummary)}. *

                    * The number returned is the smallest significance level * at which one can reject the null hypothesis that the two means are * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

                    *

                    * See {@link #homoscedasticT(double[], double[])} for the formula used to * compute the t-statistic. The sum of the sample sizes minus 2 is used as * the degrees of freedom.

                    *

                    * Usage Note:
                    * The validity of the p-value depends on the assumptions of the parametric * t-test procedure, as discussed * here *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *

                    * * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test * @throws IllegalArgumentException if the precondition is not met * @throws MathException if an error occurs computing the p-value */ public double homoscedasticTTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException { checkSampleData(sampleStats1); checkSampleData(sampleStats2); return homoscedasticTTest(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), sampleStats2.getVariance(), sampleStats1.getN(), sampleStats2.getN()); } /** * Performs a * * two-sided t-test evaluating the null hypothesis that * sampleStats1 and sampleStats2 describe * datasets drawn from populations with the same mean, with significance * level alpha. This test does not assume that the * subpopulation variances are equal. To perform the test under the equal * variances assumption, use * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}. *

                    * Returns true iff the null hypothesis that the means are * equal can be rejected with confidence 1 - alpha. To * perform a 1-sided test, use alpha * 2

                    *

                    * See {@link #t(double[], double[])} for the formula used to compute the * t-statistic. Degrees of freedom are approximated using the * * Welch-Satterthwaite approximation.

                    *

                    * Examples:

                      *
                    1. To test the (2-sided) hypothesis mean 1 = mean 2 at * the 95%, use *
                      tTest(sampleStats1, sampleStats2, 0.05) *
                    2. *
                    3. To test the (one-sided) hypothesis mean 1 < mean 2 * at the 99% level, first verify that the measured mean of * sample 1 is less than the mean of sample 2 * and then use *
                      tTest(sampleStats1, sampleStats2, 0.02) *

                    *

                    * Usage Note:
                    * The validity of the test depends on the assumptions of the parametric * t-test procedure, as discussed * * here

                    *

                    * Preconditions:

                      *
                    • The datasets described by the two Univariates must each contain * at least 2 observations. *
                    • *
                    • 0 < alpha < 0.5 *

                    * * @param sampleStats1 StatisticalSummary describing sample data values * @param sampleStats2 StatisticalSummary describing sample data values * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha * @throws IllegalArgumentException if the preconditions are not met * @throws MathException if an error occurs performing the test */ public boolean tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2, double alpha) throws IllegalArgumentException, MathException { checkSignificanceLevel(alpha); return tTest(sampleStats1, sampleStats2) < alpha; } //----------------------------------------------- Protected methods /** * Computes approximate degrees of freedom for 2-sample t-test. * * @param v1 first sample variance * @param v2 second sample variance * @param n1 first sample n * @param n2 second sample n * @return approximate degrees of freedom */ protected double df(double v1, double v2, double n1, double n2) { return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) / ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) / (n2 * n2 * (n2 - 1d))); } /** * Computes t test statistic for 1-sample t-test. * * @param m sample mean * @param mu constant to test against * @param v sample variance * @param n sample n * @return t test statistic */ protected double t(double m, double mu, double v, double n) { return (m - mu) / FastMath.sqrt(v / n); } /** * Computes t test statistic for 2-sample t-test. *

                    * Does not assume that subpopulation variances are equal.

                    * * @param m1 first sample mean * @param m2 second sample mean * @param v1 first sample variance * @param v2 second sample variance * @param n1 first sample n * @param n2 second sample n * @return t test statistic */ protected double t(double m1, double m2, double v1, double v2, double n1, double n2) { return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2)); } /** * Computes t test statistic for 2-sample t-test under the hypothesis * of equal subpopulation variances. * * @param m1 first sample mean * @param m2 second sample mean * @param v1 first sample variance * @param v2 second sample variance * @param n1 first sample n * @param n2 second sample n * @return t test statistic */ protected double homoscedasticT(double m1, double m2, double v1, double v2, double n1, double n2) { double pooledVariance = ((n1 - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2); return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2)); } /** * Computes p-value for 2-sided, 1-sample t-test. * * @param m sample mean * @param mu constant to test against * @param v sample variance * @param n sample n * @return p-value * @throws MathException if an error occurs computing the p-value */ protected double tTest(double m, double mu, double v, double n) throws MathException { double t = FastMath.abs(t(m, mu, v, n)); distribution.setDegreesOfFreedom(n - 1); return 2.0 * distribution.cumulativeProbability(-t); } /** * Computes p-value for 2-sided, 2-sample t-test. *

                    * Does not assume subpopulation variances are equal. Degrees of freedom * are estimated from the data.

                    * * @param m1 first sample mean * @param m2 second sample mean * @param v1 first sample variance * @param v2 second sample variance * @param n1 first sample n * @param n2 second sample n * @return p-value * @throws MathException if an error occurs computing the p-value */ protected double tTest(double m1, double m2, double v1, double v2, double n1, double n2) throws MathException { double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2)); double degreesOfFreedom = 0; degreesOfFreedom = df(v1, v2, n1, n2); distribution.setDegreesOfFreedom(degreesOfFreedom); return 2.0 * distribution.cumulativeProbability(-t); } /** * Computes p-value for 2-sided, 2-sample t-test, under the assumption * of equal subpopulation variances. *

                    * The sum of the sample sizes minus 2 is used as degrees of freedom.

                    * * @param m1 first sample mean * @param m2 second sample mean * @param v1 first sample variance * @param v2 second sample variance * @param n1 first sample n * @param n2 second sample n * @return p-value * @throws MathException if an error occurs computing the p-value */ protected double homoscedasticTTest(double m1, double m2, double v1, double v2, double n1, double n2) throws MathException { double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2)); double degreesOfFreedom = n1 + n2 - 2; distribution.setDegreesOfFreedom(degreesOfFreedom); return 2.0 * distribution.cumulativeProbability(-t); } /** * Modify the distribution used to compute inference statistics. * @param value the new distribution * @since 1.2 * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public void setDistribution(TDistribution value) { distribution = value; } /** Check significance level. * @param alpha significance level * @exception IllegalArgumentException if significance level is out of bounds */ private void checkSignificanceLevel(final double alpha) throws IllegalArgumentException { if ((alpha <= 0) || (alpha > 0.5)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0.0, 0.5); } } /** Check sample data. * @param data sample data * @exception IllegalArgumentException if there is not enough sample data */ private void checkSampleData(final double[] data) throws IllegalArgumentException { if ((data == null) || (data.length < 2)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, (data == null) ? 0 : data.length); } } /** Check sample data. * @param stat statistical summary * @exception IllegalArgumentException if there is not enough sample data */ private void checkSampleData(final StatisticalSummary stat) throws IllegalArgumentException { if ((stat == null) || (stat.getN() < 2)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, (stat == null) ? 0 : stat.getN()); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/package.html100644 1750 1750 1762 11532241247 27546 0ustarlucluc 0 0 Classes providing hypothesis testing and confidence interval construction. commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java100644 1750 1750 37052 11532241247 30111 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import java.util.Collection; import org.apache.commons.math.MathException; import org.apache.commons.math.stat.descriptive.StatisticalSummary; /** * A collection of static methods to create inference test instances or to * perform inference tests. * *

                    * The set methods are not compatible with using the class in multiple threads, * and have therefore been deprecated (along with the getters). * The setters and getters will be removed in version 3.0. * * @since 1.1 * @version $Revision: 1067582 $ $Date: 2011-02-06 04:55:32 +0100 (dim. 06 févr. 2011) $ */ public class TestUtils { /** Singleton TTest instance using default implementation. */ private static TTest tTest = new TTestImpl(); /** Singleton ChiSquareTest instance using default implementation. */ private static ChiSquareTest chiSquareTest = new ChiSquareTestImpl(); /** Singleton ChiSquareTest instance using default implementation. */ private static UnknownDistributionChiSquareTest unknownDistributionChiSquareTest = new ChiSquareTestImpl(); /** Singleton OneWayAnova instance using default implementation. */ private static OneWayAnova oneWayAnova = new OneWayAnovaImpl(); /** * Prevent instantiation. */ protected TestUtils() { super(); } /** * Set the (singleton) TTest instance. * * @param chiSquareTest the new instance to use * @since 1.2 * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads */ @Deprecated public static void setChiSquareTest(TTest chiSquareTest) { TestUtils.tTest = chiSquareTest; } /** * Return a (singleton) TTest instance. Does not create a new instance. * * @return a TTest instance * @deprecated 2.2 will be removed in 3.0 */ @Deprecated public static TTest getTTest() { return tTest; } /** * Set the (singleton) ChiSquareTest instance. * * @param chiSquareTest the new instance to use * @since 1.2 * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads */ @Deprecated public static void setChiSquareTest(ChiSquareTest chiSquareTest) { TestUtils.chiSquareTest = chiSquareTest; } /** * Return a (singleton) ChiSquareTest instance. Does not create a new instance. * * @return a ChiSquareTest instance * @deprecated 2.2 will be removed in 3.0 */ @Deprecated public static ChiSquareTest getChiSquareTest() { return chiSquareTest; } /** * Set the (singleton) UnknownDistributionChiSquareTest instance. * * @param unknownDistributionChiSquareTest the new instance to use * @since 1.2 * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads */ @Deprecated public static void setUnknownDistributionChiSquareTest(UnknownDistributionChiSquareTest unknownDistributionChiSquareTest) { TestUtils.unknownDistributionChiSquareTest = unknownDistributionChiSquareTest; } /** * Return a (singleton) UnknownDistributionChiSquareTest instance. Does not create a new instance. * * @return a UnknownDistributionChiSquareTest instance * @deprecated 2.2 will be removed in 3.0 */ @Deprecated public static UnknownDistributionChiSquareTest getUnknownDistributionChiSquareTest() { return unknownDistributionChiSquareTest; } /** * Set the (singleton) OneWayAnova instance * * @param oneWayAnova the new instance to use * @since 1.2 * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads */ @Deprecated public static void setOneWayAnova(OneWayAnova oneWayAnova) { TestUtils.oneWayAnova = oneWayAnova; } /** * Return a (singleton) OneWayAnova instance. Does not create a new instance. * * @return a OneWayAnova instance * @since 1.2 * @deprecated 2.2 will be removed in 3.0 */ @Deprecated public static OneWayAnova getOneWayAnova() { return oneWayAnova; } // CHECKSTYLE: stop JavadocMethodCheck /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(double[], double[]) */ public static double homoscedasticT(double[] sample1, double[] sample2) throws IllegalArgumentException { return tTest.homoscedasticT(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double homoscedasticT(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException { return tTest.homoscedasticT(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[], double) */ public static boolean homoscedasticTTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { return tTest. homoscedasticTTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[]) */ public static double homoscedasticTTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { return tTest.homoscedasticTTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double homoscedasticTTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException { return tTest.homoscedasticTTest(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedT(double[], double[]) */ public static double pairedT(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { return tTest.pairedT(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[], double) */ public static boolean pairedTTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { return tTest.pairedTTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[]) */ public static double pairedTTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { return tTest.pairedTTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double, double[]) */ public static double t(double mu, double[] observed) throws IllegalArgumentException { return tTest.t(mu, observed); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double t(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException { return tTest.t(mu, sampleStats); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double[], double[]) */ public static double t(double[] sample1, double[] sample2) throws IllegalArgumentException { return tTest.t(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#t(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double t(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException { return tTest.t(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[], double) */ public static boolean tTest(double mu, double[] sample, double alpha) throws IllegalArgumentException, MathException { return tTest.tTest(mu, sample, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[]) */ public static double tTest(double mu, double[] sample) throws IllegalArgumentException, MathException { return tTest.tTest(mu, sample); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) */ public static boolean tTest(double mu, StatisticalSummary sampleStats, double alpha) throws IllegalArgumentException, MathException { return tTest. tTest(mu, sampleStats, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double tTest(double mu, StatisticalSummary sampleStats) throws IllegalArgumentException, MathException { return tTest.tTest(mu, sampleStats); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[], double) */ public static boolean tTest(double[] sample1, double[] sample2, double alpha) throws IllegalArgumentException, MathException { return tTest.tTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[]) */ public static double tTest(double[] sample1, double[] sample2) throws IllegalArgumentException, MathException { return tTest.tTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) */ public static boolean tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2, double alpha) throws IllegalArgumentException, MathException { return tTest. tTest(sampleStats1, sampleStats2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ public static double tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) throws IllegalArgumentException, MathException { return tTest.tTest(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(double[], long[]) */ public static double chiSquare(double[] expected, long[] observed) throws IllegalArgumentException { return chiSquareTest.chiSquare(expected, observed); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(long[][]) */ public static double chiSquare(long[][] counts) throws IllegalArgumentException { return chiSquareTest.chiSquare(counts); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[], double) */ public static boolean chiSquareTest(double[] expected, long[] observed, double alpha) throws IllegalArgumentException, MathException { return chiSquareTest.chiSquareTest(expected, observed, alpha); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[]) */ public static double chiSquareTest(double[] expected, long[] observed) throws IllegalArgumentException, MathException { return chiSquareTest.chiSquareTest(expected, observed); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][], double) */ public static boolean chiSquareTest(long[][] counts, double alpha) throws IllegalArgumentException, MathException { return chiSquareTest. chiSquareTest(counts, alpha); } /** * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][]) */ public static double chiSquareTest(long[][] counts) throws IllegalArgumentException, MathException { return chiSquareTest. chiSquareTest(counts); } /** * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareDataSetsComparison(long[], long[]) * * @since 1.2 */ public static double chiSquareDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException { return unknownDistributionChiSquareTest.chiSquareDataSetsComparison(observed1, observed2); } /** * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[]) * * @since 1.2 */ public static double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException, MathException { return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2); } /** * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[], double) * * @since 1.2 */ public static boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, double alpha) throws IllegalArgumentException, MathException { return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2, alpha); } /** * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaFValue(Collection) * * @since 1.2 */ public static double oneWayAnovaFValue(Collection categoryData) throws IllegalArgumentException, MathException { return oneWayAnova.anovaFValue(categoryData); } /** * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaPValue(Collection) * * @since 1.2 */ public static double oneWayAnovaPValue(Collection categoryData) throws IllegalArgumentException, MathException { return oneWayAnova.anovaPValue(categoryData); } /** * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaTest(Collection,double) * * @since 1.2 */ public static boolean oneWayAnovaTest(Collection categoryData, double alpha) throws IllegalArgumentException, MathException { return oneWayAnova.anovaTest(categoryData, alpha); } // CHECKSTYLE: resume JavadocMethodCheck } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/UnknownDistributionChiSqua100644 1750 1750 15241 11532241247 32542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import org.apache.commons.math.MathException; /** * An interface for Chi-Square tests for unknown distributions. *

                    Two samples tests are used when the distribution is unknown a priori * but provided by one sample. We compare the second sample against the first.

                    * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 1.2 */ public interface UnknownDistributionChiSquareTest extends ChiSquareTest { /** *

                    Computes a * * Chi-Square two sample test statistic comparing bin frequency counts * in observed1 and observed2. The * sums of frequency counts in the two samples are not required to be the * same. The formula used to compute the test statistic is

                    * * ∑[(K * observed1[i] - observed2[i]/K)2 / (observed1[i] + observed2[i])] * where *
                    K = &sqrt;[&sum(observed2 / ∑(observed1)] *

                    *

                    This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that * both observed counts follow the same distribution.

                    *

                    * Preconditions:

                      *
                    • Observed counts must be non-negative. *
                    • *
                    • Observed counts for a specific bin must not both be zero. *
                    • *
                    • Observed counts for a specific sample must not all be 0. *
                    • *
                    • The arrays observed1 and observed2 must have the same length and * their common length must be at least 2. *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @return chiSquare statistic * @throws IllegalArgumentException if preconditions are not met */ double chiSquareDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException; /** *

                    Returns the observed significance level, or * p-value, associated with a Chi-Square two sample test comparing * bin frequency counts in observed1 and * observed2. *

                    *

                    The number returned is the smallest significance level at which one * can reject the null hypothesis that the observed counts conform to the * same distribution. *

                    *

                    See {@link #chiSquareDataSetsComparison(long[], long[])} for details * on the formula used to compute the test statistic. The degrees of * of freedom used to perform the test is one less than the common length * of the input observed count arrays. *

                    * Preconditions:
                      *
                    • Observed counts must be non-negative. *
                    • *
                    • Observed counts for a specific bin must not both be zero. *
                    • *
                    • Observed counts for a specific sample must not all be 0. *
                    • *
                    • The arrays observed1 and observed2 must * have the same length and * their common length must be at least 2. *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @return p-value * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs computing the p-value */ double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) throws IllegalArgumentException, MathException; /** *

                    Performs a Chi-Square two sample test comparing two binned data * sets. The test evaluates the null hypothesis that the two lists of * observed counts conform to the same frequency distribution, with * significance level alpha. Returns true iff the null * hypothesis can be rejected with 100 * (1 - alpha) percent confidence. *

                    *

                    See {@link #chiSquareDataSetsComparison(long[], long[])} for * details on the formula used to compute the Chisquare statistic used * in the test. The degrees of of freedom used to perform the test is * one less than the common length of the input observed count arrays. *

                    * Preconditions:
                      *
                    • Observed counts must be non-negative. *
                    • *
                    • Observed counts for a specific bin must not both be zero. *
                    • *
                    • Observed counts for a specific sample must not all be 0. *
                    • *
                    • The arrays observed1 and observed2 must * have the same length and their common length must be at least 2. *
                    • *
                    • 0 < alpha < 0.5 *

                    * If any of the preconditions are not met, an * IllegalArgumentException is thrown.

                    * * @param observed1 array of observed frequency counts of the first data set * @param observed2 array of observed frequency counts of the second data set * @param alpha significance level of the test * @return true iff null hypothesis can be rejected with confidence * 1 - alpha * @throws IllegalArgumentException if preconditions are not met * @throws MathException if an error occurs performing the test */ boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, double alpha) throws IllegalArgumentException, MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/stat/inference/OneWayAnovaImpl.java100644 1750 1750 16537 11532241247 31167 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.stat.inference; import java.util.Collection; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.distribution.FDistribution; import org.apache.commons.math.distribution.FDistributionImpl; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.stat.descriptive.summary.Sum; import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; /** * Implements one-way ANOVA statistics defined in the {@link OneWayAnovaImpl} * interface. * *

                    Uses the * {@link org.apache.commons.math.distribution.FDistribution * commons-math F Distribution implementation} to estimate exact p-values.

                    * *

                    This implementation is based on a description at * http://faculty.vassar.edu/lowry/ch13pt1.html

                    *
                     * Abbreviations: bg = between groups,
                     *                wg = within groups,
                     *                ss = sum squared deviations
                     * 
                    * * @since 1.2 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class OneWayAnovaImpl implements OneWayAnova { /** * Default constructor. */ public OneWayAnovaImpl() { } /** * {@inheritDoc}

                    * This implementation computes the F statistic using the definitional * formula

                         *   F = msbg/mswg
                    * where
                         *  msbg = between group mean square
                         *  mswg = within group mean square
                    * are as defined * here

                    */ public double anovaFValue(Collection categoryData) throws IllegalArgumentException, MathException { AnovaStats a = anovaStats(categoryData); return a.F; } /** * {@inheritDoc}

                    * This implementation uses the * {@link org.apache.commons.math.distribution.FDistribution * commons-math F Distribution implementation} to estimate the exact * p-value, using the formula

                         *   p = 1 - cumulativeProbability(F)
                    * where F is the F value and cumulativeProbability * is the commons-math implementation of the F distribution.

                    */ public double anovaPValue(Collection categoryData) throws IllegalArgumentException, MathException { AnovaStats a = anovaStats(categoryData); FDistribution fdist = new FDistributionImpl(a.dfbg, a.dfwg); return 1.0 - fdist.cumulativeProbability(a.F); } /** * {@inheritDoc}

                    * This implementation uses the * {@link org.apache.commons.math.distribution.FDistribution * commons-math F Distribution implementation} to estimate the exact * p-value, using the formula

                         *   p = 1 - cumulativeProbability(F)
                    * where F is the F value and cumulativeProbability * is the commons-math implementation of the F distribution.

                    *

                    True is returned iff the estimated p-value is less than alpha.

                    */ public boolean anovaTest(Collection categoryData, double alpha) throws IllegalArgumentException, MathException { if ((alpha <= 0) || (alpha > 0.5)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL, alpha, 0, 0.5); } return anovaPValue(categoryData) < alpha; } /** * This method actually does the calculations (except P-value). * * @param categoryData Collection of double[] * arrays each containing data for one category * @return computed AnovaStats * @throws IllegalArgumentException if categoryData does not meet * preconditions specified in the interface definition * @throws MathException if an error occurs computing the Anova stats */ private AnovaStats anovaStats(Collection categoryData) throws IllegalArgumentException, MathException { // check if we have enough categories if (categoryData.size() < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.TWO_OR_MORE_CATEGORIES_REQUIRED, categoryData.size()); } // check if each category has enough data and all is double[] for (double[] array : categoryData) { if (array.length <= 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED, array.length); } } int dfwg = 0; double sswg = 0; Sum totsum = new Sum(); SumOfSquares totsumsq = new SumOfSquares(); int totnum = 0; for (double[] data : categoryData) { Sum sum = new Sum(); SumOfSquares sumsq = new SumOfSquares(); int num = 0; for (int i = 0; i < data.length; i++) { double val = data[i]; // within category num++; sum.increment(val); sumsq.increment(val); // for all categories totnum++; totsum.increment(val); totsumsq.increment(val); } dfwg += num - 1; double ss = sumsq.getResult() - sum.getResult() * sum.getResult() / num; sswg += ss; } double sst = totsumsq.getResult() - totsum.getResult() * totsum.getResult()/totnum; double ssbg = sst - sswg; int dfbg = categoryData.size() - 1; double msbg = ssbg/dfbg; double mswg = sswg/dfwg; double F = msbg/mswg; return new AnovaStats(dfbg, dfwg, F); } /** Convenience class to pass dfbg,dfwg,F values around within AnovaImpl. No get/set methods provided. */ private static class AnovaStats { /** Degrees of freedom in numerator (between groups). */ private int dfbg; /** Degrees of freedom in denominator (within groups). */ private int dfwg; /** Statistic. */ private double F; /** * Constructor * @param dfbg degrees of freedom in numerator (between groups) * @param dfwg degrees of freedom in denominator (within groups) * @param F statistic */ private AnovaStats(int dfbg, int dfwg, double F) { this.dfbg = dfbg; this.dfwg = dfwg; this.F = F; } } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/NotARotationMatrixException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/NotARotationMatrixException.java100644 1750 1750 4173 11532241244 32473 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.Localizable; /** * This class represents exceptions thrown while building rotations * from matrices. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 1.2 */ public class NotARotationMatrixException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = 5647178478658937642L; /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @deprecated as of 2.2 replaced by {@link #NotARotationMatrixException(Localizable, Object...)} */ @Deprecated public NotARotationMatrixException(String specifier, Object ... parts) { super(specifier, parts); } /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public NotARotationMatrixException(Localizable specifier, Object ... parts) { super(specifier, parts); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/Vector3DFormat.java100644 1750 1750 27141 11532241244 27670 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.CompositeFormat; /** * Formats a 3D vector in components list format "{x; y; z}". *

                    The prefix and suffix "{" and "}" and the separator "; " can be replaced by * any user-defined strings. The number format for components can be configured.

                    *

                    White space is ignored at parse time, even if it is in the prefix, suffix * or separator specifications. So even if the default separator does include a space * character that is used at format time, both input string "{1;1;1}" and * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be * returned. In the second case, however, the parse position after parsing will be * just after the closing curly brace, i.e. just before the trailing space.

                    * * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ */ public class Vector3DFormat extends CompositeFormat { /** Serializable version identifier */ private static final long serialVersionUID = -5447606608652576301L; /** The default prefix: "{". */ private static final String DEFAULT_PREFIX = "{"; /** The default suffix: "}". */ private static final String DEFAULT_SUFFIX = "}"; /** The default separator: ", ". */ private static final String DEFAULT_SEPARATOR = "; "; /** Prefix. */ private final String prefix; /** Suffix. */ private final String suffix; /** Separator. */ private final String separator; /** Trimmed prefix. */ private final String trimmedPrefix; /** Trimmed suffix. */ private final String trimmedSuffix; /** Trimmed separator. */ private final String trimmedSeparator; /** The format used for components. */ private final NumberFormat format; /** * Create an instance with default settings. *

                    The instance uses the default prefix, suffix and separator: * "{", "}", and "; " and the default number format for components.

                    */ public Vector3DFormat() { this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, getDefaultNumberFormat()); } /** * Create an instance with a custom number format for components. * @param format the custom format for components. */ public Vector3DFormat(final NumberFormat format) { this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format); } /** * Create an instance with custom prefix, suffix and separator. * @param prefix prefix to use instead of the default "{" * @param suffix suffix to use instead of the default "}" * @param separator separator to use instead of the default "; " */ public Vector3DFormat(final String prefix, final String suffix, final String separator) { this(prefix, suffix, separator, getDefaultNumberFormat()); } /** * Create an instance with custom prefix, suffix, separator and format * for components. * @param prefix prefix to use instead of the default "{" * @param suffix suffix to use instead of the default "}" * @param separator separator to use instead of the default "; " * @param format the custom format for components. */ public Vector3DFormat(final String prefix, final String suffix, final String separator, final NumberFormat format) { this.prefix = prefix; this.suffix = suffix; this.separator = separator; trimmedPrefix = prefix.trim(); trimmedSuffix = suffix.trim(); trimmedSeparator = separator.trim(); this.format = format; } /** * Get the set of locales for which 3D vectors formats are available. *

                    This is the same set as the {@link NumberFormat} set.

                    * @return available 3D vector format locales. */ public static Locale[] getAvailableLocales() { return NumberFormat.getAvailableLocales(); } /** * Get the format prefix. * @return format prefix. */ public String getPrefix() { return prefix; } /** * Get the format suffix. * @return format suffix. */ public String getSuffix() { return suffix; } /** * Get the format separator between components. * @return format separator. */ public String getSeparator() { return separator; } /** * Get the components format. * @return components format. */ public NumberFormat getFormat() { return format; } /** * Returns the default 3D vector format for the current locale. * @return the default 3D vector format. */ public static Vector3DFormat getInstance() { return getInstance(Locale.getDefault()); } /** * Returns the default 3D vector format for the given locale. * @param locale the specific locale used by the format. * @return the 3D vector format specific to the given locale. */ public static Vector3DFormat getInstance(final Locale locale) { return new Vector3DFormat(getDefaultNumberFormat(locale)); } /** * This static method calls {@link #format(Object)} on a default instance of * Vector3DFormat. * * @param v Vector3D object to format * @return A formatted vector */ public static String formatVector3D(Vector3D v) { return getInstance().format(v); } /** * Formats a {@link Vector3D} object to produce a string. * @param vector the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ public StringBuffer format(Vector3D vector, StringBuffer toAppendTo, FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); // format prefix toAppendTo.append(prefix); // format components formatDouble(vector.getX(), format, toAppendTo, pos); toAppendTo.append(separator); formatDouble(vector.getY(), format, toAppendTo, pos); toAppendTo.append(separator); formatDouble(vector.getZ(), format, toAppendTo, pos); // format suffix toAppendTo.append(suffix); return toAppendTo; } /** * Formats a object to produce a string. *

                    obj must be a {@link Vector3D} object. Any other type of * object will result in an {@link IllegalArgumentException} being thrown.

                    * @param obj the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) * @throws IllegalArgumentException is obj is not a valid type. */ @Override public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { if (obj instanceof Vector3D) { return format( (Vector3D)obj, toAppendTo, pos); } throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR, obj.getClass().getName()); } /** * Parses a string to produce a {@link Vector3D} object. * @param source the string to parse * @return the parsed {@link Vector3D} object. * @exception ParseException if the beginning of the specified string * cannot be parsed. */ public Vector3D parse(String source) throws ParseException { ParsePosition parsePosition = new ParsePosition(0); Vector3D result = parse(source, parsePosition); if (parsePosition.getIndex() == 0) { throw MathRuntimeException.createParseException( parsePosition.getErrorIndex(), LocalizedFormats.UNPARSEABLE_3D_VECTOR, source); } return result; } /** * Parses a string to produce a {@link Vector3D} object. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link Vector3D} object. */ public Vector3D parse(String source, ParsePosition pos) { int initialIndex = pos.getIndex(); // parse prefix parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedPrefix, pos)) { return null; } // parse X component parseAndIgnoreWhitespace(source, pos); Number x = parseNumber(source, format, pos); if (x == null) { // invalid abscissa // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } // parse Y component parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedSeparator, pos)) { return null; } parseAndIgnoreWhitespace(source, pos); Number y = parseNumber(source, format, pos); if (y == null) { // invalid ordinate // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } // parse Z component parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedSeparator, pos)) { return null; } parseAndIgnoreWhitespace(source, pos); Number z = parseNumber(source, format, pos); if (z == null) { // invalid height // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } // parse suffix parseAndIgnoreWhitespace(source, pos); if (!parseFixedstring(source, trimmedSuffix, pos)) { return null; } return new Vector3D(x.doubleValue(), y.doubleValue(), z.doubleValue()); } /** * Parses a string to produce a object. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed object. * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) */ @Override public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/RotationOrder.java100644 1750 1750 13434 11532241244 27661 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; /** * This class is a utility representing a rotation order specification * for Cardan or Euler angles specification. * * This class cannot be instanciated by the user. He can only use one * of the twelve predefined supported orders as an argument to either * the {@link Rotation#Rotation(RotationOrder,double,double,double)} * constructor or the {@link Rotation#getAngles} method. * * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 */ public final class RotationOrder { /** Set of Cardan angles. * this ordered set of rotations is around X, then around Y, then * around Z */ public static final RotationOrder XYZ = new RotationOrder("XYZ", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_K); /** Set of Cardan angles. * this ordered set of rotations is around X, then around Z, then * around Y */ public static final RotationOrder XZY = new RotationOrder("XZY", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_J); /** Set of Cardan angles. * this ordered set of rotations is around Y, then around X, then * around Z */ public static final RotationOrder YXZ = new RotationOrder("YXZ", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K); /** Set of Cardan angles. * this ordered set of rotations is around Y, then around Z, then * around X */ public static final RotationOrder YZX = new RotationOrder("YZX", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I); /** Set of Cardan angles. * this ordered set of rotations is around Z, then around X, then * around Y */ public static final RotationOrder ZXY = new RotationOrder("ZXY", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J); /** Set of Cardan angles. * this ordered set of rotations is around Z, then around Y, then * around X */ public static final RotationOrder ZYX = new RotationOrder("ZYX", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_I); /** Set of Euler angles. * this ordered set of rotations is around X, then around Y, then * around X */ public static final RotationOrder XYX = new RotationOrder("XYX", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_I); /** Set of Euler angles. * this ordered set of rotations is around X, then around Z, then * around X */ public static final RotationOrder XZX = new RotationOrder("XZX", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_I); /** Set of Euler angles. * this ordered set of rotations is around Y, then around X, then * around Y */ public static final RotationOrder YXY = new RotationOrder("YXY", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_J); /** Set of Euler angles. * this ordered set of rotations is around Y, then around Z, then * around Y */ public static final RotationOrder YZY = new RotationOrder("YZY", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_J); /** Set of Euler angles. * this ordered set of rotations is around Z, then around X, then * around Z */ public static final RotationOrder ZXZ = new RotationOrder("ZXZ", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_K); /** Set of Euler angles. * this ordered set of rotations is around Z, then around Y, then * around Z */ public static final RotationOrder ZYZ = new RotationOrder("ZYZ", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_K); /** Name of the rotations order. */ private final String name; /** Axis of the first rotation. */ private final Vector3D a1; /** Axis of the second rotation. */ private final Vector3D a2; /** Axis of the third rotation. */ private final Vector3D a3; /** Private constructor. * This is a utility class that cannot be instantiated by the user, * so its only constructor is private. * @param name name of the rotation order * @param a1 axis of the first rotation * @param a2 axis of the second rotation * @param a3 axis of the third rotation */ private RotationOrder(final String name, final Vector3D a1, final Vector3D a2, final Vector3D a3) { this.name = name; this.a1 = a1; this.a2 = a2; this.a3 = a3; } /** Get a string representation of the instance. * @return a string representation of the instance (in fact, its name) */ @Override public String toString() { return name; } /** Get the axis of the first rotation. * @return axis of the first rotation */ public Vector3D getA1() { return a1; } /** Get the axis of the second rotation. * @return axis of the second rotation */ public Vector3D getA2() { return a2; } /** Get the axis of the second rotation. * @return axis of the second rotation */ public Vector3D getA3() { return a3; } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/CardanEulerSingularityException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/CardanEulerSingularityException.100644 1750 1750 3334 11532241244 32501 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.LocalizedFormats; /** This class represents exceptions thrown while extractiong Cardan * or Euler angles from a rotation. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 1.2 */ public class CardanEulerSingularityException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -1360952845582206770L; /** * Simple constructor. * build an exception with a default message. * @param isCardan if true, the rotation is related to Cardan angles, * if false it is related to EulerAngles */ public CardanEulerSingularityException(boolean isCardan) { super(isCardan ? LocalizedFormats.CARDAN_ANGLES_SINGULARITY : LocalizedFormats.EULER_ANGLES_SINGULARITY); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/package.html100644 1750 1750 1631 11532241244 26460 0ustarlucluc 0 0

                    This package provides basic 3D geometry components.

                    commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/Vector3D.java100644 1750 1750 42727 11532241244 26526 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * This class implements vectors in a three-dimensional space. *

                    Instance of this class are guaranteed to be immutable.

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class Vector3D implements Serializable { /** Null vector (coordinates: 0, 0, 0). */ public static final Vector3D ZERO = new Vector3D(0, 0, 0); /** First canonical vector (coordinates: 1, 0, 0). */ public static final Vector3D PLUS_I = new Vector3D(1, 0, 0); /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */ public static final Vector3D MINUS_I = new Vector3D(-1, 0, 0); /** Second canonical vector (coordinates: 0, 1, 0). */ public static final Vector3D PLUS_J = new Vector3D(0, 1, 0); /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */ public static final Vector3D MINUS_J = new Vector3D(0, -1, 0); /** Third canonical vector (coordinates: 0, 0, 1). */ public static final Vector3D PLUS_K = new Vector3D(0, 0, 1); /** Opposite of the third canonical vector (coordinates: 0, 0, -1). */ public static final Vector3D MINUS_K = new Vector3D(0, 0, -1); // CHECKSTYLE: stop ConstantName /** A vector with all coordinates set to NaN. */ public static final Vector3D NaN = new Vector3D(Double.NaN, Double.NaN, Double.NaN); // CHECKSTYLE: resume ConstantName /** A vector with all coordinates set to positive infinity. */ public static final Vector3D POSITIVE_INFINITY = new Vector3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); /** A vector with all coordinates set to negative infinity. */ public static final Vector3D NEGATIVE_INFINITY = new Vector3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); /** Default format. */ private static final Vector3DFormat DEFAULT_FORMAT = Vector3DFormat.getInstance(); /** Serializable version identifier. */ private static final long serialVersionUID = 5133268763396045979L; /** Abscissa. */ private final double x; /** Ordinate. */ private final double y; /** Height. */ private final double z; /** Simple constructor. * Build a vector from its coordinates * @param x abscissa * @param y ordinate * @param z height * @see #getX() * @see #getY() * @see #getZ() */ public Vector3D(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } /** Simple constructor. * Build a vector from its azimuthal coordinates * @param alpha azimuth (α) around Z * (0 is +X, π/2 is +Y, π is -X and 3π/2 is -Y) * @param delta elevation (δ) above (XY) plane, from -π/2 to +π/2 * @see #getAlpha() * @see #getDelta() */ public Vector3D(double alpha, double delta) { double cosDelta = FastMath.cos(delta); this.x = FastMath.cos(alpha) * cosDelta; this.y = FastMath.sin(alpha) * cosDelta; this.z = FastMath.sin(delta); } /** Multiplicative constructor * Build a vector from another one and a scale factor. * The vector built will be a * u * @param a scale factor * @param u base (unscaled) vector */ public Vector3D(double a, Vector3D u) { this.x = a * u.x; this.y = a * u.y; this.z = a * u.z; } /** Linear constructor * Build a vector from two other ones and corresponding scale factors. * The vector built will be a1 * u1 + a2 * u2 * @param a1 first scale factor * @param u1 first base (unscaled) vector * @param a2 second scale factor * @param u2 second base (unscaled) vector */ public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2) { this.x = a1 * u1.x + a2 * u2.x; this.y = a1 * u1.y + a2 * u2.y; this.z = a1 * u1.z + a2 * u2.z; } /** Linear constructor * Build a vector from three other ones and corresponding scale factors. * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 * @param a1 first scale factor * @param u1 first base (unscaled) vector * @param a2 second scale factor * @param u2 second base (unscaled) vector * @param a3 third scale factor * @param u3 third base (unscaled) vector */ public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2, double a3, Vector3D u3) { this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x; this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y; this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z; } /** Linear constructor * Build a vector from four other ones and corresponding scale factors. * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4 * @param a1 first scale factor * @param u1 first base (unscaled) vector * @param a2 second scale factor * @param u2 second base (unscaled) vector * @param a3 third scale factor * @param u3 third base (unscaled) vector * @param a4 fourth scale factor * @param u4 fourth base (unscaled) vector */ public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2, double a3, Vector3D u3, double a4, Vector3D u4) { this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x; this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y; this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z + a4 * u4.z; } /** Get the abscissa of the vector. * @return abscissa of the vector * @see #Vector3D(double, double, double) */ public double getX() { return x; } /** Get the ordinate of the vector. * @return ordinate of the vector * @see #Vector3D(double, double, double) */ public double getY() { return y; } /** Get the height of the vector. * @return height of the vector * @see #Vector3D(double, double, double) */ public double getZ() { return z; } /** Get the L1 norm for the vector. * @return L1 norm for the vector */ public double getNorm1() { return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z); } /** Get the L2 norm for the vector. * @return euclidian norm for the vector */ public double getNorm() { return FastMath.sqrt (x * x + y * y + z * z); } /** Get the square of the norm for the vector. * @return square of the euclidian norm for the vector */ public double getNormSq() { return x * x + y * y + z * z; } /** Get the L norm for the vector. * @return L norm for the vector */ public double getNormInf() { return FastMath.max(FastMath.max(FastMath.abs(x), FastMath.abs(y)), FastMath.abs(z)); } /** Get the azimuth of the vector. * @return azimuth (α) of the vector, between -π and +π * @see #Vector3D(double, double) */ public double getAlpha() { return FastMath.atan2(y, x); } /** Get the elevation of the vector. * @return elevation (δ) of the vector, between -π/2 and +π/2 * @see #Vector3D(double, double) */ public double getDelta() { return FastMath.asin(z / getNorm()); } /** Add a vector to the instance. * @param v vector to add * @return a new vector */ public Vector3D add(Vector3D v) { return new Vector3D(x + v.x, y + v.y, z + v.z); } /** Add a scaled vector to the instance. * @param factor scale factor to apply to v before adding it * @param v vector to add * @return a new vector */ public Vector3D add(double factor, Vector3D v) { return new Vector3D(x + factor * v.x, y + factor * v.y, z + factor * v.z); } /** Subtract a vector from the instance. * @param v vector to subtract * @return a new vector */ public Vector3D subtract(Vector3D v) { return new Vector3D(x - v.x, y - v.y, z - v.z); } /** Subtract a scaled vector from the instance. * @param factor scale factor to apply to v before subtracting it * @param v vector to subtract * @return a new vector */ public Vector3D subtract(double factor, Vector3D v) { return new Vector3D(x - factor * v.x, y - factor * v.y, z - factor * v.z); } /** Get a normalized vector aligned with the instance. * @return a new normalized vector * @exception ArithmeticException if the norm is zero */ public Vector3D normalize() { double s = getNorm(); if (s == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR); } return scalarMultiply(1 / s); } /** Get a vector orthogonal to the instance. *

                    There are an infinite number of normalized vectors orthogonal * to the instance. This method picks up one of them almost * arbitrarily. It is useful when one needs to compute a reference * frame with one of the axes in a predefined direction. The * following example shows how to build a frame having the k axis * aligned with the known vector u : *

                    
                       *   Vector3D k = u.normalize();
                       *   Vector3D i = k.orthogonal();
                       *   Vector3D j = Vector3D.crossProduct(k, i);
                       * 

                    * @return a new normalized vector orthogonal to the instance * @exception ArithmeticException if the norm of the instance is null */ public Vector3D orthogonal() { double threshold = 0.6 * getNorm(); if (threshold == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM); } if ((x >= -threshold) && (x <= threshold)) { double inverse = 1 / FastMath.sqrt(y * y + z * z); return new Vector3D(0, inverse * z, -inverse * y); } else if ((y >= -threshold) && (y <= threshold)) { double inverse = 1 / FastMath.sqrt(x * x + z * z); return new Vector3D(-inverse * z, 0, inverse * x); } double inverse = 1 / FastMath.sqrt(x * x + y * y); return new Vector3D(inverse * y, -inverse * x, 0); } /** Compute the angular separation between two vectors. *

                    This method computes the angular separation between two * vectors using the dot product for well separated vectors and the * cross product for almost aligned vectors. This allows to have a * good accuracy in all cases, even for vectors very close to each * other.

                    * @param v1 first vector * @param v2 second vector * @return angular separation between v1 and v2 * @exception ArithmeticException if either vector has a null norm */ public static double angle(Vector3D v1, Vector3D v2) { double normProduct = v1.getNorm() * v2.getNorm(); if (normProduct == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM); } double dot = dotProduct(v1, v2); double threshold = normProduct * 0.9999; if ((dot < -threshold) || (dot > threshold)) { // the vectors are almost aligned, compute using the sine Vector3D v3 = crossProduct(v1, v2); if (dot >= 0) { return FastMath.asin(v3.getNorm() / normProduct); } return FastMath.PI - FastMath.asin(v3.getNorm() / normProduct); } // the vectors are sufficiently separated to use the cosine return FastMath.acos(dot / normProduct); } /** Get the opposite of the instance. * @return a new vector which is opposite to the instance */ public Vector3D negate() { return new Vector3D(-x, -y, -z); } /** Multiply the instance by a scalar * @param a scalar * @return a new vector */ public Vector3D scalarMultiply(double a) { return new Vector3D(a * x, a * y, a * z); } /** * Returns true if any coordinate of this vector is NaN; false otherwise * @return true if any coordinate of this vector is NaN; false otherwise */ public boolean isNaN() { return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z); } /** * Returns true if any coordinate of this vector is infinite and none are NaN; * false otherwise * @return true if any coordinate of this vector is infinite and none are NaN; * false otherwise */ public boolean isInfinite() { return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z)); } /** * Test for the equality of two 3D vectors. *

                    * If all coordinates of two 3D vectors are exactly the same, and none are * Double.NaN, the two 3D vectors are considered to be equal. *

                    *

                    * NaN coordinates are considered to affect globally the vector * and be equals to each other - i.e, if either (or all) coordinates of the * 3D vector are equal to Double.NaN, the 3D vector is equal to * {@link #NaN}. *

                    * * @param other Object to test for equality to this * @return true if two 3D vector objects are equal, false if * object is null, not an instance of Vector3D, or * not equal to this Vector3D instance * */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof Vector3D) { final Vector3D rhs = (Vector3D)other; if (rhs.isNaN()) { return this.isNaN(); } return (x == rhs.x) && (y == rhs.y) && (z == rhs.z); } return false; } /** * Get a hashCode for the 3D vector. *

                    * All NaN values have the same hash code.

                    * * @return a hash code value for this object */ @Override public int hashCode() { if (isNaN()) { return 8; } return 31 * (23 * MathUtils.hash(x) + 19 * MathUtils.hash(y) + MathUtils.hash(z)); } /** Compute the dot-product of two vectors. * @param v1 first vector * @param v2 second vector * @return the dot product v1.v2 */ public static double dotProduct(Vector3D v1, Vector3D v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } /** Compute the cross-product of two vectors. * @param v1 first vector * @param v2 second vector * @return the cross product v1 ^ v2 as a new Vector */ public static Vector3D crossProduct(Vector3D v1, Vector3D v2) { return new Vector3D(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); } /** Compute the distance between two vectors according to the L1 norm. *

                    Calling this method is equivalent to calling: * v1.subtract(v2).getNorm1() except that no intermediate * vector is built

                    * @param v1 first vector * @param v2 second vector * @return the distance between v1 and v2 according to the L1 norm */ public static double distance1(Vector3D v1, Vector3D v2) { final double dx = FastMath.abs(v2.x - v1.x); final double dy = FastMath.abs(v2.y - v1.y); final double dz = FastMath.abs(v2.z - v1.z); return dx + dy + dz; } /** Compute the distance between two vectors according to the L2 norm. *

                    Calling this method is equivalent to calling: * v1.subtract(v2).getNorm() except that no intermediate * vector is built

                    * @param v1 first vector * @param v2 second vector * @return the distance between v1 and v2 according to the L2 norm */ public static double distance(Vector3D v1, Vector3D v2) { final double dx = v2.x - v1.x; final double dy = v2.y - v1.y; final double dz = v2.z - v1.z; return FastMath.sqrt(dx * dx + dy * dy + dz * dz); } /** Compute the distance between two vectors according to the L norm. *

                    Calling this method is equivalent to calling: * v1.subtract(v2).getNormInf() except that no intermediate * vector is built

                    * @param v1 first vector * @param v2 second vector * @return the distance between v1 and v2 according to the L norm */ public static double distanceInf(Vector3D v1, Vector3D v2) { final double dx = FastMath.abs(v2.x - v1.x); final double dy = FastMath.abs(v2.y - v1.y); final double dz = FastMath.abs(v2.z - v1.z); return FastMath.max(FastMath.max(dx, dy), dz); } /** Compute the square of the distance between two vectors. *

                    Calling this method is equivalent to calling: * v1.subtract(v2).getNormSq() except that no intermediate * vector is built

                    * @param v1 first vector * @param v2 second vector * @return the square of the distance between v1 and v2 */ public static double distanceSq(Vector3D v1, Vector3D v2) { final double dx = v2.x - v1.x; final double dy = v2.y - v1.y; final double dz = v2.z - v1.z; return dx * dx + dy * dy + dz * dz; } /** Get a string representation of this vector. * @return a string representation of this vector */ @Override public String toString() { return DEFAULT_FORMAT.format(this); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/geometry/Rotation.java100644 1750 1750 124727 11532241244 26715 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.geometry; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * This class implements rotations in a three-dimensional space. * *

                    Rotations can be represented by several different mathematical * entities (matrices, axe and angle, Cardan or Euler angles, * quaternions). This class presents an higher level abstraction, more * user-oriented and hiding this implementation details. Well, for the * curious, we use quaternions for the internal representation. The * user can build a rotation from any of these representations, and * any of these representations can be retrieved from a * Rotation instance (see the various constructors and * getters). In addition, a rotation can also be built implicitly * from a set of vectors and their image.

                    *

                    This implies that this class can be used to convert from one * representation to another one. For example, converting a rotation * matrix into a set of Cardan angles from can be done using the * following single line of code:

                    *
                     * double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ);
                     * 
                    *

                    Focus is oriented on what a rotation do rather than on its * underlying representation. Once it has been built, and regardless of its * internal representation, a rotation is an operator which basically * transforms three dimensional {@link Vector3D vectors} into other three * dimensional {@link Vector3D vectors}. Depending on the application, the * meaning of these vectors may vary and the semantics of the rotation also.

                    *

                    For example in an spacecraft attitude simulation tool, users will often * consider the vectors are fixed (say the Earth direction for example) and the * frames change. The rotation transforms the coordinates of the vector in inertial * frame into the coordinates of the same vector in satellite frame. In this * case, the rotation implicitly defines the relation between the two frames.

                    *

                    Another example could be a telescope control application, where the rotation * would transform the sighting direction at rest into the desired observing * direction when the telescope is pointed towards an object of interest. In this * case the rotation transforms the direction at rest in a topocentric frame * into the sighting direction in the same topocentric frame. This implies in this * case the frame is fixed and the vector moves.

                    *

                    In many case, both approaches will be combined. In our telescope example, * we will probably also need to transform the observing direction in the topocentric * frame into the observing direction in inertial frame taking into account the observatory * location and the Earth rotation, which would essentially be an application of the * first approach.

                    * *

                    These examples show that a rotation is what the user wants it to be. This * class does not push the user towards one specific definition and hence does not * provide methods like projectVectorIntoDestinationFrame or * computeTransformedDirection. It provides simpler and more generic * methods: {@link #applyTo(Vector3D) applyTo(Vector3D)} and {@link * #applyInverseTo(Vector3D) applyInverseTo(Vector3D)}.

                    * *

                    Since a rotation is basically a vectorial operator, several rotations can be * composed together and the composite operation r = r1 o * r2 (which means that for each vector u, * r(u) = r1(r2(u))) is also a rotation. Hence * we can consider that in addition to vectors, a rotation can be applied to other * rotations as well (or to itself). With our previous notations, we would say we * can apply r1 to r2 and the result * we get is r = r1 o r2. For this purpose, the * class provides the methods: {@link #applyTo(Rotation) applyTo(Rotation)} and * {@link #applyInverseTo(Rotation) applyInverseTo(Rotation)}.

                    * *

                    Rotations are guaranteed to be immutable objects.

                    * * @version $Revision: 1067500 $ $Date: 2011-02-05 21:11:30 +0100 (sam. 05 févr. 2011) $ * @see Vector3D * @see RotationOrder * @since 1.2 */ public class Rotation implements Serializable { /** Identity rotation. */ public static final Rotation IDENTITY = new Rotation(1.0, 0.0, 0.0, 0.0, false); /** Serializable version identifier */ private static final long serialVersionUID = -2153622329907944313L; /** Scalar coordinate of the quaternion. */ private final double q0; /** First coordinate of the vectorial part of the quaternion. */ private final double q1; /** Second coordinate of the vectorial part of the quaternion. */ private final double q2; /** Third coordinate of the vectorial part of the quaternion. */ private final double q3; /** Build a rotation from the quaternion coordinates. *

                    A rotation can be built from a normalized quaternion, * i.e. a quaternion for which q02 + * q12 + q22 + * q32 = 1. If the quaternion is not normalized, * the constructor can normalize it in a preprocessing step.

                    *

                    Note that some conventions put the scalar part of the quaternion * as the 4th component and the vector part as the first three * components. This is not our convention. We put the scalar part * as the first component.

                    * @param q0 scalar part of the quaternion * @param q1 first coordinate of the vectorial part of the quaternion * @param q2 second coordinate of the vectorial part of the quaternion * @param q3 third coordinate of the vectorial part of the quaternion * @param needsNormalization if true, the coordinates are considered * not to be normalized, a normalization preprocessing step is performed * before using them */ public Rotation(double q0, double q1, double q2, double q3, boolean needsNormalization) { if (needsNormalization) { // normalization preprocessing double inv = 1.0 / FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3); q0 *= inv; q1 *= inv; q2 *= inv; q3 *= inv; } this.q0 = q0; this.q1 = q1; this.q2 = q2; this.q3 = q3; } /** Build a rotation from an axis and an angle. *

                    We use the convention that angles are oriented according to * the effect of the rotation on vectors around the axis. That means * that if (i, j, k) is a direct frame and if we first provide +k as * the axis and π/2 as the angle to this constructor, and then * {@link #applyTo(Vector3D) apply} the instance to +i, we will get * +j.

                    *

                    Another way to represent our convention is to say that a rotation * of angle θ about the unit vector (x, y, z) is the same as the * rotation build from quaternion components { cos(-θ/2), * x * sin(-θ/2), y * sin(-θ/2), z * sin(-θ/2) }. * Note the minus sign on the angle!

                    *

                    On the one hand this convention is consistent with a vectorial * perspective (moving vectors in fixed frames), on the other hand it * is different from conventions with a frame perspective (fixed vectors * viewed from different frames) like the ones used for example in spacecraft * attitude community or in the graphics community.

                    * @param axis axis around which to rotate * @param angle rotation angle. * @exception ArithmeticException if the axis norm is zero */ public Rotation(Vector3D axis, double angle) { double norm = axis.getNorm(); if (norm == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_AXIS); } double halfAngle = -0.5 * angle; double coeff = FastMath.sin(halfAngle) / norm; q0 = FastMath.cos (halfAngle); q1 = coeff * axis.getX(); q2 = coeff * axis.getY(); q3 = coeff * axis.getZ(); } /** Build a rotation from a 3X3 matrix. *

                    Rotation matrices are orthogonal matrices, i.e. unit matrices * (which are matrices for which m.mT = I) with real * coefficients. The module of the determinant of unit matrices is * 1, among the orthogonal 3X3 matrices, only the ones having a * positive determinant (+1) are rotation matrices.

                    * *

                    When a rotation is defined by a matrix with truncated values * (typically when it is extracted from a technical sheet where only * four to five significant digits are available), the matrix is not * orthogonal anymore. This constructor handles this case * transparently by using a copy of the given matrix and applying a * correction to the copy in order to perfect its orthogonality. If * the Frobenius norm of the correction needed is above the given * threshold, then the matrix is considered to be too far from a * true rotation matrix and an exception is thrown.

                    * * @param m rotation matrix * @param threshold convergence threshold for the iterative * orthogonality correction (convergence is reached when the * difference between two steps of the Frobenius norm of the * correction is below this threshold) * * @exception NotARotationMatrixException if the matrix is not a 3X3 * matrix, or if it cannot be transformed into an orthogonal matrix * with the given threshold, or if the determinant of the resulting * orthogonal matrix is negative * */ public Rotation(double[][] m, double threshold) throws NotARotationMatrixException { // dimension check if ((m.length != 3) || (m[0].length != 3) || (m[1].length != 3) || (m[2].length != 3)) { throw new NotARotationMatrixException( LocalizedFormats.ROTATION_MATRIX_DIMENSIONS, m.length, m[0].length); } // compute a "close" orthogonal matrix double[][] ort = orthogonalizeMatrix(m, threshold); // check the sign of the determinant double det = ort[0][0] * (ort[1][1] * ort[2][2] - ort[2][1] * ort[1][2]) - ort[1][0] * (ort[0][1] * ort[2][2] - ort[2][1] * ort[0][2]) + ort[2][0] * (ort[0][1] * ort[1][2] - ort[1][1] * ort[0][2]); if (det < 0.0) { throw new NotARotationMatrixException( LocalizedFormats.CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT, det); } // There are different ways to compute the quaternions elements // from the matrix. They all involve computing one element from // the diagonal of the matrix, and computing the three other ones // using a formula involving a division by the first element, // which unfortunately can be zero. Since the norm of the // quaternion is 1, we know at least one element has an absolute // value greater or equal to 0.5, so it is always possible to // select the right formula and avoid division by zero and even // numerical inaccuracy. Checking the elements in turn and using // the first one greater than 0.45 is safe (this leads to a simple // test since qi = 0.45 implies 4 qi^2 - 1 = -0.19) double s = ort[0][0] + ort[1][1] + ort[2][2]; if (s > -0.19) { // compute q0 and deduce q1, q2 and q3 q0 = 0.5 * FastMath.sqrt(s + 1.0); double inv = 0.25 / q0; q1 = inv * (ort[1][2] - ort[2][1]); q2 = inv * (ort[2][0] - ort[0][2]); q3 = inv * (ort[0][1] - ort[1][0]); } else { s = ort[0][0] - ort[1][1] - ort[2][2]; if (s > -0.19) { // compute q1 and deduce q0, q2 and q3 q1 = 0.5 * FastMath.sqrt(s + 1.0); double inv = 0.25 / q1; q0 = inv * (ort[1][2] - ort[2][1]); q2 = inv * (ort[0][1] + ort[1][0]); q3 = inv * (ort[0][2] + ort[2][0]); } else { s = ort[1][1] - ort[0][0] - ort[2][2]; if (s > -0.19) { // compute q2 and deduce q0, q1 and q3 q2 = 0.5 * FastMath.sqrt(s + 1.0); double inv = 0.25 / q2; q0 = inv * (ort[2][0] - ort[0][2]); q1 = inv * (ort[0][1] + ort[1][0]); q3 = inv * (ort[2][1] + ort[1][2]); } else { // compute q3 and deduce q0, q1 and q2 s = ort[2][2] - ort[0][0] - ort[1][1]; q3 = 0.5 * FastMath.sqrt(s + 1.0); double inv = 0.25 / q3; q0 = inv * (ort[0][1] - ort[1][0]); q1 = inv * (ort[0][2] + ort[2][0]); q2 = inv * (ort[2][1] + ort[1][2]); } } } } /** Build the rotation that transforms a pair of vector into another pair. *

                    Except for possible scale factors, if the instance were applied to * the pair (u1, u2) it will produce the pair * (v1, v2).

                    * *

                    If the angular separation between u1 and u2 is * not the same as the angular separation between v1 and * v2, then a corrected v'2 will be used rather than * v2, the corrected vector will be in the (v1, * v2) plane.

                    * * @param u1 first vector of the origin pair * @param u2 second vector of the origin pair * @param v1 desired image of u1 by the rotation * @param v2 desired image of u2 by the rotation * @exception IllegalArgumentException if the norm of one of the vectors is zero */ public Rotation(Vector3D u1, Vector3D u2, Vector3D v1, Vector3D v2) { // norms computation double u1u1 = Vector3D.dotProduct(u1, u1); double u2u2 = Vector3D.dotProduct(u2, u2); double v1v1 = Vector3D.dotProduct(v1, v1); double v2v2 = Vector3D.dotProduct(v2, v2); if ((u1u1 == 0) || (u2u2 == 0) || (v1v1 == 0) || (v2v2 == 0)) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR); } double u1x = u1.getX(); double u1y = u1.getY(); double u1z = u1.getZ(); double u2x = u2.getX(); double u2y = u2.getY(); double u2z = u2.getZ(); // normalize v1 in order to have (v1'|v1') = (u1|u1) double coeff = FastMath.sqrt (u1u1 / v1v1); double v1x = coeff * v1.getX(); double v1y = coeff * v1.getY(); double v1z = coeff * v1.getZ(); v1 = new Vector3D(v1x, v1y, v1z); // adjust v2 in order to have (u1|u2) = (v1|v2) and (v2'|v2') = (u2|u2) double u1u2 = Vector3D.dotProduct(u1, u2); double v1v2 = Vector3D.dotProduct(v1, v2); double coeffU = u1u2 / u1u1; double coeffV = v1v2 / u1u1; double beta = FastMath.sqrt((u2u2 - u1u2 * coeffU) / (v2v2 - v1v2 * coeffV)); double alpha = coeffU - beta * coeffV; double v2x = alpha * v1x + beta * v2.getX(); double v2y = alpha * v1y + beta * v2.getY(); double v2z = alpha * v1z + beta * v2.getZ(); v2 = new Vector3D(v2x, v2y, v2z); // preliminary computation (we use explicit formulation instead // of relying on the Vector3D class in order to avoid building lots // of temporary objects) Vector3D uRef = u1; Vector3D vRef = v1; double dx1 = v1x - u1.getX(); double dy1 = v1y - u1.getY(); double dz1 = v1z - u1.getZ(); double dx2 = v2x - u2.getX(); double dy2 = v2y - u2.getY(); double dz2 = v2z - u2.getZ(); Vector3D k = new Vector3D(dy1 * dz2 - dz1 * dy2, dz1 * dx2 - dx1 * dz2, dx1 * dy2 - dy1 * dx2); double c = k.getX() * (u1y * u2z - u1z * u2y) + k.getY() * (u1z * u2x - u1x * u2z) + k.getZ() * (u1x * u2y - u1y * u2x); if (c == 0) { // the (q1, q2, q3) vector is in the (u1, u2) plane // we try other vectors Vector3D u3 = Vector3D.crossProduct(u1, u2); Vector3D v3 = Vector3D.crossProduct(v1, v2); double u3x = u3.getX(); double u3y = u3.getY(); double u3z = u3.getZ(); double v3x = v3.getX(); double v3y = v3.getY(); double v3z = v3.getZ(); double dx3 = v3x - u3x; double dy3 = v3y - u3y; double dz3 = v3z - u3z; k = new Vector3D(dy1 * dz3 - dz1 * dy3, dz1 * dx3 - dx1 * dz3, dx1 * dy3 - dy1 * dx3); c = k.getX() * (u1y * u3z - u1z * u3y) + k.getY() * (u1z * u3x - u1x * u3z) + k.getZ() * (u1x * u3y - u1y * u3x); if (c == 0) { // the (q1, q2, q3) vector is aligned with u1: // we try (u2, u3) and (v2, v3) k = new Vector3D(dy2 * dz3 - dz2 * dy3, dz2 * dx3 - dx2 * dz3, dx2 * dy3 - dy2 * dx3); c = k.getX() * (u2y * u3z - u2z * u3y) + k.getY() * (u2z * u3x - u2x * u3z) + k.getZ() * (u2x * u3y - u2y * u3x); if (c == 0) { // the (q1, q2, q3) vector is aligned with everything // this is really the identity rotation q0 = 1.0; q1 = 0.0; q2 = 0.0; q3 = 0.0; return; } // we will have to use u2 and v2 to compute the scalar part uRef = u2; vRef = v2; } } // compute the vectorial part c = FastMath.sqrt(c); double inv = 1.0 / (c + c); q1 = inv * k.getX(); q2 = inv * k.getY(); q3 = inv * k.getZ(); // compute the scalar part k = new Vector3D(uRef.getY() * q3 - uRef.getZ() * q2, uRef.getZ() * q1 - uRef.getX() * q3, uRef.getX() * q2 - uRef.getY() * q1); c = Vector3D.dotProduct(k, k); q0 = Vector3D.dotProduct(vRef, k) / (c + c); } /** Build one of the rotations that transform one vector into another one. *

                    Except for a possible scale factor, if the instance were * applied to the vector u it will produce the vector v. There is an * infinite number of such rotations, this constructor choose the * one with the smallest associated angle (i.e. the one whose axis * is orthogonal to the (u, v) plane). If u and v are colinear, an * arbitrary rotation axis is chosen.

                    * * @param u origin vector * @param v desired image of u by the rotation * @exception IllegalArgumentException if the norm of one of the vectors is zero */ public Rotation(Vector3D u, Vector3D v) { double normProduct = u.getNorm() * v.getNorm(); if (normProduct == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR); } double dot = Vector3D.dotProduct(u, v); if (dot < ((2.0e-15 - 1.0) * normProduct)) { // special case u = -v: we select a PI angle rotation around // an arbitrary vector orthogonal to u Vector3D w = u.orthogonal(); q0 = 0.0; q1 = -w.getX(); q2 = -w.getY(); q3 = -w.getZ(); } else { // general case: (u, v) defines a plane, we select // the shortest possible rotation: axis orthogonal to this plane q0 = FastMath.sqrt(0.5 * (1.0 + dot / normProduct)); double coeff = 1.0 / (2.0 * q0 * normProduct); q1 = coeff * (v.getY() * u.getZ() - v.getZ() * u.getY()); q2 = coeff * (v.getZ() * u.getX() - v.getX() * u.getZ()); q3 = coeff * (v.getX() * u.getY() - v.getY() * u.getX()); } } /** Build a rotation from three Cardan or Euler elementary rotations. *

                    Cardan rotations are three successive rotations around the * canonical axes X, Y and Z, each axis being used once. There are * 6 such sets of rotations (XYZ, XZY, YXZ, YZX, ZXY and ZYX). Euler * rotations are three successive rotations around the canonical * axes X, Y and Z, the first and last rotations being around the * same axis. There are 6 such sets of rotations (XYX, XZX, YXY, * YZY, ZXZ and ZYZ), the most popular one being ZXZ.

                    *

                    Beware that many people routinely use the term Euler angles even * for what really are Cardan angles (this confusion is especially * widespread in the aerospace business where Roll, Pitch and Yaw angles * are often wrongly tagged as Euler angles).

                    * * @param order order of rotations to use * @param alpha1 angle of the first elementary rotation * @param alpha2 angle of the second elementary rotation * @param alpha3 angle of the third elementary rotation */ public Rotation(RotationOrder order, double alpha1, double alpha2, double alpha3) { Rotation r1 = new Rotation(order.getA1(), alpha1); Rotation r2 = new Rotation(order.getA2(), alpha2); Rotation r3 = new Rotation(order.getA3(), alpha3); Rotation composed = r1.applyTo(r2.applyTo(r3)); q0 = composed.q0; q1 = composed.q1; q2 = composed.q2; q3 = composed.q3; } /** Revert a rotation. * Build a rotation which reverse the effect of another * rotation. This means that if r(u) = v, then r.revert(v) = u. The * instance is not changed. * @return a new rotation whose effect is the reverse of the effect * of the instance */ public Rotation revert() { return new Rotation(-q0, q1, q2, q3, false); } /** Get the scalar coordinate of the quaternion. * @return scalar coordinate of the quaternion */ public double getQ0() { return q0; } /** Get the first coordinate of the vectorial part of the quaternion. * @return first coordinate of the vectorial part of the quaternion */ public double getQ1() { return q1; } /** Get the second coordinate of the vectorial part of the quaternion. * @return second coordinate of the vectorial part of the quaternion */ public double getQ2() { return q2; } /** Get the third coordinate of the vectorial part of the quaternion. * @return third coordinate of the vectorial part of the quaternion */ public double getQ3() { return q3; } /** Get the normalized axis of the rotation. * @return normalized axis of the rotation * @see #Rotation(Vector3D, double) */ public Vector3D getAxis() { double squaredSine = q1 * q1 + q2 * q2 + q3 * q3; if (squaredSine == 0) { return new Vector3D(1, 0, 0); } else if (q0 < 0) { double inverse = 1 / FastMath.sqrt(squaredSine); return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse); } double inverse = -1 / FastMath.sqrt(squaredSine); return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse); } /** Get the angle of the rotation. * @return angle of the rotation (between 0 and π) * @see #Rotation(Vector3D, double) */ public double getAngle() { if ((q0 < -0.1) || (q0 > 0.1)) { return 2 * FastMath.asin(FastMath.sqrt(q1 * q1 + q2 * q2 + q3 * q3)); } else if (q0 < 0) { return 2 * FastMath.acos(-q0); } return 2 * FastMath.acos(q0); } /** Get the Cardan or Euler angles corresponding to the instance. *

                    The equations show that each rotation can be defined by two * different values of the Cardan or Euler angles set. For example * if Cardan angles are used, the rotation defined by the angles * a1, a2 and a3 is the same as * the rotation defined by the angles π + a1, π * - a2 and π + a3. This method implements * the following arbitrary choices:

                    *
                      *
                    • for Cardan angles, the chosen set is the one for which the * second angle is between -π/2 and π/2 (i.e its cosine is * positive),
                    • *
                    • for Euler angles, the chosen set is the one for which the * second angle is between 0 and π (i.e its sine is positive).
                    • *
                    * *

                    Cardan and Euler angle have a very disappointing drawback: all * of them have singularities. This means that if the instance is * too close to the singularities corresponding to the given * rotation order, it will be impossible to retrieve the angles. For * Cardan angles, this is often called gimbal lock. There is * nothing to do to prevent this, it is an intrinsic problem * with Cardan and Euler representation (but not a problem with the * rotation itself, which is perfectly well defined). For Cardan * angles, singularities occur when the second angle is close to * -π/2 or +π/2, for Euler angle singularities occur when the * second angle is close to 0 or π, this implies that the identity * rotation is always singular for Euler angles!

                    * * @param order rotation order to use * @return an array of three angles, in the order specified by the set * @exception CardanEulerSingularityException if the rotation is * singular with respect to the angles set specified */ public double[] getAngles(RotationOrder order) throws CardanEulerSingularityException { if (order == RotationOrder.XYZ) { // r (Vector3D.plusK) coordinates are : // sin (theta), -cos (theta) sin (phi), cos (theta) cos (phi) // (-r) (Vector3D.plusI) coordinates are : // cos (psi) cos (theta), -sin (psi) cos (theta), sin (theta) // and we can choose to have theta in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_K); Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(-(v1.getY()), v1.getZ()), FastMath.asin(v2.getZ()), FastMath.atan2(-(v2.getY()), v2.getX()) }; } else if (order == RotationOrder.XZY) { // r (Vector3D.plusJ) coordinates are : // -sin (psi), cos (psi) cos (phi), cos (psi) sin (phi) // (-r) (Vector3D.plusI) coordinates are : // cos (theta) cos (psi), -sin (psi), sin (theta) cos (psi) // and we can choose to have psi in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_J); Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(v1.getZ(), v1.getY()), -FastMath.asin(v2.getY()), FastMath.atan2(v2.getZ(), v2.getX()) }; } else if (order == RotationOrder.YXZ) { // r (Vector3D.plusK) coordinates are : // cos (phi) sin (theta), -sin (phi), cos (phi) cos (theta) // (-r) (Vector3D.plusJ) coordinates are : // sin (psi) cos (phi), cos (psi) cos (phi), -sin (phi) // and we can choose to have phi in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_K); Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(v1.getX(), v1.getZ()), -FastMath.asin(v2.getZ()), FastMath.atan2(v2.getX(), v2.getY()) }; } else if (order == RotationOrder.YZX) { // r (Vector3D.plusI) coordinates are : // cos (psi) cos (theta), sin (psi), -cos (psi) sin (theta) // (-r) (Vector3D.plusJ) coordinates are : // sin (psi), cos (phi) cos (psi), -sin (phi) cos (psi) // and we can choose to have psi in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_I); Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(-(v1.getZ()), v1.getX()), FastMath.asin(v2.getX()), FastMath.atan2(-(v2.getZ()), v2.getY()) }; } else if (order == RotationOrder.ZXY) { // r (Vector3D.plusJ) coordinates are : // -cos (phi) sin (psi), cos (phi) cos (psi), sin (phi) // (-r) (Vector3D.plusK) coordinates are : // -sin (theta) cos (phi), sin (phi), cos (theta) cos (phi) // and we can choose to have phi in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_J); Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(-(v1.getX()), v1.getY()), FastMath.asin(v2.getY()), FastMath.atan2(-(v2.getX()), v2.getZ()) }; } else if (order == RotationOrder.ZYX) { // r (Vector3D.plusI) coordinates are : // cos (theta) cos (psi), cos (theta) sin (psi), -sin (theta) // (-r) (Vector3D.plusK) coordinates are : // -sin (theta), sin (phi) cos (theta), cos (phi) cos (theta) // and we can choose to have theta in the interval [-PI/2 ; +PI/2] Vector3D v1 = applyTo(Vector3D.PLUS_I); Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { throw new CardanEulerSingularityException(true); } return new double[] { FastMath.atan2(v1.getY(), v1.getX()), -FastMath.asin(v2.getX()), FastMath.atan2(v2.getY(), v2.getZ()) }; } else if (order == RotationOrder.XYX) { // r (Vector3D.plusI) coordinates are : // cos (theta), sin (phi1) sin (theta), -cos (phi1) sin (theta) // (-r) (Vector3D.plusI) coordinates are : // cos (theta), sin (theta) sin (phi2), sin (theta) cos (phi2) // and we can choose to have theta in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_I); Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getY(), -v1.getZ()), FastMath.acos(v2.getX()), FastMath.atan2(v2.getY(), v2.getZ()) }; } else if (order == RotationOrder.XZX) { // r (Vector3D.plusI) coordinates are : // cos (psi), cos (phi1) sin (psi), sin (phi1) sin (psi) // (-r) (Vector3D.plusI) coordinates are : // cos (psi), -sin (psi) cos (phi2), sin (psi) sin (phi2) // and we can choose to have psi in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_I); Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getZ(), v1.getY()), FastMath.acos(v2.getX()), FastMath.atan2(v2.getZ(), -v2.getY()) }; } else if (order == RotationOrder.YXY) { // r (Vector3D.plusJ) coordinates are : // sin (theta1) sin (phi), cos (phi), cos (theta1) sin (phi) // (-r) (Vector3D.plusJ) coordinates are : // sin (phi) sin (theta2), cos (phi), -sin (phi) cos (theta2) // and we can choose to have phi in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_J); Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getX(), v1.getZ()), FastMath.acos(v2.getY()), FastMath.atan2(v2.getX(), -v2.getZ()) }; } else if (order == RotationOrder.YZY) { // r (Vector3D.plusJ) coordinates are : // -cos (theta1) sin (psi), cos (psi), sin (theta1) sin (psi) // (-r) (Vector3D.plusJ) coordinates are : // sin (psi) cos (theta2), cos (psi), sin (psi) sin (theta2) // and we can choose to have psi in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_J); Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getZ(), -v1.getX()), FastMath.acos(v2.getY()), FastMath.atan2(v2.getZ(), v2.getX()) }; } else if (order == RotationOrder.ZXZ) { // r (Vector3D.plusK) coordinates are : // sin (psi1) sin (phi), -cos (psi1) sin (phi), cos (phi) // (-r) (Vector3D.plusK) coordinates are : // sin (phi) sin (psi2), sin (phi) cos (psi2), cos (phi) // and we can choose to have phi in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_K); Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getX(), -v1.getY()), FastMath.acos(v2.getZ()), FastMath.atan2(v2.getX(), v2.getY()) }; } else { // last possibility is ZYZ // r (Vector3D.plusK) coordinates are : // cos (psi1) sin (theta), sin (psi1) sin (theta), cos (theta) // (-r) (Vector3D.plusK) coordinates are : // -sin (theta) cos (psi2), sin (theta) sin (psi2), cos (theta) // and we can choose to have theta in the interval [0 ; PI] Vector3D v1 = applyTo(Vector3D.PLUS_K); Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { throw new CardanEulerSingularityException(false); } return new double[] { FastMath.atan2(v1.getY(), v1.getX()), FastMath.acos(v2.getZ()), FastMath.atan2(v2.getY(), -v2.getX()) }; } } /** Get the 3X3 matrix corresponding to the instance * @return the matrix corresponding to the instance */ public double[][] getMatrix() { // products double q0q0 = q0 * q0; double q0q1 = q0 * q1; double q0q2 = q0 * q2; double q0q3 = q0 * q3; double q1q1 = q1 * q1; double q1q2 = q1 * q2; double q1q3 = q1 * q3; double q2q2 = q2 * q2; double q2q3 = q2 * q3; double q3q3 = q3 * q3; // create the matrix double[][] m = new double[3][]; m[0] = new double[3]; m[1] = new double[3]; m[2] = new double[3]; m [0][0] = 2.0 * (q0q0 + q1q1) - 1.0; m [1][0] = 2.0 * (q1q2 - q0q3); m [2][0] = 2.0 * (q1q3 + q0q2); m [0][1] = 2.0 * (q1q2 + q0q3); m [1][1] = 2.0 * (q0q0 + q2q2) - 1.0; m [2][1] = 2.0 * (q2q3 - q0q1); m [0][2] = 2.0 * (q1q3 - q0q2); m [1][2] = 2.0 * (q2q3 + q0q1); m [2][2] = 2.0 * (q0q0 + q3q3) - 1.0; return m; } /** Apply the rotation to a vector. * @param u vector to apply the rotation to * @return a new vector which is the image of u by the rotation */ public Vector3D applyTo(Vector3D u) { double x = u.getX(); double y = u.getY(); double z = u.getZ(); double s = q1 * x + q2 * y + q3 * z; return new Vector3D(2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x, 2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y, 2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z); } /** Apply the inverse of the rotation to a vector. * @param u vector to apply the inverse of the rotation to * @return a new vector which such that u is its image by the rotation */ public Vector3D applyInverseTo(Vector3D u) { double x = u.getX(); double y = u.getY(); double z = u.getZ(); double s = q1 * x + q2 * y + q3 * z; double m0 = -q0; return new Vector3D(2 * (m0 * (x * m0 - (q2 * z - q3 * y)) + s * q1) - x, 2 * (m0 * (y * m0 - (q3 * x - q1 * z)) + s * q2) - y, 2 * (m0 * (z * m0 - (q1 * y - q2 * x)) + s * q3) - z); } /** Apply the instance to another rotation. * Applying the instance to a rotation is computing the composition * in an order compliant with the following rule : let u be any * vector and v its image by r (i.e. r.applyTo(u) = v), let w be the image * of v by the instance (i.e. applyTo(v) = w), then w = comp.applyTo(u), * where comp = applyTo(r). * @param r rotation to apply the rotation to * @return a new rotation which is the composition of r by the instance */ public Rotation applyTo(Rotation r) { return new Rotation(r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3), r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2), r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3), r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1), false); } /** Apply the inverse of the instance to another rotation. * Applying the inverse of the instance to a rotation is computing * the composition in an order compliant with the following rule : * let u be any vector and v its image by r (i.e. r.applyTo(u) = v), * let w be the inverse image of v by the instance * (i.e. applyInverseTo(v) = w), then w = comp.applyTo(u), where * comp = applyInverseTo(r). * @param r rotation to apply the rotation to * @return a new rotation which is the composition of r by the inverse * of the instance */ public Rotation applyInverseTo(Rotation r) { return new Rotation(-r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3), -r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2), -r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3), -r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1), false); } /** Perfect orthogonality on a 3X3 matrix. * @param m initial matrix (not exactly orthogonal) * @param threshold convergence threshold for the iterative * orthogonality correction (convergence is reached when the * difference between two steps of the Frobenius norm of the * correction is below this threshold) * @return an orthogonal matrix close to m * @exception NotARotationMatrixException if the matrix cannot be * orthogonalized with the given threshold after 10 iterations */ private double[][] orthogonalizeMatrix(double[][] m, double threshold) throws NotARotationMatrixException { double[] m0 = m[0]; double[] m1 = m[1]; double[] m2 = m[2]; double x00 = m0[0]; double x01 = m0[1]; double x02 = m0[2]; double x10 = m1[0]; double x11 = m1[1]; double x12 = m1[2]; double x20 = m2[0]; double x21 = m2[1]; double x22 = m2[2]; double fn = 0; double fn1; double[][] o = new double[3][3]; double[] o0 = o[0]; double[] o1 = o[1]; double[] o2 = o[2]; // iterative correction: Xn+1 = Xn - 0.5 * (Xn.Mt.Xn - M) int i = 0; while (++i < 11) { // Mt.Xn double mx00 = m0[0] * x00 + m1[0] * x10 + m2[0] * x20; double mx10 = m0[1] * x00 + m1[1] * x10 + m2[1] * x20; double mx20 = m0[2] * x00 + m1[2] * x10 + m2[2] * x20; double mx01 = m0[0] * x01 + m1[0] * x11 + m2[0] * x21; double mx11 = m0[1] * x01 + m1[1] * x11 + m2[1] * x21; double mx21 = m0[2] * x01 + m1[2] * x11 + m2[2] * x21; double mx02 = m0[0] * x02 + m1[0] * x12 + m2[0] * x22; double mx12 = m0[1] * x02 + m1[1] * x12 + m2[1] * x22; double mx22 = m0[2] * x02 + m1[2] * x12 + m2[2] * x22; // Xn+1 o0[0] = x00 - 0.5 * (x00 * mx00 + x01 * mx10 + x02 * mx20 - m0[0]); o0[1] = x01 - 0.5 * (x00 * mx01 + x01 * mx11 + x02 * mx21 - m0[1]); o0[2] = x02 - 0.5 * (x00 * mx02 + x01 * mx12 + x02 * mx22 - m0[2]); o1[0] = x10 - 0.5 * (x10 * mx00 + x11 * mx10 + x12 * mx20 - m1[0]); o1[1] = x11 - 0.5 * (x10 * mx01 + x11 * mx11 + x12 * mx21 - m1[1]); o1[2] = x12 - 0.5 * (x10 * mx02 + x11 * mx12 + x12 * mx22 - m1[2]); o2[0] = x20 - 0.5 * (x20 * mx00 + x21 * mx10 + x22 * mx20 - m2[0]); o2[1] = x21 - 0.5 * (x20 * mx01 + x21 * mx11 + x22 * mx21 - m2[1]); o2[2] = x22 - 0.5 * (x20 * mx02 + x21 * mx12 + x22 * mx22 - m2[2]); // correction on each elements double corr00 = o0[0] - m0[0]; double corr01 = o0[1] - m0[1]; double corr02 = o0[2] - m0[2]; double corr10 = o1[0] - m1[0]; double corr11 = o1[1] - m1[1]; double corr12 = o1[2] - m1[2]; double corr20 = o2[0] - m2[0]; double corr21 = o2[1] - m2[1]; double corr22 = o2[2] - m2[2]; // Frobenius norm of the correction fn1 = corr00 * corr00 + corr01 * corr01 + corr02 * corr02 + corr10 * corr10 + corr11 * corr11 + corr12 * corr12 + corr20 * corr20 + corr21 * corr21 + corr22 * corr22; // convergence test if (FastMath.abs(fn1 - fn) <= threshold) return o; // prepare next iteration x00 = o0[0]; x01 = o0[1]; x02 = o0[2]; x10 = o1[0]; x11 = o1[1]; x12 = o1[2]; x20 = o2[0]; x21 = o2[1]; x22 = o2[2]; fn = fn1; } // the algorithm did not converge after 10 iterations throw new NotARotationMatrixException( LocalizedFormats.UNABLE_TO_ORTHOGONOLIZE_MATRIX, i - 1); } /** Compute the distance between two rotations. *

                    The distance is intended here as a way to check if two * rotations are almost similar (i.e. they transform vectors the same way) * or very different. It is mathematically defined as the angle of * the rotation r that prepended to one of the rotations gives the other * one:

                    *
                       *        r1(r) = r2
                       * 
                    *

                    This distance is an angle between 0 and π. Its value is the smallest * possible upper bound of the angle in radians between r1(v) * and r2(v) for all possible vectors v. This upper bound is * reached for some v. The distance is equal to 0 if and only if the two * rotations are identical.

                    *

                    Comparing two rotations should always be done using this value rather * than for example comparing the components of the quaternions. It is much * more stable, and has a geometric meaning. Also comparing quaternions * components is error prone since for example quaternions (0.36, 0.48, -0.48, -0.64) * and (-0.36, -0.48, 0.48, 0.64) represent exactly the same rotation despite * their components are different (they are exact opposites).

                    * @param r1 first rotation * @param r2 second rotation * @return distance between r1 and r2 */ public static double distance(Rotation r1, Rotation r2) { return r1.applyInverseTo(r2).getAngle(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ArgumentOutsideDomainException.java100644 1750 1750 3374 11532241247 31346 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a method is called with an out of bounds argument. * * @since 1.2 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class ArgumentOutsideDomainException extends FunctionEvaluationException { /** Serializable version identifier. */ private static final long serialVersionUID = -4965972841162580234L; /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param argument the failing function argument * @param lower lower bound of the domain * @param upper upper bound of the domain */ public ArgumentOutsideDomainException(double argument, double lower, double upper) { super(argument, LocalizedFormats.ARGUMENT_OUTSIDE_DOMAIN, argument, lower, upper); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/DuplicateSampleAbscissaException.java100644 1750 1750 3566 11532241247 31627 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception thrown when a sample contains several entries at the same abscissa. * * @since 1.2 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class DuplicateSampleAbscissaException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -2271007547170169872L; /** * Construct an exception indicating the duplicate abscissa. * @param abscissa duplicate abscissa * @param i1 index of one entry having the duplicate abscissa * @param i2 index of another entry having the duplicate abscissa */ public DuplicateSampleAbscissaException(double abscissa, int i1, int i2) { super(LocalizedFormats.DUPLICATED_ABSCISSA, abscissa, i1, i2); } /** * Get the duplicate abscissa. * @return duplicate abscissa */ public double getDuplicateAbscissa() { return ((Double) getArguments()[0]).doubleValue(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/Field.java100644 1750 1750 3566 11532241247 24246 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; /** * Interface representing a field. *

                    * Classes implementing this interface will often be singletons. *

                    * @param the type of the field elements * @see FieldElement * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface Field { /** Get the additive identity of the field. *

                    * The additive identity is the element e0 of the field such that * for all elements a of the field, the equalities a + e0 = * e0 + a = a hold. *

                    * @return additive identity of the field */ T getZero(); /** Get the multiplicative identity of the field. *

                    * The multiplicative identity is the element e1 of the field such that * for all elements a of the field, the equalities a × e1 = * e1 × a = a hold. *

                    * @return multiplicative identity of the field */ T getOne(); } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleVectorialPointChecker.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleVectorialPointChecker.100644 1750 1750 7076 11532241244 32505 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Simple implementation of the {@link VectorialConvergenceChecker} interface using * only point coordinates. *

                    * Convergence is considered to have been reached if either the relative * difference between each point coordinate are smaller than a threshold * or if either the absolute difference between the point coordinates are * smaller than another threshold. *

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class SimpleVectorialPointChecker implements VectorialConvergenceChecker { /** Default relative threshold. */ private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; /** Default absolute threshold. */ private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; /** Relative tolerance threshold. */ private final double relativeThreshold; /** Absolute tolerance threshold. */ private final double absoluteThreshold; /** Build an instance with default threshold. */ public SimpleVectorialPointChecker() { this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; } /** Build an instance with a specified threshold. *

                    * In order to perform only relative checks, the absolute tolerance * must be set to a negative value. In order to perform only absolute * checks, the relative tolerance must be set to a negative value. *

                    * @param relativeThreshold relative tolerance threshold * @param absoluteThreshold absolute tolerance threshold */ public SimpleVectorialPointChecker(final double relativeThreshold, final double absoluteThreshold) { this.relativeThreshold = relativeThreshold; this.absoluteThreshold = absoluteThreshold; } /** {@inheritDoc} */ public boolean converged(final int iteration, final VectorialPointValuePair previous, final VectorialPointValuePair current) { final double[] p = previous.getPointRef(); final double[] c = current.getPointRef(); for (int i = 0; i < p.length; ++i) { final double pi = p[i]; final double ci = c[i]; final double difference = FastMath.abs(pi - ci); final double size = FastMath.max(FastMath.abs(pi), FastMath.abs(ci)); if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) { return false; } } return true; } } ././@LongLink100644 0 0 177 11532242443 10260 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMult100644 1750 1750 21362 11532241244 32636 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomVectorGenerator; /** * Special implementation of the {@link DifferentiableMultivariateRealOptimizer} interface adding * multi-start features to an existing optimizer. *

                    * This class wraps a classical optimizer to use it several times in * turn with different starting points in order to avoid being trapped * into a local extremum when looking for a global one. *

                    * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class MultiStartDifferentiableMultivariateRealOptimizer implements DifferentiableMultivariateRealOptimizer { /** Underlying classical optimizer. */ private final DifferentiableMultivariateRealOptimizer optimizer; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed for all starts. */ private int totalIterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed for all starts. */ private int totalEvaluations; /** Number of gradient evaluations already performed for all starts. */ private int totalGradientEvaluations; /** Number of starts to go. */ private int starts; /** Random generator for multi-start. */ private RandomVectorGenerator generator; /** Found optima. */ private RealPointValuePair[] optima; /** * Create a multi-start optimizer from a single-start optimizer * @param optimizer single-start optimizer to wrap * @param starts number of starts to perform (including the * first one), multi-start is disabled if value is less than or * equal to 1 * @param generator random vector generator to use for restarts */ public MultiStartDifferentiableMultivariateRealOptimizer(final DifferentiableMultivariateRealOptimizer optimizer, final int starts, final RandomVectorGenerator generator) { this.optimizer = optimizer; this.totalIterations = 0; this.totalEvaluations = 0; this.totalGradientEvaluations = 0; this.starts = starts; this.generator = generator; this.optima = null; setMaxIterations(Integer.MAX_VALUE); setMaxEvaluations(Integer.MAX_VALUE); } /** Get all the optima found during the last call to {@link * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) * optimize}. *

                    The optimizer stores all the optima found during a set of * restarts. The {@link #optimize(DifferentiableMultivariateRealFunction, * GoalType, double[]) optimize} method returns the best point only. This * method returns all the points found at the end of each starts, * including the best one already returned by the {@link * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) * optimize} method. *

                    *

                    * The returned array as one element for each start as specified * in the constructor. It is ordered with the results from the * runs that did converge first, sorted from best to worst * objective value (i.e in ascending order if minimizing and in * descending order if maximizing), followed by and null elements * corresponding to the runs that did not converge. This means all * elements will be null if the {@link #optimize(DifferentiableMultivariateRealFunction, * GoalType, double[]) optimize} method did throw a {@link * org.apache.commons.math.ConvergenceException ConvergenceException}). * This also means that if the first element is non null, it is the best * point found across all starts.

                    * @return array containing the optima * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateRealFunction, * GoalType, double[]) optimize} has not been called */ public RealPointValuePair[] getOptima() throws IllegalStateException { if (optima == null) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET); } return optima.clone(); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return totalIterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return totalEvaluations; } /** {@inheritDoc} */ public int getGradientEvaluations() { return totalGradientEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(RealConvergenceChecker checker) { optimizer.setConvergenceChecker(checker); } /** {@inheritDoc} */ public RealConvergenceChecker getConvergenceChecker() { return optimizer.getConvergenceChecker(); } /** {@inheritDoc} */ public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, final GoalType goalType, double[] startPoint) throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException { optima = new RealPointValuePair[starts]; totalIterations = 0; totalEvaluations = 0; totalGradientEvaluations = 0; // multi-start loop for (int i = 0; i < starts; ++i) { try { optimizer.setMaxIterations(maxIterations - totalIterations); optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); optima[i] = optimizer.optimize(f, goalType, (i == 0) ? startPoint : generator.nextVector()); } catch (FunctionEvaluationException fee) { optima[i] = null; } catch (OptimizationException oe) { optima[i] = null; } totalIterations += optimizer.getIterations(); totalEvaluations += optimizer.getEvaluations(); totalGradientEvaluations += optimizer.getGradientEvaluations(); } // sort the optima from best to worst, followed by null elements Arrays.sort(optima, new Comparator() { public int compare(final RealPointValuePair o1, final RealPointValuePair o2) { if (o1 == null) { return (o2 == null) ? 0 : +1; } else if (o2 == null) { return -1; } final double v1 = o1.getValue(); final double v2 = o2.getValue(); return (goalType == GoalType.MINIMIZE) ? Double.compare(v1, v2) : Double.compare(v2, v1); } }); if (optima[0] == null) { throw new OptimizationException( LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, starts); } // return the found point given the best objective function value return optima[0]; } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleScalarValueChecker.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleScalarValueChecker.jav100644 1750 1750 6516 11532241244 32444 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Simple implementation of the {@link RealConvergenceChecker} interface using * only objective function values. *

                    * Convergence is considered to have been reached if either the relative * difference between the objective function values is smaller than a * threshold or if either the absolute difference between the objective * function values is smaller than another threshold. *

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class SimpleScalarValueChecker implements RealConvergenceChecker { /** Default relative threshold. */ private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; /** Default absolute threshold. */ private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; /** Relative tolerance threshold. */ private final double relativeThreshold; /** Absolute tolerance threshold. */ private final double absoluteThreshold; /** Build an instance with default threshold. */ public SimpleScalarValueChecker() { this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; } /** Build an instance with a specified threshold. *

                    * In order to perform only relative checks, the absolute tolerance * must be set to a negative value. In order to perform only absolute * checks, the relative tolerance must be set to a negative value. *

                    * @param relativeThreshold relative tolerance threshold * @param absoluteThreshold absolute tolerance threshold */ public SimpleScalarValueChecker(final double relativeThreshold, final double absoluteThreshold) { this.relativeThreshold = relativeThreshold; this.absoluteThreshold = absoluteThreshold; } /** {@inheritDoc} */ public boolean converged(final int iteration, final RealPointValuePair previous, final RealPointValuePair current) { final double p = previous.getValue(); final double c = current.getValue(); final double difference = FastMath.abs(p - c); final double size = FastMath.max(FastMath.abs(p), FastMath.abs(c)); return (difference <= (size * relativeThreshold)) || (difference <= absoluteThreshold); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/BrentOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/BrentOptimizer.ja100644 1750 1750 17466 11532241244 32567 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.univariate; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.util.FastMath; /** * Implements Richard Brent's algorithm (from his book "Algorithms for * Minimization without Derivatives", p. 79) for finding minima of real * univariate functions. This implementation is an adaptation partly * based on the Python code from SciPy (module "optimize.py" v0.5). * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public class BrentOptimizer extends AbstractUnivariateRealOptimizer { /** * Golden section. */ private static final double GOLDEN_SECTION = 0.5 * (3 - FastMath.sqrt(5)); /** * Construct a solver. */ public BrentOptimizer() { setMaxEvaluations(1000); setMaximalIterationCount(100); setAbsoluteAccuracy(1e-11); setRelativeAccuracy(1e-9); } /** {@inheritDoc} */ @Override protected double doOptimize() throws MaxIterationsExceededException, FunctionEvaluationException { return localMin(getGoalType() == GoalType.MINIMIZE, getMin(), getStartValue(), getMax(), getRelativeAccuracy(), getAbsoluteAccuracy()); } /** * Find the minimum of the function within the interval {@code (lo, hi)}. * * If the function is defined on the interval {@code (lo, hi)}, then * this method finds an approximation {@code x} to the point at which * the function attains its minimum.
                    * {@code t} and {@code eps} define a tolerance {@code tol = eps |x| + t} * and the function is never evaluated at two points closer together than * {@code tol}. {@code eps} should be no smaller than 2 macheps and * preferable not much less than sqrt(macheps), where * macheps is the relative machine precision. {@code t} should be * positive. * @param isMinim {@code true} when minimizing the function. * @param lo Lower bound of the interval. * @param mid Point inside the interval {@code [lo, hi]}. * @param hi Higher bound of the interval. * @param eps Relative accuracy. * @param t Absolute accuracy. * @return the optimum point. * @throws MaxIterationsExceededException if the maximum iteration count * is exceeded. * @throws FunctionEvaluationException if an error occurs evaluating the function. */ private double localMin(boolean isMinim, double lo, double mid, double hi, double eps, double t) throws MaxIterationsExceededException, FunctionEvaluationException { if (eps <= 0) { throw new NotStrictlyPositiveException(eps); } if (t <= 0) { throw new NotStrictlyPositiveException(t); } double a; double b; if (lo < hi) { a = lo; b = hi; } else { a = hi; b = lo; } double x = mid; double v = x; double w = x; double d = 0; double e = 0; double fx = computeObjectiveValue(x); if (!isMinim) { fx = -fx; } double fv = fx; double fw = fx; while (true) { double m = 0.5 * (a + b); final double tol1 = eps * FastMath.abs(x) + t; final double tol2 = 2 * tol1; // Check stopping criterion. if (FastMath.abs(x - m) > tol2 - 0.5 * (b - a)) { double p = 0; double q = 0; double r = 0; double u = 0; if (FastMath.abs(e) > tol1) { // Fit parabola. r = (x - w) * (fx - fv); q = (x - v) * (fx - fw); p = (x - v) * q - (x - w) * r; q = 2 * (q - r); if (q > 0) { p = -p; } else { q = -q; } r = e; e = d; if (p > q * (a - x) && p < q * (b - x) && FastMath.abs(p) < FastMath.abs(0.5 * q * r)) { // Parabolic interpolation step. d = p / q; u = x + d; // f must not be evaluated too close to a or b. if (u - a < tol2 || b - u < tol2) { if (x <= m) { d = tol1; } else { d = -tol1; } } } else { // Golden section step. if (x < m) { e = b - x; } else { e = a - x; } d = GOLDEN_SECTION * e; } } else { // Golden section step. if (x < m) { e = b - x; } else { e = a - x; } d = GOLDEN_SECTION * e; } // Update by at least "tol1". if (FastMath.abs(d) < tol1) { if (d >= 0) { u = x + tol1; } else { u = x - tol1; } } else { u = x + d; } double fu = computeObjectiveValue(u); if (!isMinim) { fu = -fu; } // Update a, b, v, w and x. if (fu <= fx) { if (u < x) { b = x; } else { a = x; } v = w; fv = fw; w = x; fw = fx; x = u; fx = fu; } else { if (u < x) { a = u; } else { b = u; } if (fu <= fw || w == x) { v = w; fv = fw; w = u; fw = fu; } else if (fu <= fv || v == x || v == w) { v = u; fv = fu; } } } else { // termination setFunctionValue(isMinim ? fx : -fx); return x; } incrementIterationsCounter(); } } } ././@LongLink100644 0 0 170 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/AbstractUnivariat100644 1750 1750 22554 11532241244 32641 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.univariate; import org.apache.commons.math.ConvergingAlgorithmImpl; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.MathUnsupportedOperationException; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.UnivariateRealOptimizer; /** * Provide a default implementation for several functions useful to generic * optimizers. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public abstract class AbstractUnivariateRealOptimizer extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer { /** Indicates where a root has been computed. */ protected boolean resultComputed; /** The last computed root. */ protected double result; /** Value of the function at the last computed result. */ protected double functionValue; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Optimization type */ private GoalType optimizationGoal; /** Lower end of search interval. */ private double searchMin; /** Higher end of search interval. */ private double searchMax; /** Initial guess . */ private double searchStart; /** Function to optimize. */ private UnivariateRealFunction function; /** * Construct a solver with given iteration count and accuracy. * @param defaultAbsoluteAccuracy maximum absolute error * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the * defaultAbsoluteAccuracy is not valid * @deprecated in 2.2. Please use the "setter" methods to assign meaningful * values to the maximum numbers of iterations and evaluations, and to the * absolute and relative accuracy thresholds. */ @Deprecated protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount, final double defaultAbsoluteAccuracy) { super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); resultComputed = false; setMaxEvaluations(Integer.MAX_VALUE); } /** * Default constructor. * To be removed once the single non-default one has been removed. */ protected AbstractUnivariateRealOptimizer() {} /** * Check whether a result has been computed. * @throws NoDataException if no result has been computed * @deprecated in 2.2 (no alternative). */ @Deprecated protected void checkResultComputed() { if (!resultComputed) { throw new NoDataException(); } } /** {@inheritDoc} */ public double getResult() { if (!resultComputed) { throw new NoDataException(); } return result; } /** {@inheritDoc} */ public double getFunctionValue() throws FunctionEvaluationException { if (Double.isNaN(functionValue)) { final double opt = getResult(); functionValue = function.value(opt); } return functionValue; } /** * Convenience function for implementations. * * @param x the result to set * @param fx the result to set * @param iterationCount the iteration count to set * @deprecated in 2.2 (no alternative). */ @Deprecated protected final void setResult(final double x, final double fx, final int iterationCount) { this.result = x; this.functionValue = fx; this.iterationCount = iterationCount; this.resultComputed = true; } /** * Convenience function for implementations. * @deprecated in 2.2 (no alternative). */ @Deprecated protected final void clearResult() { this.resultComputed = false; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return evaluations; } /** * @return the optimization type. */ public GoalType getGoalType() { return optimizationGoal; } /** * @return the lower of the search interval. */ public double getMin() { return searchMin; } /** * @return the higher of the search interval. */ public double getMax() { return searchMax; } /** * @return the initial guess. */ public double getStartValue() { return searchStart; } /** * Compute the objective function value. * @param f objective function * @param point point at which the objective function must be evaluated * @return objective function value at specified point * @exception FunctionEvaluationException if the function cannot be evaluated * or the maximal number of iterations is exceeded * @deprecated in 2.2. Use this {@link #computeObjectiveValue(double) * replacement} instead. */ @Deprecated protected double computeObjectiveValue(final UnivariateRealFunction f, final double point) throws FunctionEvaluationException { if (++evaluations > maxEvaluations) { throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point); } return f.value(point); } /** * Compute the objective function value. * * @param point Point at which the objective function must be evaluated. * @return the objective function value at specified point. * @exception FunctionEvaluationException if the function cannot be evaluated * or the maximal number of iterations is exceeded. */ protected double computeObjectiveValue(double point) throws FunctionEvaluationException { if (++evaluations > maxEvaluations) { resultComputed = false; throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point); } return function.value(point); } /** {@inheritDoc} */ public double optimize(UnivariateRealFunction f, GoalType goal, double min, double max, double startValue) throws MaxIterationsExceededException, FunctionEvaluationException { // Initialize. this.searchMin = min; this.searchMax = max; this.searchStart = startValue; this.optimizationGoal = goal; this.function = f; // Reset. functionValue = Double.NaN; evaluations = 0; resetIterationsCounter(); // Perform computation. result = doOptimize(); resultComputed = true; return result; } /** * Set the value at the optimum. * * @param functionValue Value of the objective function at the optimum. */ protected void setFunctionValue(double functionValue) { this.functionValue = functionValue; } /** {@inheritDoc} */ public double optimize(UnivariateRealFunction f, GoalType goal, double min, double max) throws MaxIterationsExceededException, FunctionEvaluationException { return optimize(f, goal, min, max, min + 0.5 * (max - min)); } /** * Method for implementing actual optimization algorithms in derived * classes. * * From version 3.0 onwards, this method will be abstract - i.e. * concrete implementations will have to implement it. If this method * is not implemented, subclasses must override * {@link #optimize(UnivariateRealFunction, GoalType, double, double)}. * * @return the optimum. * @throws MaxIterationsExceededException if the maximum iteration count * is exceeded. * @throws FunctionEvaluationException if an error occurs evaluating * the function. */ protected double doOptimize() throws MaxIterationsExceededException, FunctionEvaluationException { throw new MathUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/package.html100644 1750 1750 1727 11532241244 31530 0ustarlucluc 0 0 Univariate real functions minimum finding algorithms. ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/BracketFinder.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/univariate/BracketFinder.jav100644 1750 1750 17560 11532241244 32476 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.univariate; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.optimization.GoalType; /** * Provide an interval that brackets a local optimum of a function. * This code is based on a Python implementation (from SciPy, * module {@code optimize.py} v0.5). * @version $Revision$ $Date$ * @since 2.2 */ public class BracketFinder { /** Tolerance to avoid division by zero. */ private static final double EPS_MIN = 1e-21; /** * Golden section. */ private static final double GOLD = 1.618034; /** * Factor for expanding the interval. */ private final double growLimit; /** * Maximum number of iterations. */ private final int maxIterations; /** * Number of iterations. */ private int iterations; /** * Number of function evaluations. */ private int evaluations; /** * Lower bound of the bracket. */ private double lo; /** * Higher bound of the bracket. */ private double hi; /** * Point inside the bracket. */ private double mid; /** * Function value at {@link #lo}. */ private double fLo; /** * Function value at {@link #hi}. */ private double fHi; /** * Function value at {@link #mid}. */ private double fMid; /** * Constructor with default values {@code 100, 50} (see the * {@link #BracketFinder(double,int) other constructor}). */ public BracketFinder() { this(100, 50); } /** * Create a bracketing interval finder. * * @param growLimit Expanding factor. * @param maxIterations Maximum number of iterations allowed for finding * a bracketing interval. */ public BracketFinder(double growLimit, int maxIterations) { if (growLimit <= 0) { throw new NotStrictlyPositiveException(growLimit); } if (maxIterations <= 0) { throw new NotStrictlyPositiveException(maxIterations); } this.growLimit = growLimit; this.maxIterations = maxIterations; } /** * Search new points that bracket a local optimum of the function. * * @param func Function whose optimum should be bracketted. * @param goal {@link GoalType Goal type}. * @param xA Initial point. * @param xB Initial point. * @throws MaxIterationsExceededException if the maximum iteration count * is exceeded. * @throws FunctionEvaluationException if an error occurs evaluating the function. */ public void search(UnivariateRealFunction func, GoalType goal, double xA, double xB) throws MaxIterationsExceededException, FunctionEvaluationException { reset(); final boolean isMinim = goal == GoalType.MINIMIZE; double fA = eval(func, xA); double fB = eval(func, xB); if (isMinim ? fA < fB : fA > fB) { double tmp = xA; xA = xB; xB = tmp; tmp = fA; fA = fB; fB = tmp; } double xC = xB + GOLD * (xB - xA); double fC = eval(func, xC); while (isMinim ? fC < fB : fC > fB) { if (++iterations > maxIterations) { throw new MaxIterationsExceededException(maxIterations); } double tmp1 = (xB - xA) * (fB - fC); double tmp2 = (xB - xC) * (fB - fA); double val = tmp2 - tmp1; double denom = Math.abs(val) < EPS_MIN ? 2 * EPS_MIN : 2 * val; double w = xB - ((xB - xC) * tmp2 - (xB -xA) * tmp1) / denom; double wLim = xB + growLimit * (xC - xB); double fW; if ((w - xC) * (xB - w) > 0) { fW = eval(func, w); if (isMinim ? fW < fC : fW > fC) { xA = xB; xB = w; fA = fB; fB = fW; break; } else if (isMinim ? fW > fB : fW < fB) { xC = w; fC = fW; break; } w = xC + GOLD * (xC - xB); fW = eval(func, w); } else if ((w - wLim) * (wLim - xC) >= 0) { w = wLim; fW = eval(func, w); } else if ((w - wLim) * (xC - w) > 0) { fW = eval(func, w); if (isMinim ? fW < fC : fW > fC) { xB = xC; xC = w; w = xC + GOLD * (xC -xB); fB = fC; fC =fW; fW = eval(func, w); } } else { w = xC + GOLD * (xC - xB); fW = eval(func, w); } xA = xB; xB = xC; xC = w; fA = fB; fB = fC; fC = fW; } lo = xA; mid = xB; hi = xC; fLo = fA; fMid = fB; fHi = fC; } /** * @return the number of iterations. */ public int getIterations() { return iterations; } /** * @return the number of evaluations. */ public int getEvaluations() { return evaluations; } /** * @return the lower bound of the bracket. * @see #getFLow() */ public double getLo() { return lo; } /** * Get function value at {@link #getLo()}. * @return function value at {@link #getLo()} */ public double getFLow() { return fLo; } /** * @return the higher bound of the bracket. * @see #getFHi() */ public double getHi() { return hi; } /** * Get function value at {@link #getHi()}. * @return function value at {@link #getHi()} */ public double getFHi() { return fHi; } /** * @return a point in the middle of the bracket. * @see #getFMid() */ public double getMid() { return mid; } /** * Get function value at {@link #getMid()}. * @return function value at {@link #getMid()} */ public double getFMid() { return fMid; } /** * @param f Function. * @param x Argument. * @return {@code f(x)} * @throws FunctionEvaluationException if function cannot be evaluated at x */ private double eval(UnivariateRealFunction f, double x) throws FunctionEvaluationException { ++evaluations; return f.value(x); } /** * Reset internal state. */ private void reset() { iterations = 0; evaluations = 0; } } ././@LongLink100644 0 0 165 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateRe100644 1750 1750 10711 11532241244 32615 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; /** * This interface represents an optimization algorithm for * {@link DifferentiableMultivariateRealFunction scalar differentiable objective * functions}. * Optimization algorithms find the input point set that either {@link GoalType * maximize or minimize} an objective function. * * @see MultivariateRealOptimizer * @see DifferentiableMultivariateVectorialOptimizer * @version $Revision: 1065484 $ $Date: 2011-01-31 06:45:14 +0100 (lun. 31 janv. 2011) $ * @since 2.0 */ public interface DifferentiableMultivariateRealOptimizer { /** Set the maximal number of iterations of the algorithm. * @param maxIterations maximal number of function calls */ void setMaxIterations(int maxIterations); /** Get the maximal number of iterations of the algorithm. * @return maximal number of iterations */ int getMaxIterations(); /** Get the number of iterations realized by the algorithm. *

                    * The number of evaluations corresponds to the last call to the * {@code optimize} method. It is 0 if the method has not been called yet. *

                    * @return number of iterations */ int getIterations(); /** Set the maximal number of functions evaluations. * @param maxEvaluations maximal number of function evaluations */ void setMaxEvaluations(int maxEvaluations); /** Get the maximal number of functions evaluations. * @return maximal number of functions evaluations */ int getMaxEvaluations(); /** Get the number of evaluations of the objective function. *

                    * The number of evaluations corresponds to the last call to the * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize} * method. It is 0 if the method has not been called yet. *

                    * @return number of evaluations of the objective function */ int getEvaluations(); /** Get the number of evaluations of the objective function gradient. *

                    * The number of evaluations corresponds to the last call to the * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize} * method. It is 0 if the method has not been called yet. *

                    * @return number of evaluations of the objective function gradient */ int getGradientEvaluations(); /** Set the convergence checker. * @param checker object to use to check for convergence */ void setConvergenceChecker(RealConvergenceChecker checker); /** Get the convergence checker. * @return object used to check for convergence */ RealConvergenceChecker getConvergenceChecker(); /** Optimizes an objective function. * @param f objective function * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE} * @param startPoint the start point for optimization * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ RealPointValuePair optimize(DifferentiableMultivariateRealFunction f, GoalType goalType, double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/WeightedObservedPoin100644 1750 1750 4613 11532241244 32544 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.io.Serializable; /** This class is a simple container for weighted observed point in * {@link CurveFitter curve fitting}. *

                    Instances of this class are guaranteed to be immutable.

                    * @version $Revision: 786479 $ $Date: 2009-06-19 14:36:16 +0200 (ven. 19 juin 2009) $ * @since 2.0 */ public class WeightedObservedPoint implements Serializable { /** Serializable version id. */ private static final long serialVersionUID = 5306874947404636157L; /** Weight of the measurement in the fitting process. */ private final double weight; /** Abscissa of the point. */ private final double x; /** Observed value of the function at x. */ private final double y; /** Simple constructor. * @param weight weight of the measurement in the fitting process * @param x abscissa of the measurement * @param y ordinate of the measurement */ public WeightedObservedPoint(final double weight, final double x, final double y) { this.weight = weight; this.x = x; this.y = y; } /** Get the weight of the measurement in the fitting process. * @return weight of the measurement in the fitting process */ public double getWeight() { return weight; } /** Get the abscissa of the point. * @return abscissa of the point */ public double getX() { return x; } /** Get the observed value of the function at x. * @return observed value of the function at x */ public double getY() { return y; } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFunction.jav100644 1750 1750 11164 11532241244 32542 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.io.Serializable; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.exception.NullArgumentException; /** * A Gaussian function. Specifically: *

                    * f(x) = a + b*exp(-((x - c)^2 / (2*d^2))) *

                    * Notation key: *

                      *
                    • x^n: x raised to the power of n *
                    • exp(x): e^x *
                    * References: * * * @see GaussianDerivativeFunction * @see ParametricGaussianFunction * @since 2.2 * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class GaussianFunction implements DifferentiableUnivariateRealFunction, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -3195385616125629512L; /** Parameter a of this function. */ private final double a; /** Parameter b of this function. */ private final double b; /** Parameter c of this function. */ private final double c; /** Parameter d of this function. */ private final double d; /** * Constructs an instance with the specified parameters. * * @param a a parameter value * @param b b parameter value * @param c c parameter value * @param d d parameter value * * @throws IllegalArgumentException if d is 0 */ public GaussianFunction(double a, double b, double c, double d) { if (d == 0.0) { throw new ZeroException(); } this.a = a; this.b = b; this.c = c; this.d = d; } /** * Constructs an instance with the specified parameters. * * @param parameters a, b, c, and d * parameter values * * @throws IllegalArgumentException if parameters is null, * parameters length is not 4, or if * parameters[3] is 0 */ public GaussianFunction(double[] parameters) { if (parameters == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (parameters.length != 4) { throw new DimensionMismatchException(4, parameters.length); } if (parameters[3] == 0.0) { throw new ZeroException(); } this.a = parameters[0]; this.b = parameters[1]; this.c = parameters[2]; this.d = parameters[3]; } /** {@inheritDoc} */ public UnivariateRealFunction derivative() { return new GaussianDerivativeFunction(b, c, d); } /** {@inheritDoc} */ public double value(double x) { final double xMc = x - c; return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d))); } /** * Gets a parameter value. * * @return a parameter value */ public double getA() { return a; } /** * Gets b parameter value. * * @return b parameter value */ public double getB() { return b; } /** * Gets c parameter value. * * @return c parameter value */ public double getC() { return c; } /** * Gets d parameter value. * * @return d parameter value */ public double getD() { return d; } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/PolynomialFitter.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/PolynomialFitter.jav100644 1750 1750 7731 11532241244 32550 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.OptimizationException; /** This class implements a curve fitting specialized for polynomials. *

                    Polynomial fitting is a very simple case of curve fitting. The * estimated coefficients are the polynomial coefficients. They are * searched by a least square estimator.

                    * @version $Revision: 1073270 $ $Date: 2011-02-22 10:19:27 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public class PolynomialFitter { /** Fitter for the coefficients. */ private final CurveFitter fitter; /** Polynomial degree. */ private final int degree; /** Simple constructor. *

                    The polynomial fitter built this way are complete polynomials, * ie. a n-degree polynomial has n+1 coefficients.

                    * @param degree maximal degree of the polynomial * @param optimizer optimizer to use for the fitting */ public PolynomialFitter(int degree, final DifferentiableMultivariateVectorialOptimizer optimizer) { this.fitter = new CurveFitter(optimizer); this.degree = degree; } /** Add an observed weighted (x,y) point to the sample. * @param weight weight of the observed point in the fit * @param x abscissa of the point * @param y observed value of the point at x, after fitting we should * have P(x) as close as possible to this value */ public void addObservedPoint(double weight, double x, double y) { fitter.addObservedPoint(weight, x, y); } /** * Remove all observations. * @since 2.2 */ public void clearObservations() { fitter.clearObservations(); } /** Get the polynomial fitting the weighted (x, y) points. * @return polynomial function best fitting the observed points * @exception OptimizationException if the algorithm failed to converge */ public PolynomialFunction fit() throws OptimizationException { try { return new PolynomialFunction(fitter.fit(new ParametricPolynomial(), new double[degree + 1])); } catch (FunctionEvaluationException fee) { // should never happen throw new RuntimeException(fee); } } /** Dedicated parametric polynomial class. */ private static class ParametricPolynomial implements ParametricRealFunction { /** {@inheritDoc} */ public double[] gradient(double x, double[] parameters) { final double[] gradient = new double[parameters.length]; double xn = 1.0; for (int i = 0; i < parameters.length; ++i) { gradient[i] = xn; xn *= x; } return gradient; } /** {@inheritDoc} */ public double value(final double x, final double[] parameters) { double y = 0; for (int i = parameters.length - 1; i >= 0; --i) { y = y * x + parameters[i]; } return y; } } } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicCoefficients100644 1750 1750 26551 11532241244 32573 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.util.FastMath; /** This class guesses harmonic coefficients from a sample. *

                    The algorithm used to guess the coefficients is as follows:

                    *

                    We know f (t) at some sampling points ti and want to find a, * ω and φ such that f (t) = a cos (ω t + φ). *

                    * *

                    From the analytical expression, we can compute two primitives : *

                     *     If2  (t) = ∫ f2  = a2 × [t + S (t)] / 2
                     *     If'2 (t) = ∫ f'2 = a2 ω2 × [t - S (t)] / 2
                     *     where S (t) = sin (2 (ω t + φ)) / (2 ω)
                     * 
                    *

                    * *

                    We can remove S between these expressions : *

                     *     If'2 (t) = a2 ω2 t - ω2 If2 (t)
                     * 
                    *

                    * *

                    The preceding expression shows that If'2 (t) is a linear * combination of both t and If2 (t): If'2 (t) = A × t + B × If2 (t) *

                    * *

                    From the primitive, we can deduce the same form for definite * integrals between t1 and ti for each ti : *

                     *   If2 (ti) - If2 (t1) = A × (ti - t1) + B × (If2 (ti) - If2 (t1))
                     * 
                    *

                    * *

                    We can find the coefficients A and B that best fit the sample * to this linear expression by computing the definite integrals for * each sample points. *

                    * *

                    For a bilinear expression z (xi, yi) = A × xi + B × yi, the * coefficients A and B that minimize a least square criterion * ∑ (zi - z (xi, yi))2 are given by these expressions:

                    *
                     *
                     *         ∑yiyi ∑xizi - ∑xiyi ∑yizi
                     *     A = ------------------------
                     *         ∑xixi ∑yiyi - ∑xiyi ∑xiyi
                     *
                     *         ∑xixi ∑yizi - ∑xiyi ∑xizi
                     *     B = ------------------------
                     *         ∑xixi ∑yiyi - ∑xiyi ∑xiyi
                     * 
                    *

                    * * *

                    In fact, we can assume both a and ω are positive and * compute them directly, knowing that A = a2 ω2 and that * B = - ω2. The complete algorithm is therefore:

                    *
                     *
                     * for each ti from t1 to tn-1, compute:
                     *   f  (ti)
                     *   f' (ti) = (f (ti+1) - f(ti-1)) / (ti+1 - ti-1)
                     *   xi = ti - t1
                     *   yi = ∫ f2 from t1 to ti
                     *   zi = ∫ f'2 from t1 to ti
                     *   update the sums ∑xixi, ∑yiyi, ∑xiyi, ∑xizi and ∑yizi
                     * end for
                     *
                     *            |--------------------------
                     *         \  | ∑yiyi ∑xizi - ∑xiyi ∑yizi
                     * a     =  \ | ------------------------
                     *           \| ∑xiyi ∑xizi - ∑xixi ∑yizi
                     *
                     *
                     *            |--------------------------
                     *         \  | ∑xiyi ∑xizi - ∑xixi ∑yizi
                     * ω     =  \ | ------------------------
                     *           \| ∑xixi ∑yiyi - ∑xiyi ∑xiyi
                     *
                     * 
                    *

                    *

                    Once we know ω, we can compute: *

                     *    fc = ω f (t) cos (ω t) - f' (t) sin (ω t)
                     *    fs = ω f (t) sin (ω t) + f' (t) cos (ω t)
                     * 
                    *

                    *

                    It appears that fc = a ω cos (φ) and * fs = -a ω sin (φ), so we can use these * expressions to compute φ. The best estimate over the sample is * given by averaging these expressions. *

                    *

                    Since integrals and means are involved in the preceding * estimations, these operations run in O(n) time, where n is the * number of measurements.

                    * @version $Revision: 1056034 $ $Date: 2011-01-06 20:41:43 +0100 (jeu. 06 janv. 2011) $ * @since 2.0 */ public class HarmonicCoefficientsGuesser { /** Sampled observations. */ private final WeightedObservedPoint[] observations; /** Guessed amplitude. */ private double a; /** Guessed pulsation ω. */ private double omega; /** Guessed phase φ. */ private double phi; /** Simple constructor. * @param observations sampled observations */ public HarmonicCoefficientsGuesser(WeightedObservedPoint[] observations) { this.observations = observations.clone(); a = Double.NaN; omega = Double.NaN; } /** Estimate a first guess of the coefficients. * @exception OptimizationException if the sample is too short or if * the first guess cannot be computed (when the elements under the * square roots are negative). * */ public void guess() throws OptimizationException { sortObservations(); guessAOmega(); guessPhi(); } /** Sort the observations with respect to the abscissa. */ private void sortObservations() { // Since the samples are almost always already sorted, this // method is implemented as an insertion sort that reorders the // elements in place. Insertion sort is very efficient in this case. WeightedObservedPoint curr = observations[0]; for (int j = 1; j < observations.length; ++j) { WeightedObservedPoint prec = curr; curr = observations[j]; if (curr.getX() < prec.getX()) { // the current element should be inserted closer to the beginning int i = j - 1; WeightedObservedPoint mI = observations[i]; while ((i >= 0) && (curr.getX() < mI.getX())) { observations[i + 1] = mI; if (i-- != 0) { mI = observations[i]; } } observations[i + 1] = curr; curr = observations[j]; } } } /** Estimate a first guess of the a and ω coefficients. * @exception OptimizationException if the sample is too short or if * the first guess cannot be computed (when the elements under the * square roots are negative). */ private void guessAOmega() throws OptimizationException { // initialize the sums for the linear model between the two integrals double sx2 = 0.0; double sy2 = 0.0; double sxy = 0.0; double sxz = 0.0; double syz = 0.0; double currentX = observations[0].getX(); double currentY = observations[0].getY(); double f2Integral = 0; double fPrime2Integral = 0; final double startX = currentX; for (int i = 1; i < observations.length; ++i) { // one step forward final double previousX = currentX; final double previousY = currentY; currentX = observations[i].getX(); currentY = observations[i].getY(); // update the integrals of f2 and f'2 // considering a linear model for f (and therefore constant f') final double dx = currentX - previousX; final double dy = currentY - previousY; final double f2StepIntegral = dx * (previousY * previousY + previousY * currentY + currentY * currentY) / 3; final double fPrime2StepIntegral = dy * dy / dx; final double x = currentX - startX; f2Integral += f2StepIntegral; fPrime2Integral += fPrime2StepIntegral; sx2 += x * x; sy2 += f2Integral * f2Integral; sxy += x * f2Integral; sxz += x * fPrime2Integral; syz += f2Integral * fPrime2Integral; } // compute the amplitude and pulsation coefficients double c1 = sy2 * sxz - sxy * syz; double c2 = sxy * sxz - sx2 * syz; double c3 = sx2 * sy2 - sxy * sxy; if ((c1 / c2 < 0.0) || (c2 / c3 < 0.0)) { throw new OptimizationException(LocalizedFormats.UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS); } a = FastMath.sqrt(c1 / c2); omega = FastMath.sqrt(c2 / c3); } /** Estimate a first guess of the φ coefficient. */ private void guessPhi() { // initialize the means double fcMean = 0.0; double fsMean = 0.0; double currentX = observations[0].getX(); double currentY = observations[0].getY(); for (int i = 1; i < observations.length; ++i) { // one step forward final double previousX = currentX; final double previousY = currentY; currentX = observations[i].getX(); currentY = observations[i].getY(); final double currentYPrime = (currentY - previousY) / (currentX - previousX); double omegaX = omega * currentX; double cosine = FastMath.cos(omegaX); double sine = FastMath.sin(omegaX); fcMean += omega * currentY * cosine - currentYPrime * sine; fsMean += omega * currentY * sine + currentYPrime * cosine; } phi = FastMath.atan2(-fsMean, fcMean); } /** Get the guessed amplitude a. * @return guessed amplitude a; */ public double getGuessedAmplitude() { return a; } /** Get the guessed pulsation ω. * @return guessed pulsation ω */ public double getGuessedPulsation() { return omega; } /** Get the guessed phase φ. * @return guessed phase φ */ public double getGuessedPhase() { return phi; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java100644 1750 1750 16765 11532241244 31701 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.VectorialPointValuePair; /** Fitter for parametric univariate real functions y = f(x). *

                    When a univariate real function y = f(x) does depend on some * unknown parameters p0, p1 ... pn-1, * this class can be used to find these parameters. It does this * by fitting the curve so it remains very close to a set of * observed points (x0, y0), (x1, * y1) ... (xk-1, yk-1). This fitting * is done by finding the parameters values that minimizes the objective * function ∑(yi-f(xi))2. This is * really a least squares problem.

                    * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class CurveFitter { /** Optimizer to use for the fitting. */ private final DifferentiableMultivariateVectorialOptimizer optimizer; /** Observed points. */ private final List observations; /** Simple constructor. * @param optimizer optimizer to use for the fitting */ public CurveFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) { this.optimizer = optimizer; observations = new ArrayList(); } /** Add an observed (x,y) point to the sample with unit weight. *

                    Calling this method is equivalent to call * addObservedPoint(1.0, x, y).

                    * @param x abscissa of the point * @param y observed value of the point at x, after fitting we should * have f(x) as close as possible to this value * @see #addObservedPoint(double, double, double) * @see #addObservedPoint(WeightedObservedPoint) * @see #getObservations() */ public void addObservedPoint(double x, double y) { addObservedPoint(1.0, x, y); } /** Add an observed weighted (x,y) point to the sample. * @param weight weight of the observed point in the fit * @param x abscissa of the point * @param y observed value of the point at x, after fitting we should * have f(x) as close as possible to this value * @see #addObservedPoint(double, double) * @see #addObservedPoint(WeightedObservedPoint) * @see #getObservations() */ public void addObservedPoint(double weight, double x, double y) { observations.add(new WeightedObservedPoint(weight, x, y)); } /** Add an observed weighted (x,y) point to the sample. * @param observed observed point to add * @see #addObservedPoint(double, double) * @see #addObservedPoint(double, double, double) * @see #getObservations() */ public void addObservedPoint(WeightedObservedPoint observed) { observations.add(observed); } /** Get the observed points. * @return observed points * @see #addObservedPoint(double, double) * @see #addObservedPoint(double, double, double) * @see #addObservedPoint(WeightedObservedPoint) */ public WeightedObservedPoint[] getObservations() { return observations.toArray(new WeightedObservedPoint[observations.size()]); } /** * Remove all observations. */ public void clearObservations() { observations.clear(); } /** Fit a curve. *

                    This method compute the coefficients of the curve that best * fit the sample of observed points previously given through calls * to the {@link #addObservedPoint(WeightedObservedPoint) * addObservedPoint} method.

                    * @param f parametric function to fit * @param initialGuess first guess of the function parameters * @return fitted parameters * @exception FunctionEvaluationException if the objective function throws one during the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ public double[] fit(final ParametricRealFunction f, final double[] initialGuess) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { // prepare least squares problem double[] target = new double[observations.size()]; double[] weights = new double[observations.size()]; int i = 0; for (WeightedObservedPoint point : observations) { target[i] = point.getY(); weights[i] = point.getWeight(); ++i; } // perform the fit VectorialPointValuePair optimum = optimizer.optimize(new TheoreticalValuesFunction(f), target, weights, initialGuess); // extract the coefficients return optimum.getPointRef(); } /** Vectorial function computing function theoretical values. */ private class TheoreticalValuesFunction implements DifferentiableMultivariateVectorialFunction { /** Function to fit. */ private final ParametricRealFunction f; /** Simple constructor. * @param f function to fit. */ public TheoreticalValuesFunction(final ParametricRealFunction f) { this.f = f; } /** {@inheritDoc} */ public MultivariateMatrixFunction jacobian() { return new MultivariateMatrixFunction() { public double[][] value(double[] point) throws FunctionEvaluationException, IllegalArgumentException { final double[][] jacobian = new double[observations.size()][]; int i = 0; for (WeightedObservedPoint observed : observations) { jacobian[i++] = f.gradient(observed.getX(), point); } return jacobian; } }; } /** {@inheritDoc} */ public double[] value(double[] point) throws FunctionEvaluationException, IllegalArgumentException { // compute the residuals final double[] values = new double[observations.size()]; int i = 0; for (WeightedObservedPoint observed : observations) { values[i++] = f.value(observed.getX(), point); } return values; } } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianDerivativeFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianDerivativeFu100644 1750 1750 6776 11532241244 32570 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.io.Serializable; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.exception.NullArgumentException; /** * The derivative of {@link GaussianFunction}. Specifically: *

                    * f'(x) = (-b / (d^2)) * (x - c) * exp(-((x - c)^2) / (2*(d^2))) *

                    * Notation key: *

                      *
                    • x^n: x raised to the power of n *
                    • exp(x): e^x *
                    * * @since 2.2 * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class GaussianDerivativeFunction implements UnivariateRealFunction, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -6500229089670174766L; /** Parameter b of this function. */ private final double b; /** Parameter c of this function. */ private final double c; /** Square of the parameter d of this function. */ private final double d2; /** * Constructs an instance with the specified parameters. * * @param b b parameter value * @param c c parameter value * @param d d parameter value * * @throws IllegalArgumentException if d is 0 */ public GaussianDerivativeFunction(double b, double c, double d) { if (d == 0.0) { throw new ZeroException(); } this.b = b; this.c = c; this.d2 = d * d; } /** * Constructs an instance with the specified parameters. * * @param parameters b, c, and d parameter values * * @throws IllegalArgumentException if parameters is null, * parameters length is not 3, or if * parameters[2] is 0 */ public GaussianDerivativeFunction(double[] parameters) { if (parameters == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (parameters.length != 3) { throw new DimensionMismatchException(3, parameters.length); } if (parameters[2] == 0.0) { throw new ZeroException(); } this.b = parameters[0]; this.c = parameters[1]; this.d2 = parameters[2] * parameters[2]; } /** {@inheritDoc} */ public double value(double x) { final double xMc = x - c; return (-b / d2) * xMc * Math.exp(-(xMc * xMc) / (2.0 * d2)); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/package.html100644 1750 1750 2370 11532241244 31020 0ustarlucluc 0 0 This package provides classes to perform curve fitting.

                    Curve fitting is a special case of a least squares problem were the parameters are the coefficients of a function f whose graph y=f(x) should pass through sample points, and were the objective function is the squared sum of residuals f(xi)-yi for observed points (xi, yi).

                    ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFu100644 1750 1750 15164 11532241244 32564 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.io.Serializable; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.optimization.fitting.ParametricRealFunction; /** * A Gaussian function. Specifically: *

                    * f(x) = a + b*exp(-((x - c)^2 / (2*d^2))) *

                    * The parameters have the following meaning: *

                      *
                    • a is a constant offset that shifts f(x) up or down *
                    • b is the height of the peak *
                    • c is the position of the center of the peak *
                    • d is related to the FWHM by FWHM = 2*sqrt(2*ln(2))*d *
                    * Notation key: *
                      *
                    • x^n: x raised to the power of n *
                    • exp(x): e^x *
                    • sqrt(x): the square root of x *
                    • ln(x): the natural logarithm of x *
                    * References: * * * @since 2.2 * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class ParametricGaussianFunction implements ParametricRealFunction, Serializable { /** Serializable version Id. */ private static final long serialVersionUID = -3875578602503903233L; /** * Constructs an instance. */ public ParametricGaussianFunction() { } /** * Computes value of function f(x) for the specified x and * parameters a, b, c, and d. * * @param x x value * @param parameters values of a, b, c, and * d * * @return value of f(x) evaluated at x with the specified * parameters * * @throws IllegalArgumentException if parameters is invalid as * determined by {@link #validateParameters(double[])} * @throws ZeroException if parameters values are * invalid as determined by {@link #validateParameters(double[])} */ public double value(double x, double[] parameters) throws ZeroException { validateParameters(parameters); final double a = parameters[0]; final double b = parameters[1]; final double c = parameters[2]; final double d = parameters[3]; final double xMc = x - c; return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d))); } /** * Computes the gradient vector for a four variable version of the function * where the parameters, a, b, c, and d, * are considered the variables, not x. That is, instead of * computing the gradient vector for the function f(x) (which would * just be the derivative of f(x) with respect to x since * it's a one-dimensional function), computes the gradient vector for the * function f(a, b, c, d) = a + b*exp(-((x - c)^2 / (2*d^2))) * treating the specified x as a constant. *

                    * The components of the computed gradient vector are the partial * derivatives of f(a, b, c, d) with respect to each variable. * That is, the partial derivative of f(a, b, c, d) with respect to * a, the partial derivative of f(a, b, c, d) with respect * to b, the partial derivative of f(a, b, c, d) with * respect to c, and the partial derivative of f(a, b, c, * d) with respect to d. * * @param x x value to be used as constant in f(a, b, c, * d) * @param parameters values of a, b, c, and * d for computation of gradient vector of f(a, b, c, * d) * * @return gradient vector of f(a, b, c, d) * * @throws IllegalArgumentException if parameters is invalid as * determined by {@link #validateParameters(double[])} * @throws ZeroException if parameters values are * invalid as determined by {@link #validateParameters(double[])} */ public double[] gradient(double x, double[] parameters) throws ZeroException { validateParameters(parameters); final double b = parameters[1]; final double c = parameters[2]; final double d = parameters[3]; final double xMc = x - c; final double d2 = d * d; final double exp = Math.exp(-xMc * xMc / (2 * d2)); final double f = b * exp * xMc / d2; return new double[] { 1.0, exp, f, f * xMc / d }; } /** * Validates parameters to ensure they are appropriate for the evaluation of * the value and gradient methods. * * @param parameters values of a, b, c, and * d * * @throws IllegalArgumentException if parameters is * null or if parameters does not have * length == 4 * @throws ZeroException if parameters[3] * (d) is 0 */ private void validateParameters(double[] parameters) throws ZeroException { if (parameters == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (parameters.length != 4) { throw new DimensionMismatchException(4, parameters.length); } if (parameters[3] == 0.0) { throw new ZeroException(); } } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/ParametricRealFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/ParametricRealFuncti100644 1750 1750 3654 11532241244 32534 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a real function that depends on one independent * variable plus some extra parameters. * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public interface ParametricRealFunction { /** * Compute the value of the function. * @param x the point for which the function value should be computed * @param parameters function parameters * @return the value * @throws FunctionEvaluationException if the function evaluation fails */ double value(double x, double[] parameters) throws FunctionEvaluationException; /** * Compute the gradient of the function with respect to its parameters. * @param x the point for which the function value should be computed * @param parameters function parameters * @return the value * @throws FunctionEvaluationException if the function evaluation fails */ double[] gradient(double x, double[] parameters) throws FunctionEvaluationException; } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFunction.jav100644 1750 1750 4457 11532241244 32517 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.util.FastMath; /** Harmonic function of the form f (t) = a cos (ω t + φ). * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class HarmonicFunction implements DifferentiableUnivariateRealFunction { /** Amplitude a. */ private final double a; /** Pulsation ω. */ private final double omega; /** Phase φ. */ private final double phi; /** Simple constructor. * @param a amplitude * @param omega pulsation * @param phi phase */ public HarmonicFunction(double a, double omega, double phi) { this.a = a; this.omega = omega; this.phi = phi; } /** {@inheritDoc} */ public double value(double x) { return a * FastMath.cos(omega * x + phi); } /** {@inheritDoc} */ public HarmonicFunction derivative() { return new HarmonicFunction(a * omega, omega, phi + FastMath.PI / 2); } /** Get the amplitude a. * @return amplitude a; */ public double getAmplitude() { return a; } /** Get the pulsation ω. * @return pulsation ω */ public double getPulsation() { return omega; } /** Get the phase φ. * @return phase φ */ public double getPhase() { return phi; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java100644 1750 1750 10760 11532241244 32354 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.fitting.CurveFitter; import org.apache.commons.math.optimization.fitting.WeightedObservedPoint; /** * Fits points to a Gaussian function (that is, a {@link GaussianFunction}). *

                    * Usage example: *

                     *   GaussianFitter fitter = new GaussianFitter(
                     *     new LevenbergMarquardtOptimizer());
                     *   fitter.addObservedPoint(4.0254623,  531026.0);
                     *   fitter.addObservedPoint(4.03128248, 984167.0);
                     *   fitter.addObservedPoint(4.03839603, 1887233.0);
                     *   fitter.addObservedPoint(4.04421621, 2687152.0);
                     *   fitter.addObservedPoint(4.05132976, 3461228.0);
                     *   fitter.addObservedPoint(4.05326982, 3580526.0);
                     *   fitter.addObservedPoint(4.05779662, 3439750.0);
                     *   fitter.addObservedPoint(4.0636168,  2877648.0);
                     *   fitter.addObservedPoint(4.06943698, 2175960.0);
                     *   fitter.addObservedPoint(4.07525716, 1447024.0);
                     *   fitter.addObservedPoint(4.08237071, 717104.0);
                     *   fitter.addObservedPoint(4.08366408, 620014.0);
                     *  GaussianFunction fitFunction = fitter.fit();
                     * 
                    * * @see ParametricGaussianFunction * @since 2.2 * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ */ public class GaussianFitter { /** Fitter used for fitting. */ private final CurveFitter fitter; /** * Constructs an instance using the specified optimizer. * * @param optimizer optimizer to use for the fitting */ public GaussianFitter(DifferentiableMultivariateVectorialOptimizer optimizer) { fitter = new CurveFitter(optimizer); } /** * Adds point (x, y) to list of observed points * with a weight of 1.0. * * @param x x point value * @param y y point value */ public void addObservedPoint(double x, double y) { addObservedPoint(1.0, x, y); } /** * Adds point (x, y) to list of observed points * with a weight of weight. * * @param weight weight assigned to point * @param x x point value * @param y y point value */ public void addObservedPoint(double weight, double x, double y) { fitter.addObservedPoint(weight, x, y); } /** * Fits Gaussian function to the observed points. * * @return Gaussian function best fitting the observed points * * @throws FunctionEvaluationException if CurveFitter.fit throws it * @throws OptimizationException if CurveFitter.fit throws it * @throws IllegalArgumentException if CurveFitter.fit throws it * * @see CurveFitter */ public GaussianFunction fit() throws FunctionEvaluationException, OptimizationException { return new GaussianFunction(fitter.fit(new ParametricGaussianFunction(), createParametersGuesser(fitter.getObservations()).guess())); } /** * Factory method to create a GaussianParametersGuesser * instance initialized with the specified observations. * * @param observations points used to initialize the created * GaussianParametersGuesser instance * * @return new GaussianParametersGuesser instance */ protected GaussianParametersGuesser createParametersGuesser(WeightedObservedPoint[] observations) { return new GaussianParametersGuesser(observations); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java100644 1750 1750 12551 11532241244 32342 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.util.FastMath; /** This class implements a curve fitting specialized for sinusoids. *

                    Harmonic fitting is a very simple case of curve fitting. The * estimated coefficients are the amplitude a, the pulsation ω and * the phase φ: f (t) = a cos (ω t + φ). They are * searched by a least square estimator initialized with a rough guess * based on integrals.

                    * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class HarmonicFitter { /** Fitter for the coefficients. */ private final CurveFitter fitter; /** Values for amplitude, pulsation ω and phase φ. */ private double[] parameters; /** Simple constructor. * @param optimizer optimizer to use for the fitting */ public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) { this.fitter = new CurveFitter(optimizer); parameters = null; } /** Simple constructor. *

                    This constructor can be used when a first guess of the * coefficients is already known.

                    * @param optimizer optimizer to use for the fitting * @param initialGuess guessed values for amplitude (index 0), * pulsation ω (index 1) and phase φ (index 2) */ public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer, final double[] initialGuess) { this.fitter = new CurveFitter(optimizer); this.parameters = initialGuess.clone(); } /** Add an observed weighted (x,y) point to the sample. * @param weight weight of the observed point in the fit * @param x abscissa of the point * @param y observed value of the point at x, after fitting we should * have P(x) as close as possible to this value */ public void addObservedPoint(double weight, double x, double y) { fitter.addObservedPoint(weight, x, y); } /** Fit an harmonic function to the observed points. * @return harmonic function best fitting the observed points * @throws OptimizationException if the sample is too short or if * the first guess cannot be computed */ public HarmonicFunction fit() throws OptimizationException { // shall we compute the first guess of the parameters ourselves ? if (parameters == null) { final WeightedObservedPoint[] observations = fitter.getObservations(); if (observations.length < 4) { throw new OptimizationException(LocalizedFormats.INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE, observations.length, 4); } HarmonicCoefficientsGuesser guesser = new HarmonicCoefficientsGuesser(observations); guesser.guess(); parameters = new double[] { guesser.getGuessedAmplitude(), guesser.getGuessedPulsation(), guesser.getGuessedPhase() }; } try { double[] fitted = fitter.fit(new ParametricHarmonicFunction(), parameters); return new HarmonicFunction(fitted[0], fitted[1], fitted[2]); } catch (FunctionEvaluationException fee) { // should never happen throw new RuntimeException(fee); } } /** Parametric harmonic function. */ private static class ParametricHarmonicFunction implements ParametricRealFunction { /** {@inheritDoc} */ public double value(double x, double[] parameters) { final double a = parameters[0]; final double omega = parameters[1]; final double phi = parameters[2]; return a * FastMath.cos(omega * x + phi); } /** {@inheritDoc} */ public double[] gradient(double x, double[] parameters) { final double a = parameters[0]; final double omega = parameters[1]; final double phi = parameters[2]; final double alpha = omega * x + phi; final double cosAlpha = FastMath.cos(alpha); final double sinAlpha = FastMath.sin(alpha); return new double[] { cosAlpha, -a * x * sinAlpha, -a * sinAlpha }; } } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianParametersGuesser.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/fitting/GaussianParametersGu100644 1750 1750 23300 11532241244 32570 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.fitting; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.exception.NullArgumentException; /** * Guesses the parameters ({@code a}, {@code b}, {@code c}, and {@code d}) * of a {@link ParametricGaussianFunction} based on the specified observed * points. * * @since 2.2 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class GaussianParametersGuesser { /** Observed points. */ private final WeightedObservedPoint[] observations; /** Resulting guessed parameters. */ private double[] parameters; /** * Constructs instance with the specified observed points. * * @param observations observed points upon which should base guess */ public GaussianParametersGuesser(WeightedObservedPoint[] observations) { if (observations == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); } if (observations.length < 3) { throw new NumberIsTooSmallException(observations.length, 3, true); } this.observations = observations.clone(); } /** * Guesses the parameters based on the observed points. * * @return guessed parameters array {a, b, c, d} */ public double[] guess() { if (parameters == null) { parameters = basicGuess(observations); } return parameters.clone(); } /** * Guesses the parameters based on the specified observed points. * * @param points observed points upon which should base guess * * @return guessed parameters array {a, b, c, d} */ private double[] basicGuess(WeightedObservedPoint[] points) { Arrays.sort(points, createWeightedObservedPointComparator()); double[] params = new double[4]; int minYIdx = findMinY(points); params[0] = points[minYIdx].getY(); int maxYIdx = findMaxY(points); params[1] = points[maxYIdx].getY(); params[2] = points[maxYIdx].getX(); double fwhmApprox; try { double halfY = params[0] + ((params[1] - params[0]) / 2.0); double fwhmX1 = interpolateXAtY(points, maxYIdx, -1, halfY); double fwhmX2 = interpolateXAtY(points, maxYIdx, +1, halfY); fwhmApprox = fwhmX2 - fwhmX1; } catch (OutOfRangeException e) { fwhmApprox = points[points.length - 1].getX() - points[0].getX(); } params[3] = fwhmApprox / (2.0 * Math.sqrt(2.0 * Math.log(2.0))); return params; } /** * Finds index of point in specified points with the smallest Y. * * @param points points to search * * @return index in specified points array */ private int findMinY(WeightedObservedPoint[] points) { int minYIdx = 0; for (int i = 1; i < points.length; i++) { if (points[i].getY() < points[minYIdx].getY()) { minYIdx = i; } } return minYIdx; } /** * Finds index of point in specified points with the largest Y. * * @param points points to search * * @return index in specified points array */ private int findMaxY(WeightedObservedPoint[] points) { int maxYIdx = 0; for (int i = 1; i < points.length; i++) { if (points[i].getY() > points[maxYIdx].getY()) { maxYIdx = i; } } return maxYIdx; } /** * Interpolates using the specified points to determine X at the specified * Y. * * @param points points to use for interpolation * @param startIdx index within points from which to start search for * interpolation bounds points * @param idxStep index step for search for interpolation bounds points * @param y Y value for which X should be determined * * @return value of X at the specified Y * * @throws IllegalArgumentException if idxStep is 0 * @throws OutOfRangeException if specified y is not within the * range of the specified points */ private double interpolateXAtY(WeightedObservedPoint[] points, int startIdx, int idxStep, double y) throws OutOfRangeException { if (idxStep == 0) { throw new ZeroException(); } WeightedObservedPoint[] twoPoints = getInterpolationPointsForY(points, startIdx, idxStep, y); WeightedObservedPoint pointA = twoPoints[0]; WeightedObservedPoint pointB = twoPoints[1]; if (pointA.getY() == y) { return pointA.getX(); } if (pointB.getY() == y) { return pointB.getX(); } return pointA.getX() + (((y - pointA.getY()) * (pointB.getX() - pointA.getX())) / (pointB.getY() - pointA.getY())); } /** * Gets the two bounding interpolation points from the specified points * suitable for determining X at the specified Y. * * @param points points to use for interpolation * @param startIdx index within points from which to start search for * interpolation bounds points * @param idxStep index step for search for interpolation bounds points * @param y Y value for which X should be determined * * @return array containing two points suitable for determining X at the * specified Y * * @throws IllegalArgumentException if idxStep is 0 * @throws OutOfRangeException if specified y is not within the * range of the specified points */ private WeightedObservedPoint[] getInterpolationPointsForY(WeightedObservedPoint[] points, int startIdx, int idxStep, double y) throws OutOfRangeException { if (idxStep == 0) { throw new ZeroException(); } for (int i = startIdx; (idxStep < 0) ? (i + idxStep >= 0) : (i + idxStep < points.length); i += idxStep) { if (isBetween(y, points[i].getY(), points[i + idxStep].getY())) { return (idxStep < 0) ? new WeightedObservedPoint[] { points[i + idxStep], points[i] } : new WeightedObservedPoint[] { points[i], points[i + idxStep] }; } } double minY = Double.POSITIVE_INFINITY; double maxY = Double.NEGATIVE_INFINITY; for (final WeightedObservedPoint point : points) { minY = Math.min(minY, point.getY()); maxY = Math.max(maxY, point.getY()); } throw new OutOfRangeException(y, minY, maxY); } /** * Determines whether a value is between two other values. * * @param value value to determine whether is between boundary1 * and boundary2 * @param boundary1 one end of the range * @param boundary2 other end of the range * * @return true if value is between boundary1 and * boundary2 (inclusive); false otherwise */ private boolean isBetween(double value, double boundary1, double boundary2) { return (value >= boundary1 && value <= boundary2) || (value >= boundary2 && value <= boundary1); } /** * Factory method creating Comparator for comparing * WeightedObservedPoint instances. * * @return new Comparator instance */ private Comparator createWeightedObservedPointComparator() { return new Comparator() { public int compare(WeightedObservedPoint p1, WeightedObservedPoint p2) { if (p1 == null && p2 == null) { return 0; } if (p1 == null) { return -1; } if (p2 == null) { return 1; } if (p1.getX() < p2.getX()) { return -1; } if (p1.getX() > p2.getX()) { return 1; } if (p1.getY() < p2.getY()) { return -1; } if (p1.getY() > p2.getY()) { return 1; } if (p1.getWeight() < p2.getWeight()) { return -1; } if (p1.getWeight() > p2.getWeight()) { return 1; } return 0; } }; } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/LinearObjectiveFuncti100644 1750 1750 12000 11532241244 32515 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.linear.ArrayRealVector; /** * An objective function for a linear optimization problem. *

                    * A linear objective function has one the form: *

                     * c1x1 + ... cnxn + d
                     * 
                    * The ci and d are the coefficients of the equation, * the xi are the coordinates of the current point. *

                    * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $ * @since 2.0 */ public class LinearObjectiveFunction implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -4531815507568396090L; /** Coefficients of the constraint (ci). */ private final transient RealVector coefficients; /** Constant term of the linear equation. */ private final double constantTerm; /** * @param coefficients The coefficients for the linear equation being optimized * @param constantTerm The constant term of the linear equation */ public LinearObjectiveFunction(double[] coefficients, double constantTerm) { this(new ArrayRealVector(coefficients), constantTerm); } /** * @param coefficients The coefficients for the linear equation being optimized * @param constantTerm The constant term of the linear equation */ public LinearObjectiveFunction(RealVector coefficients, double constantTerm) { this.coefficients = coefficients; this.constantTerm = constantTerm; } /** * Get the coefficients of the linear equation being optimized. * @return coefficients of the linear equation being optimized */ public RealVector getCoefficients() { return coefficients; } /** * Get the constant of the linear equation being optimized. * @return constant of the linear equation being optimized */ public double getConstantTerm() { return constantTerm; } /** * Compute the value of the linear equation at the current point * @param point point at which linear equation must be evaluated * @return value of the linear equation at the current point */ public double getValue(final double[] point) { return coefficients.dotProduct(point) + constantTerm; } /** * Compute the value of the linear equation at the current point * @param point point at which linear equation must be evaluated * @return value of the linear equation at the current point */ public double getValue(final RealVector point) { return coefficients.dotProduct(point) + constantTerm; } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof LinearObjectiveFunction) { LinearObjectiveFunction rhs = (LinearObjectiveFunction) other; return (constantTerm == rhs.constantTerm) && coefficients.equals(rhs.coefficients); } return false; } /** {@inheritDoc} */ @Override public int hashCode() { return Double.valueOf(constantTerm).hashCode() ^ coefficients.hashCode(); } /** Serialize the instance. * @param oos stream where object should be written * @throws IOException if object cannot be written to stream */ private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); MatrixUtils.serializeRealVector(coefficients, oos); } /** Deserialize the instance. * @param ois stream from which the object should be read * @throws ClassNotFoundException if a class in the stream cannot be found * @throws IOException if object cannot be read from the stream */ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); MatrixUtils.deserializeRealVector(this, "coefficients", ois); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/Relationship.java100644 1750 1750 3751 11532241244 31655 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; /** * Types of relationships between two cells in a Solver {@link LinearConstraint}. * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $ * @since 2.0 */ public enum Relationship { /** Equality relationship. */ EQ("="), /** Lesser than or equal relationship. */ LEQ("<="), /** Greater than or equal relationship. */ GEQ(">="); /** Display string for the relationship. */ private final String stringValue; /** Simple constructor. * @param stringValue display string for the relationship */ private Relationship(String stringValue) { this.stringValue = stringValue; } /** {@inheritDoc} */ @Override public String toString() { return stringValue; } /** * Get the relationship obtained when multiplying all coefficients by -1. * @return relationship obtained when multiplying all coefficients by -1 */ public Relationship oppositeRelationship() { switch (this) { case LEQ : return GEQ; case GEQ : return LEQ; default : return EQ; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/SimplexSolver.java100644 1750 1750 15514 11532241244 32050 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.util.MathUtils; /** * Solves a linear problem using the Two-Phase Simplex Method. * @version $Revision: 812831 $ $Date: 2009-09-09 10:48:03 +0200 (mer. 09 sept. 2009) $ * @since 2.0 */ public class SimplexSolver extends AbstractLinearOptimizer { /** Default amount of error to accept in floating point comparisons. */ private static final double DEFAULT_EPSILON = 1.0e-6; /** Amount of error to accept in floating point comparisons. */ protected final double epsilon; /** * Build a simplex solver with default settings. */ public SimplexSolver() { this(DEFAULT_EPSILON); } /** * Build a simplex solver with a specified accepted amount of error * @param epsilon the amount of error to accept in floating point comparisons */ public SimplexSolver(final double epsilon) { this.epsilon = epsilon; } /** * Returns the column with the most negative coefficient in the objective function row. * @param tableau simple tableau for the problem * @return column with the most negative coefficient */ private Integer getPivotColumn(SimplexTableau tableau) { double minValue = 0; Integer minPos = null; for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getWidth() - 1; i++) { if (MathUtils.compareTo(tableau.getEntry(0, i), minValue, epsilon) < 0) { minValue = tableau.getEntry(0, i); minPos = i; } } return minPos; } /** * Returns the row with the minimum ratio as given by the minimum ratio test (MRT). * @param tableau simple tableau for the problem * @param col the column to test the ratio of. See {@link #getPivotColumn(SimplexTableau)} * @return row with the minimum ratio */ private Integer getPivotRow(SimplexTableau tableau, final int col) { // create a list of all the rows that tie for the lowest score in the minimum ratio test List minRatioPositions = new ArrayList(); double minRatio = Double.MAX_VALUE; for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getHeight(); i++) { final double rhs = tableau.getEntry(i, tableau.getWidth() - 1); final double entry = tableau.getEntry(i, col); if (MathUtils.compareTo(entry, 0, epsilon) > 0) { final double ratio = rhs / entry; if (MathUtils.equals(ratio, minRatio, epsilon)) { minRatioPositions.add(i); } else if (ratio < minRatio) { minRatio = ratio; minRatioPositions = new ArrayList(); minRatioPositions.add(i); } } } if (minRatioPositions.size() == 0) { return null; } else if (minRatioPositions.size() > 1) { // there's a degeneracy as indicated by a tie in the minimum ratio test // check if there's an artificial variable that can be forced out of the basis for (Integer row : minRatioPositions) { for (int i = 0; i < tableau.getNumArtificialVariables(); i++) { int column = i + tableau.getArtificialVariableOffset(); if (MathUtils.equals(tableau.getEntry(row, column), 1, epsilon) && row.equals(tableau.getBasicRow(column))) { return row; } } } } return minRatioPositions.get(0); } /** * Runs one iteration of the Simplex method on the given model. * @param tableau simple tableau for the problem * @throws OptimizationException if the maximal iteration count has been * exceeded or if the model is found not to have a bounded solution */ protected void doIteration(final SimplexTableau tableau) throws OptimizationException { incrementIterationsCounter(); Integer pivotCol = getPivotColumn(tableau); Integer pivotRow = getPivotRow(tableau, pivotCol); if (pivotRow == null) { throw new UnboundedSolutionException(); } // set the pivot element to 1 double pivotVal = tableau.getEntry(pivotRow, pivotCol); tableau.divideRow(pivotRow, pivotVal); // set the rest of the pivot column to 0 for (int i = 0; i < tableau.getHeight(); i++) { if (i != pivotRow) { double multiplier = tableau.getEntry(i, pivotCol); tableau.subtractRow(i, pivotRow, multiplier); } } } /** * Solves Phase 1 of the Simplex method. * @param tableau simple tableau for the problem * @exception OptimizationException if the maximal number of iterations is * exceeded, or if the problem is found not to have a bounded solution, or * if there is no feasible solution */ protected void solvePhase1(final SimplexTableau tableau) throws OptimizationException { // make sure we're in Phase 1 if (tableau.getNumArtificialVariables() == 0) { return; } while (!tableau.isOptimal()) { doIteration(tableau); } // if W is not zero then we have no feasible solution if (!MathUtils.equals(tableau.getEntry(0, tableau.getRhsOffset()), 0, epsilon)) { throw new NoFeasibleSolutionException(); } } /** {@inheritDoc} */ @Override public RealPointValuePair doOptimize() throws OptimizationException { final SimplexTableau tableau = new SimplexTableau(function, linearConstraints, goal, nonNegative, epsilon); solvePhase1(tableau); tableau.dropPhase1Objective(); while (!tableau.isOptimal()) { doIteration(tableau); } return tableau.getSolution(); } } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/UnboundedSolutionException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/UnboundedSolutionExce100644 1750 1750 3023 11532241244 32551 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.OptimizationException; /** * This class represents exceptions thrown by optimizers when a solution * escapes to infinity. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class UnboundedSolutionException extends OptimizationException { /** Serializable version identifier. */ private static final long serialVersionUID = 940539497277290619L; /** * Simple constructor using a default message. */ public UnboundedSolutionException() { super(LocalizedFormats.UNBOUNDED_SOLUTION); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/SimplexTableau.java100644 1750 1750 51526 11532241244 32156 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.util.MathUtils; /** * A tableau for use in the Simplex method. * *

                    * Example: *

                     *   W |  Z |  x1 |  x2 |  x- | s1 |  s2 |  a1 |  RHS
                     * ---------------------------------------------------
                     *  -1    0    0     0     0     0     0     1     0   <= phase 1 objective
                     *   0    1   -15   -10    0     0     0     0     0   <= phase 2 objective
                     *   0    0    1     0     0     1     0     0     2   <= constraint 1
                     *   0    0    0     1     0     0     1     0     3   <= constraint 2
                     *   0    0    1     1     0     0     0     1     4   <= constraint 3
                     * 
                    * W: Phase 1 objective function
                    * Z: Phase 2 objective function
                    * x1 & x2: Decision variables
                    * x-: Extra decision variable to allow for negative values
                    * s1 & s2: Slack/Surplus variables
                    * a1: Artificial variable
                    * RHS: Right hand side
                    *

                    * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $ * @since 2.0 */ class SimplexTableau implements Serializable { /** Column label for negative vars. */ private static final String NEGATIVE_VAR_COLUMN_LABEL = "x-"; /** Serializable version identifier. */ private static final long serialVersionUID = -1369660067587938365L; /** Linear objective function. */ private final LinearObjectiveFunction f; /** Linear constraints. */ private final List constraints; /** Whether to restrict the variables to non-negative values. */ private final boolean restrictToNonNegative; /** The variables each column represents */ private final List columnLabels = new ArrayList(); /** Simple tableau. */ private transient RealMatrix tableau; /** Number of decision variables. */ private final int numDecisionVariables; /** Number of slack variables. */ private final int numSlackVariables; /** Number of artificial variables. */ private int numArtificialVariables; /** Amount of error to accept in floating point comparisons. */ private final double epsilon; /** * Build a tableau for a linear problem. * @param f linear objective function * @param constraints linear constraints * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE} * @param restrictToNonNegative whether to restrict the variables to non-negative values * @param epsilon amount of error to accept in floating point comparisons */ SimplexTableau(final LinearObjectiveFunction f, final Collection constraints, final GoalType goalType, final boolean restrictToNonNegative, final double epsilon) { this.f = f; this.constraints = normalizeConstraints(constraints); this.restrictToNonNegative = restrictToNonNegative; this.epsilon = epsilon; this.numDecisionVariables = f.getCoefficients().getDimension() + (restrictToNonNegative ? 0 : 1); this.numSlackVariables = getConstraintTypeCounts(Relationship.LEQ) + getConstraintTypeCounts(Relationship.GEQ); this.numArtificialVariables = getConstraintTypeCounts(Relationship.EQ) + getConstraintTypeCounts(Relationship.GEQ); this.tableau = createTableau(goalType == GoalType.MAXIMIZE); initializeColumnLabels(); } /** * Initialize the labels for the columns. */ protected void initializeColumnLabels() { if (getNumObjectiveFunctions() == 2) { columnLabels.add("W"); } columnLabels.add("Z"); for (int i = 0; i < getOriginalNumDecisionVariables(); i++) { columnLabels.add("x" + i); } if (!restrictToNonNegative) { columnLabels.add(NEGATIVE_VAR_COLUMN_LABEL); } for (int i = 0; i < getNumSlackVariables(); i++) { columnLabels.add("s" + i); } for (int i = 0; i < getNumArtificialVariables(); i++) { columnLabels.add("a" + i); } columnLabels.add("RHS"); } /** * Create the tableau by itself. * @param maximize if true, goal is to maximize the objective function * @return created tableau */ protected RealMatrix createTableau(final boolean maximize) { // create a matrix of the correct size int width = numDecisionVariables + numSlackVariables + numArtificialVariables + getNumObjectiveFunctions() + 1; // + 1 is for RHS int height = constraints.size() + getNumObjectiveFunctions(); Array2DRowRealMatrix matrix = new Array2DRowRealMatrix(height, width); // initialize the objective function rows if (getNumObjectiveFunctions() == 2) { matrix.setEntry(0, 0, -1); } int zIndex = (getNumObjectiveFunctions() == 1) ? 0 : 1; matrix.setEntry(zIndex, zIndex, maximize ? 1 : -1); RealVector objectiveCoefficients = maximize ? f.getCoefficients().mapMultiply(-1) : f.getCoefficients(); copyArray(objectiveCoefficients.getData(), matrix.getDataRef()[zIndex]); matrix.setEntry(zIndex, width - 1, maximize ? f.getConstantTerm() : -1 * f.getConstantTerm()); if (!restrictToNonNegative) { matrix.setEntry(zIndex, getSlackVariableOffset() - 1, getInvertedCoeffiecientSum(objectiveCoefficients)); } // initialize the constraint rows int slackVar = 0; int artificialVar = 0; for (int i = 0; i < constraints.size(); i++) { LinearConstraint constraint = constraints.get(i); int row = getNumObjectiveFunctions() + i; // decision variable coefficients copyArray(constraint.getCoefficients().getData(), matrix.getDataRef()[row]); // x- if (!restrictToNonNegative) { matrix.setEntry(row, getSlackVariableOffset() - 1, getInvertedCoeffiecientSum(constraint.getCoefficients())); } // RHS matrix.setEntry(row, width - 1, constraint.getValue()); // slack variables if (constraint.getRelationship() == Relationship.LEQ) { matrix.setEntry(row, getSlackVariableOffset() + slackVar++, 1); // slack } else if (constraint.getRelationship() == Relationship.GEQ) { matrix.setEntry(row, getSlackVariableOffset() + slackVar++, -1); // excess } // artificial variables if ((constraint.getRelationship() == Relationship.EQ) || (constraint.getRelationship() == Relationship.GEQ)) { matrix.setEntry(0, getArtificialVariableOffset() + artificialVar, 1); matrix.setEntry(row, getArtificialVariableOffset() + artificialVar++, 1); matrix.setRowVector(0, matrix.getRowVector(0).subtract(matrix.getRowVector(row))); } } return matrix; } /** * Get new versions of the constraints which have positive right hand sides. * @param originalConstraints original (not normalized) constraints * @return new versions of the constraints */ public List normalizeConstraints(Collection originalConstraints) { List normalized = new ArrayList(); for (LinearConstraint constraint : originalConstraints) { normalized.add(normalize(constraint)); } return normalized; } /** * Get a new equation equivalent to this one with a positive right hand side. * @param constraint reference constraint * @return new equation */ private LinearConstraint normalize(final LinearConstraint constraint) { if (constraint.getValue() < 0) { return new LinearConstraint(constraint.getCoefficients().mapMultiply(-1), constraint.getRelationship().oppositeRelationship(), -1 * constraint.getValue()); } return new LinearConstraint(constraint.getCoefficients(), constraint.getRelationship(), constraint.getValue()); } /** * Get the number of objective functions in this tableau. * @return 2 for Phase 1. 1 for Phase 2. */ protected final int getNumObjectiveFunctions() { return this.numArtificialVariables > 0 ? 2 : 1; } /** * Get a count of constraints corresponding to a specified relationship. * @param relationship relationship to count * @return number of constraint with the specified relationship */ private int getConstraintTypeCounts(final Relationship relationship) { int count = 0; for (final LinearConstraint constraint : constraints) { if (constraint.getRelationship() == relationship) { ++count; } } return count; } /** * Get the -1 times the sum of all coefficients in the given array. * @param coefficients coefficients to sum * @return the -1 times the sum of all coefficients in the given array. */ protected static double getInvertedCoeffiecientSum(final RealVector coefficients) { double sum = 0; for (double coefficient : coefficients.getData()) { sum -= coefficient; } return sum; } /** * Checks whether the given column is basic. * @param col index of the column to check * @return the row that the variable is basic in. null if the column is not basic */ protected Integer getBasicRow(final int col) { Integer row = null; for (int i = 0; i < getHeight(); i++) { if (MathUtils.equals(getEntry(i, col), 1.0, epsilon) && (row == null)) { row = i; } else if (!MathUtils.equals(getEntry(i, col), 0.0, epsilon)) { return null; } } return row; } /** * Removes the phase 1 objective function, positive cost non-artificial variables, * and the non-basic artificial variables from this tableau. */ protected void dropPhase1Objective() { if (getNumObjectiveFunctions() == 1) { return; } List columnsToDrop = new ArrayList(); columnsToDrop.add(0); // positive cost non-artificial variables for (int i = getNumObjectiveFunctions(); i < getArtificialVariableOffset(); i++) { if (MathUtils.compareTo(tableau.getEntry(0, i), 0, epsilon) > 0) { columnsToDrop.add(i); } } // non-basic artificial variables for (int i = 0; i < getNumArtificialVariables(); i++) { int col = i + getArtificialVariableOffset(); if (getBasicRow(col) == null) { columnsToDrop.add(col); } } double[][] matrix = new double[getHeight() - 1][getWidth() - columnsToDrop.size()]; for (int i = 1; i < getHeight(); i++) { int col = 0; for (int j = 0; j < getWidth(); j++) { if (!columnsToDrop.contains(j)) { matrix[i - 1][col++] = tableau.getEntry(i, j); } } } for (int i = columnsToDrop.size() - 1; i >= 0; i--) { columnLabels.remove((int) columnsToDrop.get(i)); } this.tableau = new Array2DRowRealMatrix(matrix); this.numArtificialVariables = 0; } /** * @param src the source array * @param dest the destination array */ private void copyArray(final double[] src, final double[] dest) { System.arraycopy(src, 0, dest, getNumObjectiveFunctions(), src.length); } /** * Returns whether the problem is at an optimal state. * @return whether the model has been solved */ boolean isOptimal() { for (int i = getNumObjectiveFunctions(); i < getWidth() - 1; i++) { if (MathUtils.compareTo(tableau.getEntry(0, i), 0, epsilon) < 0) { return false; } } return true; } /** * Get the current solution. * * @return current solution */ protected RealPointValuePair getSolution() { int negativeVarColumn = columnLabels.indexOf(NEGATIVE_VAR_COLUMN_LABEL); Integer negativeVarBasicRow = negativeVarColumn > 0 ? getBasicRow(negativeVarColumn) : null; double mostNegative = negativeVarBasicRow == null ? 0 : getEntry(negativeVarBasicRow, getRhsOffset()); Set basicRows = new HashSet(); double[] coefficients = new double[getOriginalNumDecisionVariables()]; for (int i = 0; i < coefficients.length; i++) { int colIndex = columnLabels.indexOf("x" + i); if (colIndex < 0) { coefficients[i] = 0; continue; } Integer basicRow = getBasicRow(colIndex); if (basicRows.contains(basicRow)) { // if multiple variables can take a given value // then we choose the first and set the rest equal to 0 coefficients[i] = 0; } else { basicRows.add(basicRow); coefficients[i] = (basicRow == null ? 0 : getEntry(basicRow, getRhsOffset())) - (restrictToNonNegative ? 0 : mostNegative); } } return new RealPointValuePair(coefficients, f.getValue(coefficients)); } /** * Subtracts a multiple of one row from another. *

                    * After application of this operation, the following will hold: * minuendRow = minuendRow - multiple * subtrahendRow *

                    * @param dividendRow index of the row * @param divisor value of the divisor */ protected void divideRow(final int dividendRow, final double divisor) { for (int j = 0; j < getWidth(); j++) { tableau.setEntry(dividendRow, j, tableau.getEntry(dividendRow, j) / divisor); } } /** * Subtracts a multiple of one row from another. *

                    * After application of this operation, the following will hold: * minuendRow = minuendRow - multiple * subtrahendRow *

                    * @param minuendRow row index * @param subtrahendRow row index * @param multiple multiplication factor */ protected void subtractRow(final int minuendRow, final int subtrahendRow, final double multiple) { tableau.setRowVector(minuendRow, tableau.getRowVector(minuendRow) .subtract(tableau.getRowVector(subtrahendRow).mapMultiply(multiple))); } /** * Get the width of the tableau. * @return width of the tableau */ protected final int getWidth() { return tableau.getColumnDimension(); } /** * Get the height of the tableau. * @return height of the tableau */ protected final int getHeight() { return tableau.getRowDimension(); } /** Get an entry of the tableau. * @param row row index * @param column column index * @return entry at (row, column) */ protected final double getEntry(final int row, final int column) { return tableau.getEntry(row, column); } /** Set an entry of the tableau. * @param row row index * @param column column index * @param value for the entry */ protected final void setEntry(final int row, final int column, final double value) { tableau.setEntry(row, column, value); } /** * Get the offset of the first slack variable. * @return offset of the first slack variable */ protected final int getSlackVariableOffset() { return getNumObjectiveFunctions() + numDecisionVariables; } /** * Get the offset of the first artificial variable. * @return offset of the first artificial variable */ protected final int getArtificialVariableOffset() { return getNumObjectiveFunctions() + numDecisionVariables + numSlackVariables; } /** * Get the offset of the right hand side. * @return offset of the right hand side */ protected final int getRhsOffset() { return getWidth() - 1; } /** * Get the number of decision variables. *

                    * If variables are not restricted to positive values, this will include 1 * extra decision variable to represent the absolute value of the most * negative variable. *

                    * @return number of decision variables * @see #getOriginalNumDecisionVariables() */ protected final int getNumDecisionVariables() { return numDecisionVariables; } /** * Get the original number of decision variables. * @return original number of decision variables * @see #getNumDecisionVariables() */ protected final int getOriginalNumDecisionVariables() { return f.getCoefficients().getDimension(); } /** * Get the number of slack variables. * @return number of slack variables */ protected final int getNumSlackVariables() { return numSlackVariables; } /** * Get the number of artificial variables. * @return number of artificial variables */ protected final int getNumArtificialVariables() { return numArtificialVariables; } /** * Get the tableau data. * @return tableau data */ protected final double[][] getData() { return tableau.getData(); } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof SimplexTableau) { SimplexTableau rhs = (SimplexTableau) other; return (restrictToNonNegative == rhs.restrictToNonNegative) && (numDecisionVariables == rhs.numDecisionVariables) && (numSlackVariables == rhs.numSlackVariables) && (numArtificialVariables == rhs.numArtificialVariables) && (epsilon == rhs.epsilon) && f.equals(rhs.f) && constraints.equals(rhs.constraints) && tableau.equals(rhs.tableau); } return false; } /** {@inheritDoc} */ @Override public int hashCode() { return Boolean.valueOf(restrictToNonNegative).hashCode() ^ numDecisionVariables ^ numSlackVariables ^ numArtificialVariables ^ Double.valueOf(epsilon).hashCode() ^ f.hashCode() ^ constraints.hashCode() ^ tableau.hashCode(); } /** Serialize the instance. * @param oos stream where object should be written * @throws IOException if object cannot be written to stream */ private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); MatrixUtils.serializeRealMatrix(tableau, oos); } /** Deserialize the instance. * @param ois stream from which the object should be read * @throws ClassNotFoundException if a class in the stream cannot be found * @throws IOException if object cannot be read from the stream */ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); MatrixUtils.deserializeRealMatrix(this, "tableau", ois); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/LinearConstraint.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/LinearConstraint.java100644 1750 1750 24157 11532241244 32516 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.linear.ArrayRealVector; /** * A linear constraint for a linear optimization problem. *

                    * A linear constraint has one of the forms: *

                      *
                    • c1x1 + ... cnxn = v
                    • *
                    • c1x1 + ... cnxn <= v
                    • *
                    • c1x1 + ... cnxn >= v
                    • *
                    • l1x1 + ... lnxn + lcst = * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst <= * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst >= * r1x1 + ... rnxn + rcst
                    • *
                    * The ci, li or ri are the coefficients of the constraints, the xi * are the coordinates of the current point and v is the value of the constraint. *

                    * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $ * @since 2.0 */ public class LinearConstraint implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -764632794033034092L; /** Coefficients of the constraint (left hand side). */ private final transient RealVector coefficients; /** Relationship between left and right hand sides (=, <=, >=). */ private final Relationship relationship; /** Value of the constraint (right hand side). */ private final double value; /** * Build a constraint involving a single linear equation. *

                    * A linear constraint with a single linear equation has one of the forms: *

                      *
                    • c1x1 + ... cnxn = v
                    • *
                    • c1x1 + ... cnxn <= v
                    • *
                    • c1x1 + ... cnxn >= v
                    • *
                    *

                    * @param coefficients The coefficients of the constraint (left hand side) * @param relationship The type of (in)equality used in the constraint * @param value The value of the constraint (right hand side) */ public LinearConstraint(final double[] coefficients, final Relationship relationship, final double value) { this(new ArrayRealVector(coefficients), relationship, value); } /** * Build a constraint involving a single linear equation. *

                    * A linear constraint with a single linear equation has one of the forms: *

                      *
                    • c1x1 + ... cnxn = v
                    • *
                    • c1x1 + ... cnxn <= v
                    • *
                    • c1x1 + ... cnxn >= v
                    • *
                    *

                    * @param coefficients The coefficients of the constraint (left hand side) * @param relationship The type of (in)equality used in the constraint * @param value The value of the constraint (right hand side) */ public LinearConstraint(final RealVector coefficients, final Relationship relationship, final double value) { this.coefficients = coefficients; this.relationship = relationship; this.value = value; } /** * Build a constraint involving two linear equations. *

                    * A linear constraint with two linear equation has one of the forms: *

                      *
                    • l1x1 + ... lnxn + lcst = * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst <= * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst >= * r1x1 + ... rnxn + rcst
                    • *
                    *

                    * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint * @param relationship The type of (in)equality used in the constraint * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint */ public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant, final Relationship relationship, final double[] rhsCoefficients, final double rhsConstant) { double[] sub = new double[lhsCoefficients.length]; for (int i = 0; i < sub.length; ++i) { sub[i] = lhsCoefficients[i] - rhsCoefficients[i]; } this.coefficients = new ArrayRealVector(sub, false); this.relationship = relationship; this.value = rhsConstant - lhsConstant; } /** * Build a constraint involving two linear equations. *

                    * A linear constraint with two linear equation has one of the forms: *

                      *
                    • l1x1 + ... lnxn + lcst = * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst <= * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst >= * r1x1 + ... rnxn + rcst
                    • *
                    *

                    * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint * @param relationship The type of (in)equality used in the constraint * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint */ public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant, final Relationship relationship, final RealVector rhsCoefficients, final double rhsConstant) { this.coefficients = lhsCoefficients.subtract(rhsCoefficients); this.relationship = relationship; this.value = rhsConstant - lhsConstant; } /** * Get the coefficients of the constraint (left hand side). * @return coefficients of the constraint (left hand side) */ public RealVector getCoefficients() { return coefficients; } /** * Get the relationship between left and right hand sides. * @return relationship between left and right hand sides */ public Relationship getRelationship() { return relationship; } /** * Get the value of the constraint (right hand side). * @return value of the constraint (right hand side) */ public double getValue() { return value; } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof LinearConstraint) { LinearConstraint rhs = (LinearConstraint) other; return (relationship == rhs.relationship) && (value == rhs.value) && coefficients.equals(rhs.coefficients); } return false; } /** {@inheritDoc} */ @Override public int hashCode() { return relationship.hashCode() ^ Double.valueOf(value).hashCode() ^ coefficients.hashCode(); } /** Serialize the instance. * @param oos stream where object should be written * @throws IOException if object cannot be written to stream */ private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); MatrixUtils.serializeRealVector(coefficients, oos); } /** Deserialize the instance. * @param ois stream from which the object should be read * @throws ClassNotFoundException if a class in the stream cannot be found * @throws IOException if object cannot be read from the stream */ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); MatrixUtils.deserializeRealVector(this, "coefficients", ois); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/package.html100644 1750 1750 1653 11532241244 30631 0ustarlucluc 0 0 This package provides optimization algorithms for linear constrained problems. commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/LinearOptimizer.java100644 1750 1750 10062 11532241244 32342 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.util.Collection; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; /** * This interface represents an optimization algorithm for linear problems. *

                    Optimization algorithms find the input point set that either {@link GoalType * maximize or minimize} an objective function. In the linear case the form of * the function is restricted to *

                     * c1x1 + ... cnxn = v
                     * 
                    * and there may be linear constraints too, of one of the forms: *
                      *
                    • c1x1 + ... cnxn = v
                    • *
                    • c1x1 + ... cnxn <= v
                    • *
                    • c1x1 + ... cnxn >= v
                    • *
                    • l1x1 + ... lnxn + lcst = * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst <= * r1x1 + ... rnxn + rcst
                    • *
                    • l1x1 + ... lnxn + lcst >= * r1x1 + ... rnxn + rcst
                    • *
                    * where the ci, li or ri are the coefficients of * the constraints, the xi are the coordinates of the current point and * v is the value of the constraint. *

                    * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface LinearOptimizer { /** Set the maximal number of iterations of the algorithm. * @param maxIterations maximal number of function calls */ void setMaxIterations(int maxIterations); /** Get the maximal number of iterations of the algorithm. * @return maximal number of iterations */ int getMaxIterations(); /** Get the number of iterations realized by the algorithm. *

                    * The number of evaluations corresponds to the last call to the * {@link #optimize(LinearObjectiveFunction, Collection, GoalType, boolean) optimize} * method. It is 0 if the method has not been called yet. *

                    * @return number of iterations */ int getIterations(); /** Optimizes an objective function. * @param f linear objective function * @param constraints linear constraints * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE} * @param restrictToNonNegative whether to restrict the variables to non-negative values * @return point/value pair giving the optimal value for objective function * @exception OptimizationException if no solution fulfilling the constraints * can be found in the allowed number of iterations */ RealPointValuePair optimize(LinearObjectiveFunction f, Collection constraints, GoalType goalType, boolean restrictToNonNegative) throws OptimizationException; } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/NoFeasibleSolutionExc100644 1750 1750 3037 11532241244 32475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.OptimizationException; /** * This class represents exceptions thrown by optimizers when no solution * fulfills the constraints. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class NoFeasibleSolutionException extends OptimizationException { /** Serializable version identifier. */ private static final long serialVersionUID = -3044253632189082760L; /** * Simple constructor using a default message. */ public NoFeasibleSolutionException() { super(LocalizedFormats.NO_FEASIBLE_SOLUTION); } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/linear/AbstractLinearOptimiz100644 1750 1750 10272 11532241244 32562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.linear; import java.util.Collection; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; /** * Base class for implementing linear optimizers. *

                    This base class handles the boilerplate methods associated to thresholds * settings and iterations counters.

                    * @version $Revision: 925812 $ $Date: 2010-03-21 16:49:31 +0100 (dim. 21 mars 2010) $ * @since 2.0 * */ public abstract class AbstractLinearOptimizer implements LinearOptimizer { /** Default maximal number of iterations allowed. */ public static final int DEFAULT_MAX_ITERATIONS = 100; /** * Linear objective function. * @since 2.1 */ protected LinearObjectiveFunction function; /** * Linear constraints. * @since 2.1 */ protected Collection linearConstraints; /** * Type of optimization goal: either {@link GoalType#MAXIMIZE} or {@link GoalType#MINIMIZE}. * @since 2.1 */ protected GoalType goal; /** * Whether to restrict the variables to non-negative values. * @since 2.1 */ protected boolean nonNegative; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed. */ private int iterations; /** Simple constructor with default settings. *

                    The maximal number of evaluation is set to its default value.

                    */ protected AbstractLinearOptimizer() { setMaxIterations(DEFAULT_MAX_ITERATIONS); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return iterations; } /** Increment the iterations counter by 1. * @exception OptimizationException if the maximal number * of iterations is exceeded */ protected void incrementIterationsCounter() throws OptimizationException { if (++iterations > maxIterations) { throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); } } /** {@inheritDoc} */ public RealPointValuePair optimize(final LinearObjectiveFunction f, final Collection constraints, final GoalType goalType, final boolean restrictToNonNegative) throws OptimizationException { // store linear problem characteristics this.function = f; this.linearConstraints = constraints; this.goal = goalType; this.nonNegative = restrictToNonNegative; iterations = 0; // solve the problem return doOptimize(); } /** Perform the bulk of optimization algorithm. * @return the point/value pair giving the optimal value for objective function * @exception OptimizationException if no solution fulfilling the constraints * can be found in the allowed number of iterations */ protected abstract RealPointValuePair doOptimize() throws OptimizationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/RealConvergenceChecker.java100644 1750 1750 5265 11532241244 32273 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; /** This interface specifies how to check if an {@link MultivariateRealOptimizer optimization * algorithm} has converged. * *

                    Deciding if convergence has been reached is a problem-dependent issue. The * user should provide a class implementing this interface to allow the optimization * algorithm to stop its search according to the problem at hand.

                    *

                    For convenience, two implementations that fit simple needs are already provided: * {@link SimpleScalarValueChecker} and {@link SimpleRealPointChecker}. The first * one considers convergence is reached when the objective function value does not * change much anymore, it does not use the point set at all. The second one * considers convergence is reached when the input point set does not change * much anymore, it does not use objective function value at all.

                    * * @version $Revision: 799857 $ $Date: 2009-08-01 15:07:12 +0200 (sam. 01 août 2009) $ * @since 2.0 */ public interface RealConvergenceChecker { /** Check if the optimization algorithm has converged considering the last points. *

                    * This method may be called several time from the same algorithm iteration with * different points. This can be detected by checking the iteration number at each * call if needed. Each time this method is called, the previous and current point * correspond to points with the same role at each iteration, so they can be * compared. As an example, simplex-based algorithms call this method for all * points of the simplex, not only for the best or worst ones. *

                    * @param iteration index of current iteration * @param previous point from previous iteration * @param current point from current iteration * @return true if the algorithm is considered to have converged */ boolean converged(int iteration, RealPointValuePair previous, RealPointValuePair current); } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/VectorialConvergenceChecker.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/VectorialConvergenceChecker.100644 1750 1750 5335 11532241244 32474 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; /** This interface specifies how to check if a {@link * DifferentiableMultivariateVectorialOptimizer optimization algorithm} has converged. * *

                    Deciding if convergence has been reached is a problem-dependent issue. The * user should provide a class implementing this interface to allow the optimization * algorithm to stop its search according to the problem at hand.

                    *

                    For convenience, two implementations that fit simple needs are already provided: * {@link SimpleVectorialValueChecker} and {@link SimpleVectorialPointChecker}. The first * one considers convergence is reached when the objective function value does not * change much anymore, it does not use the point set at all. The second one * considers convergence is reached when the input point set does not change * much anymore, it does not use objective function value at all.

                    * * @version $Revision: 780674 $ $Date: 2009-06-01 17:10:55 +0200 (lun. 01 juin 2009) $ * @since 2.0 */ public interface VectorialConvergenceChecker { /** Check if the optimization algorithm has converged considering the last points. *

                    * This method may be called several time from the same algorithm iteration with * different points. This can be detected by checking the iteration number at each * call if needed. Each time this method is called, the previous and current point * correspond to points with the same role at each iteration, so they can be * compared. As an example, simplex-based algorithms call this method for all * points of the simplex, not only for the best or worst ones. *

                    * @param iteration index of current iteration * @param previous point from previous iteration * @param current point from current iteration * @return true if the algorithm is considered to have converged */ boolean converged(int iteration, VectorialPointValuePair previous, VectorialPointValuePair current); } ././@LongLink100644 0 0 157 11532242443 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOpti100644 1750 1750 27730 11532241244 32645 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomGenerator; import org.apache.commons.math.util.FastMath; /** * Special implementation of the {@link UnivariateRealOptimizer} interface adding * multi-start features to an existing optimizer. *

                    * This class wraps a classical optimizer to use it several times in * turn with different starting points in order to avoid being trapped * into a local extremum when looking for a global one. *

                    * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public class MultiStartUnivariateRealOptimizer implements UnivariateRealOptimizer { /** Serializable version identifier. */ private static final long serialVersionUID = 5983375963110961019L; /** Underlying classical optimizer. */ private final UnivariateRealOptimizer optimizer; /** Maximal number of iterations allowed. */ private int maxIterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of iterations already performed for all starts. */ private int totalIterations; /** Number of evaluations already performed for all starts. */ private int totalEvaluations; /** Number of starts to go. */ private int starts; /** Random generator for multi-start. */ private RandomGenerator generator; /** Found optima. */ private double[] optima; /** Found function values at optima. */ private double[] optimaValues; /** * Create a multi-start optimizer from a single-start optimizer * @param optimizer single-start optimizer to wrap * @param starts number of starts to perform (including the * first one), multi-start is disabled if value is less than or * equal to 1 * @param generator random generator to use for restarts */ public MultiStartUnivariateRealOptimizer(final UnivariateRealOptimizer optimizer, final int starts, final RandomGenerator generator) { this.optimizer = optimizer; this.totalIterations = 0; this.starts = starts; this.generator = generator; this.optima = null; setMaximalIterationCount(Integer.MAX_VALUE); setMaxEvaluations(Integer.MAX_VALUE); } /** {@inheritDoc} */ public double getFunctionValue() { return optimaValues[0]; } /** {@inheritDoc} */ public double getResult() { return optima[0]; } /** {@inheritDoc} */ public double getAbsoluteAccuracy() { return optimizer.getAbsoluteAccuracy(); } /** {@inheritDoc} */ public int getIterationCount() { return totalIterations; } /** {@inheritDoc} */ public int getMaximalIterationCount() { return maxIterations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return totalEvaluations; } /** {@inheritDoc} */ public double getRelativeAccuracy() { return optimizer.getRelativeAccuracy(); } /** {@inheritDoc} */ public void resetAbsoluteAccuracy() { optimizer.resetAbsoluteAccuracy(); } /** {@inheritDoc} */ public void resetMaximalIterationCount() { optimizer.resetMaximalIterationCount(); } /** {@inheritDoc} */ public void resetRelativeAccuracy() { optimizer.resetRelativeAccuracy(); } /** {@inheritDoc} */ public void setAbsoluteAccuracy(double accuracy) { optimizer.setAbsoluteAccuracy(accuracy); } /** {@inheritDoc} */ public void setMaximalIterationCount(int count) { this.maxIterations = count; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public void setRelativeAccuracy(double accuracy) { optimizer.setRelativeAccuracy(accuracy); } /** Get all the optima found during the last call to {@link * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}. *

                    The optimizer stores all the optima found during a set of * restarts. The {@link #optimize(UnivariateRealFunction, GoalType, * double, double) optimize} method returns the best point only. This * method returns all the points found at the end of each starts, * including the best one already returned by the {@link * #optimize(UnivariateRealFunction, GoalType, double, double) optimize} * method. *

                    *

                    * The returned array as one element for each start as specified * in the constructor. It is ordered with the results from the * runs that did converge first, sorted from best to worst * objective value (i.e in ascending order if minimizing and in * descending order if maximizing), followed by Double.NaN elements * corresponding to the runs that did not converge. This means all * elements will be NaN if the {@link #optimize(UnivariateRealFunction, * GoalType, double, double) optimize} method did throw a {@link * ConvergenceException ConvergenceException}). This also means that * if the first element is not NaN, it is the best point found across * all starts.

                    * @return array containing the optima * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction, * GoalType, double, double) optimize} has not been called * @see #getOptimaValues() */ public double[] getOptima() throws IllegalStateException { if (optima == null) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET); } return optima.clone(); } /** Get all the function values at optima found during the last call to {@link * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}. *

                    * The returned array as one element for each start as specified * in the constructor. It is ordered with the results from the * runs that did converge first, sorted from best to worst * objective value (i.e in ascending order if minimizing and in * descending order if maximizing), followed by Double.NaN elements * corresponding to the runs that did not converge. This means all * elements will be NaN if the {@link #optimize(UnivariateRealFunction, * GoalType, double, double) optimize} method did throw a {@link * ConvergenceException ConvergenceException}). This also means that * if the first element is not NaN, it is the best point found across * all starts.

                    * @return array containing the optima * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction, * GoalType, double, double) optimize} has not been called * @see #getOptima() */ public double[] getOptimaValues() throws IllegalStateException { if (optimaValues == null) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET); } return optimaValues.clone(); } /** {@inheritDoc} */ public double optimize(final UnivariateRealFunction f, final GoalType goalType, final double min, final double max) throws ConvergenceException, FunctionEvaluationException { optima = new double[starts]; optimaValues = new double[starts]; totalIterations = 0; totalEvaluations = 0; // multi-start loop for (int i = 0; i < starts; ++i) { try { optimizer.setMaximalIterationCount(maxIterations - totalIterations); optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); final double bound1 = (i == 0) ? min : min + generator.nextDouble() * (max - min); final double bound2 = (i == 0) ? max : min + generator.nextDouble() * (max - min); optima[i] = optimizer.optimize(f, goalType, FastMath.min(bound1, bound2), FastMath.max(bound1, bound2)); optimaValues[i] = optimizer.getFunctionValue(); } catch (FunctionEvaluationException fee) { optima[i] = Double.NaN; optimaValues[i] = Double.NaN; } catch (ConvergenceException ce) { optima[i] = Double.NaN; optimaValues[i] = Double.NaN; } totalIterations += optimizer.getIterationCount(); totalEvaluations += optimizer.getEvaluations(); } // sort the optima from best to worst, followed by NaN elements int lastNaN = optima.length; for (int i = 0; i < lastNaN; ++i) { if (Double.isNaN(optima[i])) { optima[i] = optima[--lastNaN]; optima[lastNaN + 1] = Double.NaN; optimaValues[i] = optimaValues[--lastNaN]; optimaValues[lastNaN + 1] = Double.NaN; } } double currX = optima[0]; double currY = optimaValues[0]; for (int j = 1; j < lastNaN; ++j) { final double prevY = currY; currX = optima[j]; currY = optimaValues[j]; if ((goalType == GoalType.MAXIMIZE) ^ (currY < prevY)) { // the current element should be inserted closer to the beginning int i = j - 1; double mIX = optima[i]; double mIY = optimaValues[i]; while ((i >= 0) && ((goalType == GoalType.MAXIMIZE) ^ (currY < mIY))) { optima[i + 1] = mIX; optimaValues[i + 1] = mIY; if (i-- != 0) { mIX = optima[i]; mIY = optimaValues[i]; } else { mIX = Double.NaN; mIY = Double.NaN; } } optima[i + 1] = currX; optimaValues[i + 1] = currY; currX = optima[j]; currY = optimaValues[j]; } } if (Double.isNaN(optima[0])) { throw new OptimizationException( LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, starts); } // return the found point given the best objective function value return optima[0]; } /** {@inheritDoc} */ public double optimize(final UnivariateRealFunction f, final GoalType goalType, final double min, final double max, final double startValue) throws ConvergenceException, FunctionEvaluationException { return optimize(f, goalType, min, max); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/OptimizationException.java100644 1750 1750 4706 11532241244 32310 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * This class represents exceptions thrown by optimizers. * * @version $Revision: 1044015 $ $Date: 2010-12-09 17:06:26 +0100 (jeu. 09 déc. 2010) $ * @since 1.2 * @deprecated in 2.2 (to be removed in 3.0). */ public class OptimizationException extends ConvergenceException { /** Serializable version identifier. */ private static final long serialVersionUID = -4605887730798282127L; /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @deprecated as of 2.2 replaced by {@link #OptimizationException(Localizable, Object...)} */ @Deprecated public OptimizationException(String specifier, Object ... parts) { this(new DummyLocalizable(specifier), parts); } /** * Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public OptimizationException(Localizable specifier, Object ... parts) { super(specifier, parts); } /** * Create an exception with a given root cause. * @param cause the exception or error that caused this exception to be thrown */ public OptimizationException(Throwable cause) { super(cause); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/PowellOptimizer.java100644 1750 1750 24660 11532241244 32403 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.general.AbstractScalarDifferentiableOptimizer; import org.apache.commons.math.optimization.univariate.AbstractUnivariateRealOptimizer; import org.apache.commons.math.optimization.univariate.BracketFinder; import org.apache.commons.math.optimization.univariate.BrentOptimizer; /** * Powell algorithm. * This code is translated and adapted from the Python version of this * algorithm (as implemented in module {@code optimize.py} v0.5 of * SciPy). * * @version $Revision$ $Date$ * @since 2.2 */ public class PowellOptimizer extends AbstractScalarDifferentiableOptimizer { /** * Default relative tolerance for line search ({@value}). */ public static final double DEFAULT_LS_RELATIVE_TOLERANCE = 1e-7; /** * Default absolute tolerance for line search ({@value}). */ public static final double DEFAULT_LS_ABSOLUTE_TOLERANCE = 1e-11; /** * Line search. */ private final LineSearch line; /** * Constructor with default line search tolerances (see the * {@link #PowellOptimizer(double,double) other constructor}). */ public PowellOptimizer() { this(DEFAULT_LS_RELATIVE_TOLERANCE, DEFAULT_LS_ABSOLUTE_TOLERANCE); } /** * Constructor with default absolute line search tolerances (see * the {@link #PowellOptimizer(double,double) other constructor}). * * @param lsRelativeTolerance Relative error tolerance for * the line search algorithm ({@link BrentOptimizer}). */ public PowellOptimizer(double lsRelativeTolerance) { this(lsRelativeTolerance, DEFAULT_LS_ABSOLUTE_TOLERANCE); } /** * @param lsRelativeTolerance Relative error tolerance for * the line search algorithm ({@link BrentOptimizer}). * @param lsAbsoluteTolerance Relative error tolerance for * the line search algorithm ({@link BrentOptimizer}). */ public PowellOptimizer(double lsRelativeTolerance, double lsAbsoluteTolerance) { line = new LineSearch(lsRelativeTolerance, lsAbsoluteTolerance); } /** {@inheritDoc} */ @Override protected RealPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException { final double[] guess = point.clone(); final int n = guess.length; final double[][] direc = new double[n][n]; for (int i = 0; i < n; i++) { direc[i][i] = 1; } double[] x = guess; double fVal = computeObjectiveValue(x); double[] x1 = x.clone(); while (true) { incrementIterationsCounter(); double fX = fVal; double fX2 = 0; double delta = 0; int bigInd = 0; double alphaMin = 0; for (int i = 0; i < n; i++) { final double[] d = /* Arrays.*/ copyOf(direc[i], n); // Java 1.5 does not support Arrays.copyOf() fX2 = fVal; line.search(x, d); fVal = line.getValueAtOptimum(); alphaMin = line.getOptimum(); final double[][] result = newPointAndDirection(x, d, alphaMin); x = result[0]; if ((fX2 - fVal) > delta) { delta = fX2 - fVal; bigInd = i; } } final RealPointValuePair previous = new RealPointValuePair(x1, fX); final RealPointValuePair current = new RealPointValuePair(x, fVal); if (getConvergenceChecker().converged(getIterations(), previous, current)) { if (goal == GoalType.MINIMIZE) { return (fVal < fX) ? current : previous; } else { return (fVal > fX) ? current : previous; } } final double[] d = new double[n]; final double[] x2 = new double[n]; for (int i = 0; i < n; i++) { d[i] = x[i] - x1[i]; x2[i] = 2 * x[i] - x1[i]; } x1 = x.clone(); fX2 = computeObjectiveValue(x2); if (fX > fX2) { double t = 2 * (fX + fX2 - 2 * fVal); double temp = fX - fVal - delta; t *= temp * temp; temp = fX - fX2; t -= delta * temp * temp; if (t < 0.0) { line.search(x, d); fVal = line.getValueAtOptimum(); alphaMin = line.getOptimum(); final double[][] result = newPointAndDirection(x, d, alphaMin); x = result[0]; final int lastInd = n - 1; direc[bigInd] = direc[lastInd]; direc[lastInd] = result[1]; } } } } /** * Compute a new point (in the original space) and a new direction * vector, resulting from the line search. * The parameters {@code p} and {@code d} will be changed in-place. * * @param p Point used in the line search. * @param d Direction used in the line search. * @param optimum Optimum found by the line search. * @return a 2-element array containing the new point (at index 0) and * the new direction (at index 1). */ private double[][] newPointAndDirection(double[] p, double[] d, double optimum) { final int n = p.length; final double[][] result = new double[2][n]; final double[] nP = result[0]; final double[] nD = result[1]; for (int i = 0; i < n; i++) { nD[i] = d[i] * optimum; nP[i] = p[i] + nD[i]; } return result; } /** * Class for finding the minimum of the objective function along a given * direction. */ private class LineSearch { /** * Optimizer. */ private final AbstractUnivariateRealOptimizer optim = new BrentOptimizer(); /** * Automatic bracketing. */ private final BracketFinder bracket = new BracketFinder(); /** * Value of the optimum. */ private double optimum = Double.NaN; /** * Value of the objective function at the optimum. */ private double valueAtOptimum = Double.NaN; /** * @param relativeTolerance Relative tolerance. * @param absoluteTolerance Absolute tolerance. */ public LineSearch(double relativeTolerance, double absoluteTolerance) { optim.setRelativeAccuracy(relativeTolerance); optim.setAbsoluteAccuracy(absoluteTolerance); } /** * Find the minimum of the function {@code f(p + alpha * d)}. * * @param p Starting point. * @param d Search direction. * @throws FunctionEvaluationException if function cannot be evaluated at some test point * @throws OptimizationException if algorithm fails to converge */ public void search(final double[] p, final double[] d) throws OptimizationException, FunctionEvaluationException { // Reset. optimum = Double.NaN; valueAtOptimum = Double.NaN; try { final int n = p.length; final UnivariateRealFunction f = new UnivariateRealFunction() { public double value(double alpha) throws FunctionEvaluationException { final double[] x = new double[n]; for (int i = 0; i < n; i++) { x[i] = p[i] + alpha * d[i]; } final double obj; obj = computeObjectiveValue(x); return obj; } }; bracket.search(f, goal, 0, 1); optimum = optim.optimize(f, goal, bracket.getLo(), bracket.getHi(), bracket.getMid()); valueAtOptimum = optim.getFunctionValue(); } catch (MaxIterationsExceededException e) { throw new OptimizationException(e); } } /** * @return the optimum. */ public double getOptimum() { return optimum; } /** * @return the value of the function at the optimum. */ public double getValueAtOptimum() { return valueAtOptimum; } } /** * Java 1.5 does not support Arrays.copyOf() * * @param source the array to be copied * @param newLen the length of the copy to be returned * @return the copied array, truncated or padded as necessary. */ private double[] copyOf(double[] source, int newLen) { double[] output = new double[newLen]; System.arraycopy(source, 0, output, 0, Math.min(source.length, newLen)); return output; } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer100644 1750 1750 41177 11532241244 32563 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.MultivariateRealOptimizer; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealConvergenceChecker; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; /** * This class implements simplex-based direct search optimization * algorithms. * *

                    Direct search methods only use objective function values, they don't * need derivatives and don't either try to compute approximation of * the derivatives. According to a 1996 paper by Margaret H. Wright * (Direct * Search Methods: Once Scorned, Now Respectable), they are used * when either the computation of the derivative is impossible (noisy * functions, unpredictable discontinuities) or difficult (complexity, * computation cost). In the first cases, rather than an optimum, a * not too bad point is desired. In the latter cases, an * optimum is desired but cannot be reasonably found. In all cases * direct search methods can be useful.

                    * *

                    Simplex-based direct search methods are based on comparison of * the objective function values at the vertices of a simplex (which is a * set of n+1 points in dimension n) that is updated by the algorithms * steps.

                    * *

                    The initial configuration of the simplex can be set using either * {@link #setStartConfiguration(double[])} or {@link * #setStartConfiguration(double[][])}. If neither method has been called * before optimization is attempted, an explicit call to the first method * with all steps set to +1 is triggered, thus building a default * configuration from a unit hypercube. Each call to {@link * #optimize(MultivariateRealFunction, GoalType, double[]) optimize} will reuse * the current start configuration and move it such that its first vertex * is at the provided start point of the optimization. If the {@code optimize} * method is called to solve a different problem and the number of parameters * change, the start configuration will be reset to a default one with the * appropriate dimensions.

                    * *

                    If {@link #setConvergenceChecker(RealConvergenceChecker)} is not called, * a default {@link SimpleScalarValueChecker} is used.

                    * *

                    Convergence is checked by providing the worst points of * previous and current simplex to the convergence checker, not the best ones.

                    * *

                    This class is the base class performing the boilerplate simplex * initialization and handling. The simplex update by itself is * performed by the derived classes according to the implemented * algorithms.

                    * * implements MultivariateRealOptimizer since 2.0 * * @see MultivariateRealFunction * @see NelderMead * @see MultiDirectional * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public abstract class DirectSearchOptimizer implements MultivariateRealOptimizer { /** Simplex. */ protected RealPointValuePair[] simplex; /** Objective function. */ private MultivariateRealFunction f; /** Convergence checker. */ private RealConvergenceChecker checker; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed. */ private int iterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Start simplex configuration. */ private double[][] startConfiguration; /** Simple constructor. */ protected DirectSearchOptimizer() { setConvergenceChecker(new SimpleScalarValueChecker()); setMaxIterations(Integer.MAX_VALUE); setMaxEvaluations(Integer.MAX_VALUE); } /** Set start configuration for simplex. *

                    The start configuration for simplex is built from a box parallel to * the canonical axes of the space. The simplex is the subset of vertices * of a box parallel to the canonical axes. It is built as the path followed * while traveling from one vertex of the box to the diagonally opposite * vertex moving only along the box edges. The first vertex of the box will * be located at the start point of the optimization.

                    *

                    As an example, in dimension 3 a simplex has 4 vertices. Setting the * steps to (1, 10, 2) and the start point to (1, 1, 1) would imply the * start simplex would be: { (1, 1, 1), (2, 1, 1), (2, 11, 1), (2, 11, 3) }. * The first vertex would be set to the start point at (1, 1, 1) and the * last vertex would be set to the diagonally opposite vertex at (2, 11, 3).

                    * @param steps steps along the canonical axes representing box edges, * they may be negative but not null * @exception IllegalArgumentException if one step is null */ public void setStartConfiguration(final double[] steps) throws IllegalArgumentException { // only the relative position of the n final vertices with respect // to the first one are stored final int n = steps.length; startConfiguration = new double[n][n]; for (int i = 0; i < n; ++i) { final double[] vertexI = startConfiguration[i]; for (int j = 0; j < i + 1; ++j) { if (steps[j] == 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, j, j + 1); } System.arraycopy(steps, 0, vertexI, 0, j + 1); } } } /** Set start configuration for simplex. *

                    The real initial simplex will be set up by moving the reference * simplex such that its first point is located at the start point of the * optimization.

                    * @param referenceSimplex reference simplex * @exception IllegalArgumentException if the reference simplex does not * contain at least one point, or if there is a dimension mismatch * in the reference simplex or if one of its vertices is duplicated */ public void setStartConfiguration(final double[][] referenceSimplex) throws IllegalArgumentException { // only the relative position of the n final vertices with respect // to the first one are stored final int n = referenceSimplex.length - 1; if (n < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SIMPLEX_NEED_ONE_POINT); } startConfiguration = new double[n][n]; final double[] ref0 = referenceSimplex[0]; // vertices loop for (int i = 0; i < n + 1; ++i) { final double[] refI = referenceSimplex[i]; // safety checks if (refI.length != n) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, refI.length, n); } for (int j = 0; j < i; ++j) { final double[] refJ = referenceSimplex[j]; boolean allEquals = true; for (int k = 0; k < n; ++k) { if (refI[k] != refJ[k]) { allEquals = false; break; } } if (allEquals) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, i, j); } } // store vertex i position relative to vertex 0 position if (i > 0) { final double[] confI = startConfiguration[i - 1]; for (int k = 0; k < n; ++k) { confI[k] = refI[k] - ref0[k]; } } } } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getIterations() { return iterations; } /** {@inheritDoc} */ public int getEvaluations() { return evaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { this.checker = convergenceChecker; } /** {@inheritDoc} */ public RealConvergenceChecker getConvergenceChecker() { return checker; } /** {@inheritDoc} */ public RealPointValuePair optimize(final MultivariateRealFunction function, final GoalType goalType, final double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { if ((startConfiguration == null) || (startConfiguration.length != startPoint.length)) { // no initial configuration has been set up for simplex // build a default one from a unit hypercube final double[] unit = new double[startPoint.length]; Arrays.fill(unit, 1.0); setStartConfiguration(unit); } this.f = function; final Comparator comparator = new Comparator() { public int compare(final RealPointValuePair o1, final RealPointValuePair o2) { final double v1 = o1.getValue(); final double v2 = o2.getValue(); return (goalType == GoalType.MINIMIZE) ? Double.compare(v1, v2) : Double.compare(v2, v1); } }; // initialize search iterations = 0; evaluations = 0; buildSimplex(startPoint); evaluateSimplex(comparator); RealPointValuePair[] previous = new RealPointValuePair[simplex.length]; while (true) { if (iterations > 0) { boolean converged = true; for (int i = 0; i < simplex.length; ++i) { converged &= checker.converged(iterations, previous[i], simplex[i]); } if (converged) { // we have found an optimum return simplex[0]; } } // we still need to search System.arraycopy(simplex, 0, previous, 0, simplex.length); iterateSimplex(comparator); } } /** Increment the iterations counter by 1. * @exception OptimizationException if the maximal number * of iterations is exceeded */ protected void incrementIterationsCounter() throws OptimizationException { if (++iterations > maxIterations) { throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); } } /** Compute the next simplex of the algorithm. * @param comparator comparator to use to sort simplex vertices from best to worst * @exception FunctionEvaluationException if the function cannot be evaluated at * some point * @exception OptimizationException if the algorithm fails to converge * @exception IllegalArgumentException if the start point dimension is wrong */ protected abstract void iterateSimplex(final Comparator comparator) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; /** Evaluate the objective function on one point. *

                    A side effect of this method is to count the number of * function evaluations

                    * @param x point on which the objective function should be evaluated * @return objective function value at the given point * @exception FunctionEvaluationException if no value can be computed for the * parameters or if the maximal number of evaluations is exceeded * @exception IllegalArgumentException if the start point dimension is wrong */ protected double evaluate(final double[] x) throws FunctionEvaluationException, IllegalArgumentException { if (++evaluations > maxEvaluations) { throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), x); } return f.value(x); } /** Build an initial simplex. * @param startPoint the start point for optimization * @exception IllegalArgumentException if the start point does not match * simplex dimension */ private void buildSimplex(final double[] startPoint) throws IllegalArgumentException { final int n = startPoint.length; if (n != startConfiguration.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, startConfiguration.length); } // set first vertex simplex = new RealPointValuePair[n + 1]; simplex[0] = new RealPointValuePair(startPoint, Double.NaN); // set remaining vertices for (int i = 0; i < n; ++i) { final double[] confI = startConfiguration[i]; final double[] vertexI = new double[n]; for (int k = 0; k < n; ++k) { vertexI[k] = startPoint[k] + confI[k]; } simplex[i + 1] = new RealPointValuePair(vertexI, Double.NaN); } } /** Evaluate all the non-evaluated points of the simplex. * @param comparator comparator to use to sort simplex vertices from best to worst * @exception FunctionEvaluationException if no value can be computed for the parameters * @exception OptimizationException if the maximal number of evaluations is exceeded */ protected void evaluateSimplex(final Comparator comparator) throws FunctionEvaluationException, OptimizationException { // evaluate the objective function at all non-evaluated simplex points for (int i = 0; i < simplex.length; ++i) { final RealPointValuePair vertex = simplex[i]; final double[] point = vertex.getPointRef(); if (Double.isNaN(vertex.getValue())) { simplex[i] = new RealPointValuePair(point, evaluate(point), false); } } // sort the simplex from best to worst Arrays.sort(simplex, comparator); } /** Replace the worst point of the simplex by a new point. * @param pointValuePair point to insert * @param comparator comparator to use to sort simplex vertices from best to worst */ protected void replaceWorstPoint(RealPointValuePair pointValuePair, final Comparator comparator) { int n = simplex.length - 1; for (int i = 0; i < n; ++i) { if (comparator.compare(simplex[i], pointValuePair) > 0) { RealPointValuePair tmp = simplex[i]; simplex[i] = pointValuePair; pointValuePair = tmp; } } simplex[n] = pointValuePair; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/package.html100644 1750 1750 1663 11532241244 30632 0ustarlucluc 0 0

                    This package provides optimization algorithms that don't require derivatives.

                    ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java100644 1750 1750 12440 11532241244 32477 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import java.util.Comparator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealConvergenceChecker; import org.apache.commons.math.optimization.RealPointValuePair; /** * This class implements the multi-directional direct search method. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @see NelderMead * @since 1.2 */ public class MultiDirectional extends DirectSearchOptimizer { /** Expansion coefficient. */ private final double khi; /** Contraction coefficient. */ private final double gamma; /** Build a multi-directional optimizer with default coefficients. *

                    The default values are 2.0 for khi and 0.5 for gamma.

                    */ public MultiDirectional() { this.khi = 2.0; this.gamma = 0.5; } /** Build a multi-directional optimizer with specified coefficients. * @param khi expansion coefficient * @param gamma contraction coefficient */ public MultiDirectional(final double khi, final double gamma) { this.khi = khi; this.gamma = gamma; } /** {@inheritDoc} */ @Override protected void iterateSimplex(final Comparator comparator) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { final RealConvergenceChecker checker = getConvergenceChecker(); while (true) { incrementIterationsCounter(); // save the original vertex final RealPointValuePair[] original = simplex; final RealPointValuePair best = original[0]; // perform a reflection step final RealPointValuePair reflected = evaluateNewSimplex(original, 1.0, comparator); if (comparator.compare(reflected, best) < 0) { // compute the expanded simplex final RealPointValuePair[] reflectedSimplex = simplex; final RealPointValuePair expanded = evaluateNewSimplex(original, khi, comparator); if (comparator.compare(reflected, expanded) <= 0) { // accept the reflected simplex simplex = reflectedSimplex; } return; } // compute the contracted simplex final RealPointValuePair contracted = evaluateNewSimplex(original, gamma, comparator); if (comparator.compare(contracted, best) < 0) { // accept the contracted simplex return; } // check convergence final int iter = getIterations(); boolean converged = true; for (int i = 0; i < simplex.length; ++i) { converged &= checker.converged(iter, original[i], simplex[i]); } if (converged) { return; } } } /** Compute and evaluate a new simplex. * @param original original simplex (to be preserved) * @param coeff linear coefficient * @param comparator comparator to use to sort simplex vertices from best to poorest * @return best point in the transformed simplex * @exception FunctionEvaluationException if the function cannot be evaluated at some point * @exception OptimizationException if the maximal number of evaluations is exceeded */ private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original, final double coeff, final Comparator comparator) throws FunctionEvaluationException, OptimizationException { final double[] xSmallest = original[0].getPointRef(); final int n = xSmallest.length; // create the linearly transformed simplex simplex = new RealPointValuePair[n + 1]; simplex[0] = original[0]; for (int i = 1; i <= n; ++i) { final double[] xOriginal = original[i].getPointRef(); final double[] xTransformed = new double[n]; for (int j = 0; j < n; ++j) { xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]); } simplex[i] = new RealPointValuePair(xTransformed, Double.NaN, false); } // evaluate it evaluateSimplex(comparator); return simplex[0]; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/direct/NelderMead.java100644 1750 1750 14444 11532241244 31235 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.direct; import java.util.Comparator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; /** * This class implements the Nelder-Mead direct search method. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @see MultiDirectional * @since 1.2 */ public class NelderMead extends DirectSearchOptimizer { /** Reflection coefficient. */ private final double rho; /** Expansion coefficient. */ private final double khi; /** Contraction coefficient. */ private final double gamma; /** Shrinkage coefficient. */ private final double sigma; /** Build a Nelder-Mead optimizer with default coefficients. *

                    The default coefficients are 1.0 for rho, 2.0 for khi and 0.5 * for both gamma and sigma.

                    */ public NelderMead() { this.rho = 1.0; this.khi = 2.0; this.gamma = 0.5; this.sigma = 0.5; } /** Build a Nelder-Mead optimizer with specified coefficients. * @param rho reflection coefficient * @param khi expansion coefficient * @param gamma contraction coefficient * @param sigma shrinkage coefficient */ public NelderMead(final double rho, final double khi, final double gamma, final double sigma) { this.rho = rho; this.khi = khi; this.gamma = gamma; this.sigma = sigma; } /** {@inheritDoc} */ @Override protected void iterateSimplex(final Comparator comparator) throws FunctionEvaluationException, OptimizationException { incrementIterationsCounter(); // the simplex has n+1 point if dimension is n final int n = simplex.length - 1; // interesting values final RealPointValuePair best = simplex[0]; final RealPointValuePair secondBest = simplex[n-1]; final RealPointValuePair worst = simplex[n]; final double[] xWorst = worst.getPointRef(); // compute the centroid of the best vertices // (dismissing the worst point at index n) final double[] centroid = new double[n]; for (int i = 0; i < n; ++i) { final double[] x = simplex[i].getPointRef(); for (int j = 0; j < n; ++j) { centroid[j] += x[j]; } } final double scaling = 1.0 / n; for (int j = 0; j < n; ++j) { centroid[j] *= scaling; } // compute the reflection point final double[] xR = new double[n]; for (int j = 0; j < n; ++j) { xR[j] = centroid[j] + rho * (centroid[j] - xWorst[j]); } final RealPointValuePair reflected = new RealPointValuePair(xR, evaluate(xR), false); if ((comparator.compare(best, reflected) <= 0) && (comparator.compare(reflected, secondBest) < 0)) { // accept the reflected point replaceWorstPoint(reflected, comparator); } else if (comparator.compare(reflected, best) < 0) { // compute the expansion point final double[] xE = new double[n]; for (int j = 0; j < n; ++j) { xE[j] = centroid[j] + khi * (xR[j] - centroid[j]); } final RealPointValuePair expanded = new RealPointValuePair(xE, evaluate(xE), false); if (comparator.compare(expanded, reflected) < 0) { // accept the expansion point replaceWorstPoint(expanded, comparator); } else { // accept the reflected point replaceWorstPoint(reflected, comparator); } } else { if (comparator.compare(reflected, worst) < 0) { // perform an outside contraction final double[] xC = new double[n]; for (int j = 0; j < n; ++j) { xC[j] = centroid[j] + gamma * (xR[j] - centroid[j]); } final RealPointValuePair outContracted = new RealPointValuePair(xC, evaluate(xC), false); if (comparator.compare(outContracted, reflected) <= 0) { // accept the contraction point replaceWorstPoint(outContracted, comparator); return; } } else { // perform an inside contraction final double[] xC = new double[n]; for (int j = 0; j < n; ++j) { xC[j] = centroid[j] - gamma * (centroid[j] - xWorst[j]); } final RealPointValuePair inContracted = new RealPointValuePair(xC, evaluate(xC), false); if (comparator.compare(inContracted, worst) < 0) { // accept the contraction point replaceWorstPoint(inContracted, comparator); return; } } // perform a shrink final double[] xSmallest = simplex[0].getPointRef(); for (int i = 1; i < simplex.length; ++i) { final double[] x = simplex[i].getPoint(); for (int j = 0; j < n; ++j) { x[j] = xSmallest[j] + sigma * (x[j] - xSmallest[j]); } simplex[i] = new RealPointValuePair(x, Double.NaN, false); } evaluateSimplex(comparator); } } } ././@LongLink100644 0 0 204 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMult100644 1750 1750 22335 11532241244 32637 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomVectorGenerator; /** * Special implementation of the {@link DifferentiableMultivariateVectorialOptimizer} interface adding * multi-start features to an existing optimizer. *

                    * This class wraps a classical optimizer to use it several times in * turn with different starting points in order to avoid being trapped * into a local extremum when looking for a global one. *

                    * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class MultiStartDifferentiableMultivariateVectorialOptimizer implements DifferentiableMultivariateVectorialOptimizer { /** Serializable version identifier. */ private static final long serialVersionUID = 9206382258980561530L; /** Underlying classical optimizer. */ private final DifferentiableMultivariateVectorialOptimizer optimizer; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed for all starts. */ private int totalIterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed for all starts. */ private int totalEvaluations; /** Number of jacobian evaluations already performed for all starts. */ private int totalJacobianEvaluations; /** Number of starts to go. */ private int starts; /** Random generator for multi-start. */ private RandomVectorGenerator generator; /** Found optima. */ private VectorialPointValuePair[] optima; /** * Create a multi-start optimizer from a single-start optimizer * @param optimizer single-start optimizer to wrap * @param starts number of starts to perform (including the * first one), multi-start is disabled if value is less than or * equal to 1 * @param generator random vector generator to use for restarts */ public MultiStartDifferentiableMultivariateVectorialOptimizer( final DifferentiableMultivariateVectorialOptimizer optimizer, final int starts, final RandomVectorGenerator generator) { this.optimizer = optimizer; this.totalIterations = 0; this.totalEvaluations = 0; this.totalJacobianEvaluations = 0; this.starts = starts; this.generator = generator; this.optima = null; setMaxIterations(Integer.MAX_VALUE); setMaxEvaluations(Integer.MAX_VALUE); } /** Get all the optima found during the last call to {@link * #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize}. *

                    The optimizer stores all the optima found during a set of * restarts. The {@link #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize} method returns the * best point only. This method returns all the points found at the * end of each starts, including the best one already returned by the {@link * #optimize(DifferentiableMultivariateVectorialFunction, double[], * double[], double[]) optimize} method. *

                    *

                    * The returned array as one element for each start as specified * in the constructor. It is ordered with the results from the * runs that did converge first, sorted from best to worst * objective value (i.e in ascending order if minimizing and in * descending order if maximizing), followed by and null elements * corresponding to the runs that did not converge. This means all * elements will be null if the {@link #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize} method did throw a {@link * org.apache.commons.math.ConvergenceException ConvergenceException}). * This also means that if the first element is non null, it is the best * point found across all starts.

                    * @return array containing the optima * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize} has not been called */ public VectorialPointValuePair[] getOptima() throws IllegalStateException { if (optima == null) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET); } return optima.clone(); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return totalIterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return totalEvaluations; } /** {@inheritDoc} */ public int getJacobianEvaluations() { return totalJacobianEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(VectorialConvergenceChecker checker) { optimizer.setConvergenceChecker(checker); } /** {@inheritDoc} */ public VectorialConvergenceChecker getConvergenceChecker() { return optimizer.getConvergenceChecker(); } /** {@inheritDoc} */ public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f, final double[] target, final double[] weights, final double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { optima = new VectorialPointValuePair[starts]; totalIterations = 0; totalEvaluations = 0; totalJacobianEvaluations = 0; // multi-start loop for (int i = 0; i < starts; ++i) { try { optimizer.setMaxIterations(maxIterations - totalIterations); optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); optima[i] = optimizer.optimize(f, target, weights, (i == 0) ? startPoint : generator.nextVector()); } catch (FunctionEvaluationException fee) { optima[i] = null; } catch (OptimizationException oe) { optima[i] = null; } totalIterations += optimizer.getIterations(); totalEvaluations += optimizer.getEvaluations(); totalJacobianEvaluations += optimizer.getJacobianEvaluations(); } // sort the optima from best to worst, followed by null elements Arrays.sort(optima, new Comparator() { public int compare(final VectorialPointValuePair o1, final VectorialPointValuePair o2) { if (o1 == null) { return (o2 == null) ? 0 : +1; } else if (o2 == null) { return -1; } return Double.compare(weightedResidual(o1), weightedResidual(o2)); } private double weightedResidual(final VectorialPointValuePair pv) { final double[] value = pv.getValueRef(); double sum = 0; for (int i = 0; i < value.length; ++i) { final double ri = value[i] - target[i]; sum += weights[i] * ri * ri; } return sum; } }); if (optima[0] == null) { throw new OptimizationException( LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, starts); } // return the found point given the best objective function value return optima[0]; } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleVectorialValueChecker.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleVectorialValueChecker.100644 1750 1750 7173 11532241244 32466 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Simple implementation of the {@link VectorialConvergenceChecker} interface using * only objective function values. *

                    * Convergence is considered to have been reached if either the relative * difference between the objective function values is smaller than a * threshold or if either the absolute difference between the objective * function values is smaller than another threshold for all vectors elements. *

                    * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class SimpleVectorialValueChecker implements VectorialConvergenceChecker { /** Default relative threshold. */ private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; /** Default absolute threshold. */ private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; /** Relative tolerance threshold. */ private final double relativeThreshold; /** Absolute tolerance threshold. */ private final double absoluteThreshold; /** Build an instance with default threshold. */ public SimpleVectorialValueChecker() { this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; } /** Build an instance with a specified threshold. *

                    * In order to perform only relative checks, the absolute tolerance * must be set to a negative value. In order to perform only absolute * checks, the relative tolerance must be set to a negative value. *

                    * @param relativeThreshold relative tolerance threshold * @param absoluteThreshold absolute tolerance threshold */ public SimpleVectorialValueChecker(final double relativeThreshold, final double absoluteThreshold) { this.relativeThreshold = relativeThreshold; this.absoluteThreshold = absoluteThreshold; } /** {@inheritDoc} */ public boolean converged(final int iteration, final VectorialPointValuePair previous, final VectorialPointValuePair current) { final double[] p = previous.getValueRef(); final double[] c = current.getValueRef(); for (int i = 0; i < p.length; ++i) { final double pi = p[i]; final double ci = c[i]; final double difference = FastMath.abs(pi - ci); final double size = FastMath.max(FastMath.abs(pi), FastMath.abs(ci)); if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) { return false; } } return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java100644 1750 1750 21071 11532241244 32261 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.RealMatrix; /** This class converts {@link MultivariateVectorialFunction vectorial * objective functions} to {@link MultivariateRealFunction scalar objective functions} * when the goal is to minimize them. *

                    * This class is mostly used when the vectorial objective function represents * a theoretical result computed from a point set applied to a model and * the models point must be adjusted to fit the theoretical result to some * reference observations. The observations may be obtained for example from * physical measurements whether the model is built from theoretical * considerations. *

                    *

                    * This class computes a possibly weighted squared sum of the residuals, which is * a scalar value. The residuals are the difference between the theoretical model * (i.e. the output of the vectorial objective function) and the observations. The * class implements the {@link MultivariateRealFunction} interface and can therefore be * minimized by any optimizer supporting scalar objectives functions.This is one way * to perform a least square estimation. There are other ways to do this without using * this converter, as some optimization algorithms directly support vectorial objective * functions. *

                    *

                    * This class support combination of residuals with or without weights and correlations. *

                    * * @see MultivariateRealFunction * @see MultivariateVectorialFunction * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public class LeastSquaresConverter implements MultivariateRealFunction { /** Underlying vectorial function. */ private final MultivariateVectorialFunction function; /** Observations to be compared to objective function to compute residuals. */ private final double[] observations; /** Optional weights for the residuals. */ private final double[] weights; /** Optional scaling matrix (weight and correlations) for the residuals. */ private final RealMatrix scale; /** Build a simple converter for uncorrelated residuals with the same weight. * @param function vectorial residuals function to wrap * @param observations observations to be compared to objective function to compute residuals */ public LeastSquaresConverter(final MultivariateVectorialFunction function, final double[] observations) { this.function = function; this.observations = observations.clone(); this.weights = null; this.scale = null; } /** Build a simple converter for uncorrelated residuals with the specific weights. *

                    * The scalar objective function value is computed as: *

                         * objective = ∑weighti(observationi-objectivei)2
                         * 
                    *

                    *

                    * Weights can be used for example to combine residuals with different standard * deviations. As an example, consider a residuals array in which even elements * are angular measurements in degrees with a 0.01° standard deviation and * odd elements are distance measurements in meters with a 15m standard deviation. * In this case, the weights array should be initialized with value * 1.0/(0.012) in the even elements and 1.0/(15.02) in the * odd elements (i.e. reciprocals of variances). *

                    *

                    * The array computed by the objective function, the observations array and the * weights array must have consistent sizes or a {@link FunctionEvaluationException} will be * triggered while computing the scalar objective. *

                    * @param function vectorial residuals function to wrap * @param observations observations to be compared to objective function to compute residuals * @param weights weights to apply to the residuals * @exception IllegalArgumentException if the observations vector and the weights * vector dimensions don't match (objective function dimension is checked only when * the {@link #value(double[])} method is called) */ public LeastSquaresConverter(final MultivariateVectorialFunction function, final double[] observations, final double[] weights) throws IllegalArgumentException { if (observations.length != weights.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, observations.length, weights.length); } this.function = function; this.observations = observations.clone(); this.weights = weights.clone(); this.scale = null; } /** Build a simple converter for correlated residuals with the specific weights. *

                    * The scalar objective function value is computed as: *

                         * objective = yTy with y = scale×(observation-objective)
                         * 
                    *

                    *

                    * The array computed by the objective function, the observations array and the * the scaling matrix must have consistent sizes or a {@link FunctionEvaluationException} * will be triggered while computing the scalar objective. *

                    * @param function vectorial residuals function to wrap * @param observations observations to be compared to objective function to compute residuals * @param scale scaling matrix * @exception IllegalArgumentException if the observations vector and the scale * matrix dimensions don't match (objective function dimension is checked only when * the {@link #value(double[])} method is called) */ public LeastSquaresConverter(final MultivariateVectorialFunction function, final double[] observations, final RealMatrix scale) throws IllegalArgumentException { if (observations.length != scale.getColumnDimension()) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, observations.length, scale.getColumnDimension()); } this.function = function; this.observations = observations.clone(); this.weights = null; this.scale = scale.copy(); } /** {@inheritDoc} */ public double value(final double[] point) throws FunctionEvaluationException { // compute residuals final double[] residuals = function.value(point); if (residuals.length != observations.length) { throw new FunctionEvaluationException(point,LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, residuals.length, observations.length); } for (int i = 0; i < residuals.length; ++i) { residuals[i] -= observations[i]; } // compute sum of squares double sumSquares = 0; if (weights != null) { for (int i = 0; i < residuals.length; ++i) { final double ri = residuals[i]; sumSquares += weights[i] * ri * ri; } } else if (scale != null) { for (final double yi : scale.operate(residuals)) { sumSquares += yi * yi; } } else { for (final double ri : residuals) { sumSquares += ri * ri; } } return sumSquares; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/VectorialPointValuePair.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/VectorialPointValuePair.java100644 1750 1750 7477 11532241244 32526 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.io.Serializable; /** * This class holds a point and the vectorial value of an objective function at this point. *

                    This is a simple immutable container.

                    * @see RealPointValuePair * @see org.apache.commons.math.analysis.MultivariateVectorialFunction * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $ * @since 2.0 */ public class VectorialPointValuePair implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 1003888396256744753L; /** Point coordinates. */ private final double[] point; /** Vectorial value of the objective function at the point. */ private final double[] value; /** Build a point/objective function value pair. * @param point point coordinates (the built instance will store * a copy of the array, not the array passed as argument) * @param value value of an objective function at the point */ public VectorialPointValuePair(final double[] point, final double[] value) { this.point = (point == null) ? null : point.clone(); this.value = (value == null) ? null : value.clone(); } /** Build a point/objective function value pair. * @param point point coordinates (the built instance will store * a copy of the array, not the array passed as argument) * @param value value of an objective function at the point * @param copyArray if true, the input arrays will be copied, otherwise * they will be referenced */ public VectorialPointValuePair(final double[] point, final double[] value, final boolean copyArray) { this.point = copyArray ? ((point == null) ? null : point.clone()) : point; this.value = copyArray ? ((value == null) ? null : value.clone()) : value; } /** Get the point. * @return a copy of the stored point */ public double[] getPoint() { return (point == null) ? null : point.clone(); } /** Get a reference to the point. *

                    This method is provided as a convenience to avoid copying * the array, the elements of the array should not be modified.

                    * @return a reference to the internal array storing the point */ public double[] getPointRef() { return point; } /** Get the value of the objective function. * @return a copy of the stored value of the objective function */ public double[] getValue() { return (value == null) ? null : value.clone(); } /** Get a reference to the value of the objective function. *

                    This method is provided as a convenience to avoid copying * the array, the elements of the array should not be modified.

                    * @return a reference to the internal array storing the value of the objective function */ public double[] getValueRef() { return value; } } ././@LongLink100644 0 0 172 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateVe100644 1750 1750 11175 11532241244 32626 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.FunctionEvaluationException; /** * This interface represents an optimization algorithm for {@link DifferentiableMultivariateVectorialFunction * vectorial differentiable objective functions}. *

                    Optimization algorithms find the input point set that either {@link GoalType * maximize or minimize} an objective function.

                    * @see MultivariateRealOptimizer * @see DifferentiableMultivariateRealOptimizer * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface DifferentiableMultivariateVectorialOptimizer { /** Set the maximal number of iterations of the algorithm. * @param maxIterations maximal number of function calls * . */ void setMaxIterations(int maxIterations); /** Get the maximal number of iterations of the algorithm. * @return maximal number of iterations */ int getMaxIterations(); /** Get the number of iterations realized by the algorithm. * @return number of iterations */ int getIterations(); /** Set the maximal number of functions evaluations. * @param maxEvaluations maximal number of function evaluations */ void setMaxEvaluations(int maxEvaluations); /** Get the maximal number of functions evaluations. * @return maximal number of functions evaluations */ int getMaxEvaluations(); /** Get the number of evaluations of the objective function. *

                    * The number of evaluation correspond to the last call to the * {@link #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize} method. It is 0 if * the method has not been called yet. *

                    * @return number of evaluations of the objective function */ int getEvaluations(); /** Get the number of evaluations of the objective function jacobian . *

                    * The number of evaluation correspond to the last call to the * {@link #optimize(DifferentiableMultivariateVectorialFunction, * double[], double[], double[]) optimize} method. It is 0 if * the method has not been called yet. *

                    * @return number of evaluations of the objective function jacobian */ int getJacobianEvaluations(); /** Set the convergence checker. * @param checker object to use to check for convergence */ void setConvergenceChecker(VectorialConvergenceChecker checker); /** Get the convergence checker. * @return object used to check for convergence */ VectorialConvergenceChecker getConvergenceChecker(); /** Optimizes an objective function. *

                    * Optimization is considered to be a weighted least-squares minimization. * The cost function to be minimized is * ∑weighti(objectivei-targeti)2 *

                    * @param f objective function * @param target target value for the objective functions at optimum * @param weights weight for the least squares cost computation * @param startPoint the start point for optimization * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ VectorialPointValuePair optimize(DifferentiableMultivariateVectorialFunction f, double[] target, double[] weights, double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/UnivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/UnivariateRealOptimizer.java100644 1750 1750 11573 11532241244 32601 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.ConvergingAlgorithm; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface for (univariate real) optimization algorithms. * * @version $Revision: 1073658 $ $Date: 2011-02-23 10:45:42 +0100 (mer. 23 févr. 2011) $ * @since 2.0 */ public interface UnivariateRealOptimizer extends ConvergingAlgorithm { /** Set the maximal number of functions evaluations. * @param maxEvaluations maximal number of function evaluations */ void setMaxEvaluations(int maxEvaluations); /** Get the maximal number of functions evaluations. * @return the maximal number of functions evaluations. */ int getMaxEvaluations(); /** Get the number of evaluations of the objective function. *

                    * The number of evaluations corresponds to the last call to the * {@link #optimize(UnivariateRealFunction, GoalType, double, double) optimize} * method. It is 0 if the method has not been called yet. *

                    * @return the number of evaluations of the objective function. */ int getEvaluations(); /** * Find an optimum in the given interval. *

                    * An optimizer may require that the interval brackets a single optimum. *

                    * @param f the function to optimize. * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE}. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @return a value where the function is optimum. * @throws ConvergenceException if the maximum iteration count is exceeded * or the optimizer detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function. * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the optimizer. */ double optimize(UnivariateRealFunction f, GoalType goalType, double min, double max) throws ConvergenceException, FunctionEvaluationException; /** * Find an optimum in the given interval, start at startValue. *

                    * An optimizer may require that the interval brackets a single optimum. *

                    * @param f the function to optimize. * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE}. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param startValue the start value to use. * @return a value where the function is optimum. * @throws ConvergenceException if the maximum iteration count is exceeded * or the optimizer detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function. * @throws IllegalArgumentException if min > max or the arguments do not * satisfy the requirements specified by the optimizer. * @throws IllegalStateException if there are no data. */ double optimize(UnivariateRealFunction f, GoalType goalType, double min, double max, double startValue) throws ConvergenceException, FunctionEvaluationException; /** * Get the result of the last run of the optimizer. * * @return the optimum. * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed. */ double getResult(); /** * Get the result of the last run of the optimizer. * * @return the value of the function at the optimum. * @throws FunctionEvaluationException if an error occurs evaluating the function. * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed. */ double getFunctionValue() throws FunctionEvaluationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/package.html100644 1750 1750 7363 11532241244 27363 0ustarlucluc 0 0

                    This package provides common interfaces for the optimization algorithms provided in sub-packages. The main interfaces defines optimizers and convergence checkers. The functions that are optimized by the algorithms provided by this package and its sub-packages are a subset of the one defined in the analysis package, namely the real and vector valued functions. These functions are called objective function here. When the goal is to minimize, the functions are often called cost function, this name is not used in this package.

                    Optimizers are the algorithms that will either minimize or maximize, the objective function by changing its input variables set until an optimal set is found. There are only four interfaces defining the common behavior of optimizers, one for each supported type of objective function:

                    • {@link org.apache.commons.math.optimization.UnivariateRealOptimizer UnivariateRealOptimizer} for {@link org.apache.commons.math.analysis.UnivariateRealFunction univariate real functions}
                    • {@link org.apache.commons.math.optimization.MultivariateRealOptimizer MultivariateRealOptimizer} for {@link org.apache.commons.math.analysis.MultivariateRealFunction multivariate real functions}
                    • {@link org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer DifferentiableMultivariateRealOptimizer} for {@link org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction differentiable multivariate real functions}
                    • {@link org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer DifferentiableMultivariateVectorialOptimizer} for {@link org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction differentiable multivariate vectorial functions}

                    Despite there are only four types of supported optimizers, it is possible to optimize a transform a {@link org.apache.commons.math.analysis.MultivariateVectorialFunction non-differentiable multivariate vectorial function} by converting it to a {@link org.apache.commons.math.analysis.MultivariateRealFunction non-differentiable multivariate real function} thanks to the {@link org.apache.commons.math.optimization.LeastSquaresConverter LeastSquaresConverter} helper class. The transformed function can be optimized using any implementation of the {@link org.apache.commons.math.optimization.MultivariateRealOptimizer MultivariateRealOptimizer} interface.

                    For each of the four types of supported optimizers, there is a special implementation which wraps a classical optimizer in order to add it a multi-start feature. This feature call the underlying optimizer several times in sequence with different starting points and returns the best optimum found or all optima if desired. This is a classical way to prevent being trapped into a local extremum when looking for a global one.

                    commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/GoalType.java100644 1750 1750 2224 11532241244 27460 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.io.Serializable; /** * Goal type for an optimization problem. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public enum GoalType implements Serializable { /** Maximization goal. */ MAXIMIZE, /** Minimization goal. */ MINIMIZE } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/ConjugateGradientFormula.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/ConjugateGradientFor100644 1750 1750 3563 11532241244 32504 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; /** * Available choices of update formulas for the β parameter * in {@link NonLinearConjugateGradientOptimizer}. *

                    * The β parameter is used to compute the successive conjugate * search directions. For non-linear conjugate gradients, there are * two formulas to compute β: *

                      *
                    • Fletcher-Reeves formula
                    • *
                    • Polak-Ribière formula
                    • *
                    * On the one hand, the Fletcher-Reeves formula is guaranteed to converge * if the start point is close enough of the optimum whether the * Polak-Ribière formula may not converge in rare cases. On the * other hand, the Polak-Ribière formula is often faster when it * does converge. Polak-Ribière is often used. *

                    * @see NonLinearConjugateGradientOptimizer * @version $Revision: 758059 $ $Date: 2009-03-24 23:16:21 +0100 (mar. 24 mars 2009) $ * @since 2.0 */ public enum ConjugateGradientFormula { /** Fletcher-Reeves formula. */ FLETCHER_REEVES, /** Polak-Ribière formula. */ POLAK_RIBIERE } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOp100644 1750 1750 105605 11532241244 32571 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import java.util.Arrays; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.VectorialPointValuePair; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * This class solves a least squares problem using the Levenberg-Marquardt algorithm. * *

                    This implementation should work even for over-determined systems * (i.e. systems having more point than equations). Over-determined systems * are solved by ignoring the point which have the smallest impact according * to their jacobian column norm. Only the rank of the matrix and some loop bounds * are changed to implement this.

                    * *

                    The resolution engine is a simple translation of the MINPACK lmder routine with minor * changes. The changes include the over-determined resolution, the use of * inherited convergence checker and the Q.R. decomposition which has been * rewritten following the algorithm described in the * P. Lascaux and R. Theodor book Analyse numérique matricielle * appliquée à l'art de l'ingénieur, Masson 1986.

                    *

                    The authors of the original fortran version are: *

                      *
                    • Argonne National Laboratory. MINPACK project. March 1980
                    • *
                    • Burton S. Garbow
                    • *
                    • Kenneth E. Hillstrom
                    • *
                    • Jorge J. More
                    • *
                    * The redistribution policy for MINPACK is available here, for convenience, it * is reproduced below.

                    * * * * *
                    * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
                    * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                      *
                    1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
                    2. *
                    3. 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.
                    4. *
                    5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
                    6. *
                    7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
                    8. *
                    9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
                    10. *
                      * @version $Revision: 1073272 $ $Date: 2011-02-22 10:22:25 +0100 (mar. 22 févr. 2011) $ * @since 2.0 * */ public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer { /** Number of solved point. */ private int solvedCols; /** Diagonal elements of the R matrix in the Q.R. decomposition. */ private double[] diagR; /** Norms of the columns of the jacobian matrix. */ private double[] jacNorm; /** Coefficients of the Householder transforms vectors. */ private double[] beta; /** Columns permutation array. */ private int[] permutation; /** Rank of the jacobian matrix. */ private int rank; /** Levenberg-Marquardt parameter. */ private double lmPar; /** Parameters evolution direction associated with lmPar. */ private double[] lmDir; /** Positive input variable used in determining the initial step bound. */ private double initialStepBoundFactor; /** Desired relative error in the sum of squares. */ private double costRelativeTolerance; /** Desired relative error in the approximate solution parameters. */ private double parRelativeTolerance; /** Desired max cosine on the orthogonality between the function vector * and the columns of the jacobian. */ private double orthoTolerance; /** Threshold for QR ranking. */ private double qrRankingThreshold; /** * Build an optimizer for least squares problems. *

                      The default values for the algorithm settings are: *

                        *
                      • {@link #setConvergenceChecker(VectorialConvergenceChecker) vectorial convergence checker}: null
                      • *
                      • {@link #setInitialStepBoundFactor(double) initial step bound factor}: 100.0
                      • *
                      • {@link #setMaxIterations(int) maximal iterations}: 1000
                      • *
                      • {@link #setCostRelativeTolerance(double) cost relative tolerance}: 1.0e-10
                      • *
                      • {@link #setParRelativeTolerance(double) parameters relative tolerance}: 1.0e-10
                      • *
                      • {@link #setOrthoTolerance(double) orthogonality tolerance}: 1.0e-10
                      • *
                      • {@link #setQRRankingThreshold(double) QR ranking threshold}: {@link MathUtils#SAFE_MIN}
                      • *
                      *

                      *

                      These default values may be overridden after construction. If the {@link * #setConvergenceChecker vectorial convergence checker} is set to a non-null value, it * will be used instead of the {@link #setCostRelativeTolerance cost relative tolerance} * and {@link #setParRelativeTolerance parameters relative tolerance} settings. */ public LevenbergMarquardtOptimizer() { // set up the superclass with a default max cost evaluations setting setMaxIterations(1000); // default values for the tuning parameters setConvergenceChecker(null); setInitialStepBoundFactor(100.0); setCostRelativeTolerance(1.0e-10); setParRelativeTolerance(1.0e-10); setOrthoTolerance(1.0e-10); setQRRankingThreshold(MathUtils.SAFE_MIN); } /** * Set the positive input variable used in determining the initial step bound. * This bound is set to the product of initialStepBoundFactor and the euclidean * norm of diag*x if nonzero, or else to initialStepBoundFactor itself. In most * cases factor should lie in the interval (0.1, 100.0). 100.0 is a generally * recommended value. * * @param initialStepBoundFactor initial step bound factor */ public void setInitialStepBoundFactor(double initialStepBoundFactor) { this.initialStepBoundFactor = initialStepBoundFactor; } /** * Set the desired relative error in the sum of squares. *

                      This setting is used only if the {@link #setConvergenceChecker vectorial * convergence checker} is set to null.

                      * @param costRelativeTolerance desired relative error in the sum of squares */ public void setCostRelativeTolerance(double costRelativeTolerance) { this.costRelativeTolerance = costRelativeTolerance; } /** * Set the desired relative error in the approximate solution parameters. *

                      This setting is used only if the {@link #setConvergenceChecker vectorial * convergence checker} is set to null.

                      * @param parRelativeTolerance desired relative error * in the approximate solution parameters */ public void setParRelativeTolerance(double parRelativeTolerance) { this.parRelativeTolerance = parRelativeTolerance; } /** * Set the desired max cosine on the orthogonality. *

                      This setting is always used, regardless of the {@link #setConvergenceChecker * vectorial convergence checker} being null or non-null.

                      * @param orthoTolerance desired max cosine on the orthogonality * between the function vector and the columns of the jacobian */ public void setOrthoTolerance(double orthoTolerance) { this.orthoTolerance = orthoTolerance; } /** * Set the desired threshold for QR ranking. *

                      * If the squared norm of a column vector is smaller or equal to this threshold * during QR decomposition, it is considered to be a zero vector and hence the * rank of the matrix is reduced. *

                      * @param threshold threshold for QR ranking * @since 2.2 */ public void setQRRankingThreshold(final double threshold) { this.qrRankingThreshold = threshold; } /** {@inheritDoc} */ @Override protected VectorialPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { // arrays shared with the other private methods solvedCols = Math.min(rows, cols); diagR = new double[cols]; jacNorm = new double[cols]; beta = new double[cols]; permutation = new int[cols]; lmDir = new double[cols]; // local point double delta = 0; double xNorm = 0; double[] diag = new double[cols]; double[] oldX = new double[cols]; double[] oldRes = new double[rows]; double[] oldObj = new double[rows]; double[] qtf = new double[rows]; double[] work1 = new double[cols]; double[] work2 = new double[cols]; double[] work3 = new double[cols]; // evaluate the function at the starting point and calculate its norm updateResidualsAndCost(); // outer loop lmPar = 0; boolean firstIteration = true; VectorialPointValuePair current = new VectorialPointValuePair(point, objective); while (true) { for (int i=0;i= previousCost) || (tmp < 0.1)) { tmp = 0.1; } delta = tmp * FastMath.min(delta, 10.0 * lmNorm); lmPar /= tmp; } else if ((lmPar == 0) || (ratio >= 0.75)) { delta = 2 * lmNorm; lmPar *= 0.5; } // test for successful iteration. if (ratio >= 1.0e-4) { // successful iteration, update the norm firstIteration = false; xNorm = 0; for (int k = 0; k < cols; ++k) { double xK = diag[k] * point[k]; xNorm += xK * xK; } xNorm = FastMath.sqrt(xNorm); current = new VectorialPointValuePair(point, objective); // tests for convergence. if (checker != null) { // we use the vectorial convergence checker if (checker.converged(getIterations(), previous, current)) { return current; } } } else { // failed iteration, reset the previous values cost = previousCost; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; point[pj] = oldX[pj]; } tmpVec = residuals; residuals = oldRes; oldRes = tmpVec; tmpVec = objective; objective = oldObj; oldObj = tmpVec; } if (checker==null) { if (((FastMath.abs(actRed) <= costRelativeTolerance) && (preRed <= costRelativeTolerance) && (ratio <= 2.0)) || (delta <= parRelativeTolerance * xNorm)) { return current; } } // tests for termination and stringent tolerances // (2.2204e-16 is the machine epsilon for IEEE754) if ((FastMath.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) { throw new OptimizationException(LocalizedFormats.TOO_SMALL_COST_RELATIVE_TOLERANCE, costRelativeTolerance); } else if (delta <= 2.2204e-16 * xNorm) { throw new OptimizationException(LocalizedFormats.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE, parRelativeTolerance); } else if (maxCosine <= 2.2204e-16) { throw new OptimizationException(LocalizedFormats.TOO_SMALL_ORTHOGONALITY_TOLERANCE, orthoTolerance); } } } } /** * Determine the Levenberg-Marquardt parameter. *

                      This implementation is a translation in Java of the MINPACK * lmpar * routine.

                      *

                      This method sets the lmPar and lmDir attributes.

                      *

                      The authors of the original fortran function are:

                      *
                        *
                      • Argonne National Laboratory. MINPACK project. March 1980
                      • *
                      • Burton S. Garbow
                      • *
                      • Kenneth E. Hillstrom
                      • *
                      • Jorge J. More
                      • *
                      *

                      Luc Maisonobe did the Java translation.

                      * * @param qy array containing qTy * @param delta upper bound on the euclidean norm of diagR * lmDir * @param diag diagonal matrix * @param work1 work array * @param work2 work array * @param work3 work array */ private void determineLMParameter(double[] qy, double delta, double[] diag, double[] work1, double[] work2, double[] work3) { // compute and store in x the gauss-newton direction, if the // jacobian is rank-deficient, obtain a least squares solution for (int j = 0; j < rank; ++j) { lmDir[permutation[j]] = qy[j]; } for (int j = rank; j < cols; ++j) { lmDir[permutation[j]] = 0; } for (int k = rank - 1; k >= 0; --k) { int pk = permutation[k]; double ypk = lmDir[pk] / diagR[pk]; for (int i = 0; i < k; ++i) { lmDir[permutation[i]] -= ypk * wjacobian[i][pk]; } lmDir[pk] = ypk; } // evaluate the function at the origin, and test // for acceptance of the Gauss-Newton direction double dxNorm = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double s = diag[pj] * lmDir[pj]; work1[pj] = s; dxNorm += s * s; } dxNorm = FastMath.sqrt(dxNorm); double fp = dxNorm - delta; if (fp <= 0.1 * delta) { lmPar = 0; return; } // if the jacobian is not rank deficient, the Newton step provides // a lower bound, parl, for the zero of the function, // otherwise set this bound to zero double sum2; double parl = 0; if (rank == solvedCols) { for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] *= diag[pj] / dxNorm; } sum2 = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double sum = 0; for (int i = 0; i < j; ++i) { sum += wjacobian[i][pj] * work1[permutation[i]]; } double s = (work1[pj] - sum) / diagR[pj]; work1[pj] = s; sum2 += s * s; } parl = fp / (delta * sum2); } // calculate an upper bound, paru, for the zero of the function sum2 = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double sum = 0; for (int i = 0; i <= j; ++i) { sum += wjacobian[i][pj] * qy[i]; } sum /= diag[pj]; sum2 += sum * sum; } double gNorm = FastMath.sqrt(sum2); double paru = gNorm / delta; if (paru == 0) { // 2.2251e-308 is the smallest positive real for IEE754 paru = 2.2251e-308 / FastMath.min(delta, 0.1); } // if the input par lies outside of the interval (parl,paru), // set par to the closer endpoint lmPar = FastMath.min(paru, FastMath.max(lmPar, parl)); if (lmPar == 0) { lmPar = gNorm / dxNorm; } for (int countdown = 10; countdown >= 0; --countdown) { // evaluate the function at the current value of lmPar if (lmPar == 0) { lmPar = FastMath.max(2.2251e-308, 0.001 * paru); } double sPar = FastMath.sqrt(lmPar); for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] = sPar * diag[pj]; } determineLMDirection(qy, work1, work2, work3); dxNorm = 0; for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; double s = diag[pj] * lmDir[pj]; work3[pj] = s; dxNorm += s * s; } dxNorm = FastMath.sqrt(dxNorm); double previousFP = fp; fp = dxNorm - delta; // if the function is small enough, accept the current value // of lmPar, also test for the exceptional cases where parl is zero if ((FastMath.abs(fp) <= 0.1 * delta) || ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) { return; } // compute the Newton correction for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] = work3[pj] * diag[pj] / dxNorm; } for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; work1[pj] /= work2[j]; double tmp = work1[pj]; for (int i = j + 1; i < solvedCols; ++i) { work1[permutation[i]] -= wjacobian[i][pj] * tmp; } } sum2 = 0; for (int j = 0; j < solvedCols; ++j) { double s = work1[permutation[j]]; sum2 += s * s; } double correction = fp / (delta * sum2); // depending on the sign of the function, update parl or paru. if (fp > 0) { parl = FastMath.max(parl, lmPar); } else if (fp < 0) { paru = FastMath.min(paru, lmPar); } // compute an improved estimate for lmPar lmPar = FastMath.max(parl, lmPar + correction); } } /** * Solve a*x = b and d*x = 0 in the least squares sense. *

                      This implementation is a translation in Java of the MINPACK * qrsolv * routine.

                      *

                      This method sets the lmDir and lmDiag attributes.

                      *

                      The authors of the original fortran function are:

                      *
                        *
                      • Argonne National Laboratory. MINPACK project. March 1980
                      • *
                      • Burton S. Garbow
                      • *
                      • Kenneth E. Hillstrom
                      • *
                      • Jorge J. More
                      • *
                      *

                      Luc Maisonobe did the Java translation.

                      * * @param qy array containing qTy * @param diag diagonal matrix * @param lmDiag diagonal elements associated with lmDir * @param work work array */ private void determineLMDirection(double[] qy, double[] diag, double[] lmDiag, double[] work) { // copy R and Qty to preserve input and initialize s // in particular, save the diagonal elements of R in lmDir for (int j = 0; j < solvedCols; ++j) { int pj = permutation[j]; for (int i = j + 1; i < solvedCols; ++i) { wjacobian[i][pj] = wjacobian[j][permutation[i]]; } lmDir[j] = diagR[pj]; work[j] = qy[j]; } // eliminate the diagonal matrix d using a Givens rotation for (int j = 0; j < solvedCols; ++j) { // prepare the row of d to be eliminated, locating the // diagonal element using p from the Q.R. factorization int pj = permutation[j]; double dpj = diag[pj]; if (dpj != 0) { Arrays.fill(lmDiag, j + 1, lmDiag.length, 0); } lmDiag[j] = dpj; // the transformations to eliminate the row of d // modify only a single element of Qty // beyond the first n, which is initially zero. double qtbpj = 0; for (int k = j; k < solvedCols; ++k) { int pk = permutation[k]; // determine a Givens rotation which eliminates the // appropriate element in the current row of d if (lmDiag[k] != 0) { final double sin; final double cos; double rkk = wjacobian[k][pk]; if (FastMath.abs(rkk) < FastMath.abs(lmDiag[k])) { final double cotan = rkk / lmDiag[k]; sin = 1.0 / FastMath.sqrt(1.0 + cotan * cotan); cos = sin * cotan; } else { final double tan = lmDiag[k] / rkk; cos = 1.0 / FastMath.sqrt(1.0 + tan * tan); sin = cos * tan; } // compute the modified diagonal element of R and // the modified element of (Qty,0) wjacobian[k][pk] = cos * rkk + sin * lmDiag[k]; final double temp = cos * work[k] + sin * qtbpj; qtbpj = -sin * work[k] + cos * qtbpj; work[k] = temp; // accumulate the tranformation in the row of s for (int i = k + 1; i < solvedCols; ++i) { double rik = wjacobian[i][pk]; final double temp2 = cos * rik + sin * lmDiag[i]; lmDiag[i] = -sin * rik + cos * lmDiag[i]; wjacobian[i][pk] = temp2; } } } // store the diagonal element of s and restore // the corresponding diagonal element of R lmDiag[j] = wjacobian[j][permutation[j]]; wjacobian[j][permutation[j]] = lmDir[j]; } // solve the triangular system for z, if the system is // singular, then obtain a least squares solution int nSing = solvedCols; for (int j = 0; j < solvedCols; ++j) { if ((lmDiag[j] == 0) && (nSing == solvedCols)) { nSing = j; } if (nSing < solvedCols) { work[j] = 0; } } if (nSing > 0) { for (int j = nSing - 1; j >= 0; --j) { int pj = permutation[j]; double sum = 0; for (int i = j + 1; i < nSing; ++i) { sum += wjacobian[i][pj] * work[i]; } work[j] = (work[j] - sum) / lmDiag[j]; } } // permute the components of z back to components of lmDir for (int j = 0; j < lmDir.length; ++j) { lmDir[permutation[j]] = work[j]; } } /** * Decompose a matrix A as A.P = Q.R using Householder transforms. *

                      As suggested in the P. Lascaux and R. Theodor book * Analyse numérique matricielle appliquée à * l'art de l'ingénieur (Masson, 1986), instead of representing * the Householder transforms with uk unit vectors such that: *

                           * Hk = I - 2uk.ukt
                           * 
                      * we use k non-unit vectors such that: *
                           * Hk = I - betakvk.vkt
                           * 
                      * where vk = ak - alphak ek. * The betak coefficients are provided upon exit as recomputing * them from the vk vectors would be costly.

                      *

                      This decomposition handles rank deficient cases since the tranformations * are performed in non-increasing columns norms order thanks to columns * pivoting. The diagonal elements of the R matrix are therefore also in * non-increasing absolute values order.

                      * @exception OptimizationException if the decomposition cannot be performed */ private void qrDecomposition() throws OptimizationException { // initializations for (int k = 0; k < cols; ++k) { permutation[k] = k; double norm2 = 0; for (int i = 0; i < wjacobian.length; ++i) { double akk = wjacobian[i][k]; norm2 += akk * akk; } jacNorm[k] = FastMath.sqrt(norm2); } // transform the matrix column after column for (int k = 0; k < cols; ++k) { // select the column with the greatest norm on active components int nextColumn = -1; double ak2 = Double.NEGATIVE_INFINITY; for (int i = k; i < cols; ++i) { double norm2 = 0; for (int j = k; j < wjacobian.length; ++j) { double aki = wjacobian[j][permutation[i]]; norm2 += aki * aki; } if (Double.isInfinite(norm2) || Double.isNaN(norm2)) { throw new OptimizationException(LocalizedFormats.UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN, rows, cols); } if (norm2 > ak2) { nextColumn = i; ak2 = norm2; } } if (ak2 <= qrRankingThreshold) { rank = k; return; } int pk = permutation[nextColumn]; permutation[nextColumn] = permutation[k]; permutation[k] = pk; // choose alpha such that Hk.u = alpha ek double akk = wjacobian[k][pk]; double alpha = (akk > 0) ? -FastMath.sqrt(ak2) : FastMath.sqrt(ak2); double betak = 1.0 / (ak2 - akk * alpha); beta[pk] = betak; // transform the current column diagR[pk] = alpha; wjacobian[k][pk] -= alpha; // transform the remaining columns for (int dk = cols - 1 - k; dk > 0; --dk) { double gamma = 0; for (int j = k; j < wjacobian.length; ++j) { gamma += wjacobian[j][pk] * wjacobian[j][permutation[k + dk]]; } gamma *= betak; for (int j = k; j < wjacobian.length; ++j) { wjacobian[j][permutation[k + dk]] -= gamma * wjacobian[j][pk]; } } } rank = solvedCols; } /** * Compute the product Qt.y for some Q.R. decomposition. * * @param y vector to multiply (will be overwritten with the result) */ private void qTy(double[] y) { for (int k = 0; k < cols; ++k) { int pk = permutation[k]; double gamma = 0; for (int i = k; i < rows; ++i) { gamma += wjacobian[i][pk] * y[i]; } gamma *= beta[pk]; for (int i = k; i < rows; ++i) { y[i] -= gamma * wjacobian[i][pk]; } } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/Preconditioner.java100644 1750 1750 4617 11532241244 32345 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import org.apache.commons.math.FunctionEvaluationException; /** * This interface represents a preconditioner for differentiable scalar * objective function optimizers. * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface Preconditioner { /** * Precondition a search direction. *

                      * The returned preconditioned search direction must be computed fast or * the algorithm performances will drop drastically. A classical approach * is to compute only the diagonal elements of the hessian and to divide * the raw search direction by these elements if they are all positive. * If at least one of them is negative, it is safer to return a clone of * the raw search direction as if the hessian was the identity matrix. The * rationale for this simplified choice is that a negative diagonal element * means the current point is far from the optimum and preconditioning will * not be efficient anyway in this case. *

                      * @param point current point at which the search direction was computed * @param r raw search direction (i.e. opposite of the gradient) * @return approximation of H-1r where H is the objective function hessian * @exception FunctionEvaluationException if no cost can be computed for the parameters * @exception IllegalArgumentException if point dimension is wrong */ double[] precondition(double[] point, double[] r) throws FunctionEvaluationException, IllegalArgumentException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/package.html100644 1750 1750 1644 11532241244 30774 0ustarlucluc 0 0 This package provides optimization algorithms that require derivatives. ././@LongLink100644 0 0 171 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGr100644 1750 1750 25601 11532241244 32473 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.analysis.solvers.UnivariateRealSolver; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.util.FastMath; /** * Non-linear conjugate gradient optimizer. *

                      * This class supports both the Fletcher-Reeves and the Polak-Ribière * update formulas for the conjugate search directions. It also supports * optional preconditioning. *

                      * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 * */ public class NonLinearConjugateGradientOptimizer extends AbstractScalarDifferentiableOptimizer { /** Update formula for the beta parameter. */ private final ConjugateGradientFormula updateFormula; /** Preconditioner (may be null). */ private Preconditioner preconditioner; /** solver to use in the line search (may be null). */ private UnivariateRealSolver solver; /** Initial step used to bracket the optimum in line search. */ private double initialStep; /** Simple constructor with default settings. *

                      The convergence check is set to a {@link * org.apache.commons.math.optimization.SimpleVectorialValueChecker} * and the maximal number of iterations is set to * {@link AbstractScalarDifferentiableOptimizer#DEFAULT_MAX_ITERATIONS}. * @param updateFormula formula to use for updating the β parameter, * must be one of {@link ConjugateGradientFormula#FLETCHER_REEVES} or {@link * ConjugateGradientFormula#POLAK_RIBIERE} */ public NonLinearConjugateGradientOptimizer(final ConjugateGradientFormula updateFormula) { this.updateFormula = updateFormula; preconditioner = null; solver = null; initialStep = 1.0; } /** * Set the preconditioner. * @param preconditioner preconditioner to use for next optimization, * may be null to remove an already registered preconditioner */ public void setPreconditioner(final Preconditioner preconditioner) { this.preconditioner = preconditioner; } /** * Set the solver to use during line search. * @param lineSearchSolver solver to use during line search, may be null * to remove an already registered solver and fall back to the * default {@link BrentSolver Brent solver}. */ public void setLineSearchSolver(final UnivariateRealSolver lineSearchSolver) { this.solver = lineSearchSolver; } /** * Set the initial step used to bracket the optimum in line search. *

                      * The initial step is a factor with respect to the search direction, * which itself is roughly related to the gradient of the function *

                      * @param initialStep initial step used to bracket the optimum in line search, * if a non-positive value is used, the initial step is reset to its * default value of 1.0 */ public void setInitialStep(final double initialStep) { if (initialStep <= 0) { this.initialStep = 1.0; } else { this.initialStep = initialStep; } } /** {@inheritDoc} */ @Override protected RealPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { try { // initialization if (preconditioner == null) { preconditioner = new IdentityPreconditioner(); } if (solver == null) { solver = new BrentSolver(); } final int n = point.length; double[] r = computeObjectiveGradient(point); if (goal == GoalType.MINIMIZE) { for (int i = 0; i < n; ++i) { r[i] = -r[i]; } } // initial search direction double[] steepestDescent = preconditioner.precondition(point, r); double[] searchDirection = steepestDescent.clone(); double delta = 0; for (int i = 0; i < n; ++i) { delta += r[i] * searchDirection[i]; } RealPointValuePair current = null; while (true) { final double objective = computeObjectiveValue(point); RealPointValuePair previous = current; current = new RealPointValuePair(point, objective); if (previous != null) { if (checker.converged(getIterations(), previous, current)) { // we have found an optimum return current; } } incrementIterationsCounter(); double dTd = 0; for (final double di : searchDirection) { dTd += di * di; } // find the optimal step in the search direction final UnivariateRealFunction lsf = new LineSearchFunction(searchDirection); final double step = solver.solve(lsf, 0, findUpperBound(lsf, 0, initialStep)); // validate new point for (int i = 0; i < point.length; ++i) { point[i] += step * searchDirection[i]; } r = computeObjectiveGradient(point); if (goal == GoalType.MINIMIZE) { for (int i = 0; i < n; ++i) { r[i] = -r[i]; } } // compute beta final double deltaOld = delta; final double[] newSteepestDescent = preconditioner.precondition(point, r); delta = 0; for (int i = 0; i < n; ++i) { delta += r[i] * newSteepestDescent[i]; } final double beta; if (updateFormula == ConjugateGradientFormula.FLETCHER_REEVES) { beta = delta / deltaOld; } else { double deltaMid = 0; for (int i = 0; i < r.length; ++i) { deltaMid += r[i] * steepestDescent[i]; } beta = (delta - deltaMid) / deltaOld; } steepestDescent = newSteepestDescent; // compute conjugate search direction if ((getIterations() % n == 0) || (beta < 0)) { // break conjugation: reset search direction searchDirection = steepestDescent.clone(); } else { // compute new conjugate search direction for (int i = 0; i < n; ++i) { searchDirection[i] = steepestDescent[i] + beta * searchDirection[i]; } } } } catch (ConvergenceException ce) { throw new OptimizationException(ce); } } /** * Find the upper bound b ensuring bracketing of a root between a and b * @param f function whose root must be bracketed * @param a lower bound of the interval * @param h initial step to try * @return b such that f(a) and f(b) have opposite signs * @exception FunctionEvaluationException if the function cannot be computed * @exception OptimizationException if no bracket can be found */ private double findUpperBound(final UnivariateRealFunction f, final double a, final double h) throws FunctionEvaluationException, OptimizationException { final double yA = f.value(a); double yB = yA; for (double step = h; step < Double.MAX_VALUE; step *= FastMath.max(2, yA / yB)) { final double b = a + step; yB = f.value(b); if (yA * yB <= 0) { return b; } } throw new OptimizationException(LocalizedFormats.UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH); } /** Default identity preconditioner. */ private static class IdentityPreconditioner implements Preconditioner { /** {@inheritDoc} */ public double[] precondition(double[] variables, double[] r) { return r.clone(); } } /** Internal class for line search. *

                      * The function represented by this class is the dot product of * the objective function gradient and the search direction. Its * value is zero when the gradient is orthogonal to the search * direction, i.e. when the objective function value is a local * extremum along the search direction. *

                      */ private class LineSearchFunction implements UnivariateRealFunction { /** Search direction. */ private final double[] searchDirection; /** Simple constructor. * @param searchDirection search direction */ public LineSearchFunction(final double[] searchDirection) { this.searchDirection = searchDirection; } /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { // current point in the search direction final double[] shiftedPoint = point.clone(); for (int i = 0; i < shiftedPoint.length; ++i) { shiftedPoint[i] += x * searchDirection[i]; } // gradient of the objective function final double[] gradient; gradient = computeObjectiveGradient(shiftedPoint); // dot product with the search direction double dotProduct = 0; for (int i = 0; i < gradient.length; ++i) { dotProduct += gradient[i] * searchDirection[i]; } return dotProduct; } } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer100644 1750 1750 12060 11532241244 32630 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.BlockRealMatrix; import org.apache.commons.math.linear.DecompositionSolver; import org.apache.commons.math.linear.InvalidMatrixException; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.QRDecompositionImpl; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.VectorialPointValuePair; /** * Gauss-Newton least-squares solver. *

                      * This class solve a least-square problem by solving the normal equations * of the linearized problem at each iteration. Either LU decomposition or * QR decomposition can be used to solve the normal equations. LU decomposition * is faster but QR decomposition is more robust for difficult problems. *

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 * */ public class GaussNewtonOptimizer extends AbstractLeastSquaresOptimizer { /** Indicator for using LU decomposition. */ private final boolean useLU; /** Simple constructor with default settings. *

                      The convergence check is set to a {@link * org.apache.commons.math.optimization.SimpleVectorialValueChecker} * and the maximal number of evaluation is set to * {@link AbstractLeastSquaresOptimizer#DEFAULT_MAX_ITERATIONS}. * @param useLU if true, the normal equations will be solved using LU * decomposition, otherwise they will be solved using QR decomposition */ public GaussNewtonOptimizer(final boolean useLU) { this.useLU = useLU; } /** {@inheritDoc} */ @Override public VectorialPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { // iterate until convergence is reached VectorialPointValuePair current = null; for (boolean converged = false; !converged;) { incrementIterationsCounter(); // evaluate the objective function and its jacobian VectorialPointValuePair previous = current; updateResidualsAndCost(); updateJacobian(); current = new VectorialPointValuePair(point, objective); // build the linear problem final double[] b = new double[cols]; final double[][] a = new double[cols][cols]; for (int i = 0; i < rows; ++i) { final double[] grad = jacobian[i]; final double weight = residualsWeights[i]; final double residual = objective[i] - targetValues[i]; // compute the normal equation final double wr = weight * residual; for (int j = 0; j < cols; ++j) { b[j] += wr * grad[j]; } // build the contribution matrix for measurement i for (int k = 0; k < cols; ++k) { double[] ak = a[k]; double wgk = weight * grad[k]; for (int l = 0; l < cols; ++l) { ak[l] += wgk * grad[l]; } } } try { // solve the linearized least squares problem RealMatrix mA = new BlockRealMatrix(a); DecompositionSolver solver = useLU ? new LUDecompositionImpl(mA).getSolver() : new QRDecompositionImpl(mA).getSolver(); final double[] dX = solver.solve(b); // update the estimated parameters for (int i = 0; i < cols; ++i) { point[i] += dX[i]; } } catch(InvalidMatrixException e) { throw new OptimizationException(LocalizedFormats.UNABLE_TO_SOLVE_SINGULAR_PROBLEM); } // check convergence if (previous != null) { converged = checker.converged(getIterations(), previous, current); } } // we have converged return current; } } ././@LongLink100644 0 0 173 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/AbstractScalarDiffer100644 1750 1750 16344 11532241244 32472 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealConvergenceChecker; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; /** * Base class for implementing optimizers for multivariate scalar functions. *

                      This base class handles the boilerplate methods associated to thresholds * settings, iterations and evaluations counting.

                      * @version $Revision: 1069567 $ $Date: 2011-02-10 22:07:26 +0100 (jeu. 10 févr. 2011) $ * @since 2.0 */ public abstract class AbstractScalarDifferentiableOptimizer implements DifferentiableMultivariateRealOptimizer { /** Default maximal number of iterations allowed. */ public static final int DEFAULT_MAX_ITERATIONS = 100; /** Convergence checker. */ @Deprecated protected RealConvergenceChecker checker; /** * Type of optimization. * @since 2.1 */ @Deprecated protected GoalType goal; /** Current point set. */ @Deprecated protected double[] point; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed. */ private int iterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Number of gradient evaluations. */ private int gradientEvaluations; /** Objective function. */ private DifferentiableMultivariateRealFunction function; /** Objective function gradient. */ private MultivariateVectorialFunction gradient; /** Simple constructor with default settings. *

                      The convergence check is set to a {@link SimpleScalarValueChecker} * and the maximal number of evaluation is set to its default value.

                      */ protected AbstractScalarDifferentiableOptimizer() { setConvergenceChecker(new SimpleScalarValueChecker()); setMaxIterations(DEFAULT_MAX_ITERATIONS); setMaxEvaluations(Integer.MAX_VALUE); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return iterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return evaluations; } /** {@inheritDoc} */ public int getGradientEvaluations() { return gradientEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { this.checker = convergenceChecker; } /** {@inheritDoc} */ public RealConvergenceChecker getConvergenceChecker() { return checker; } /** Increment the iterations counter by 1. * @exception OptimizationException if the maximal number * of iterations is exceeded */ protected void incrementIterationsCounter() throws OptimizationException { if (++iterations > maxIterations) { throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); } } /** * Compute the gradient vector. * @param evaluationPoint point at which the gradient must be evaluated * @return gradient at the specified point * @exception FunctionEvaluationException if the function gradient */ protected double[] computeObjectiveGradient(final double[] evaluationPoint) throws FunctionEvaluationException { ++gradientEvaluations; return gradient.value(evaluationPoint); } /** * Compute the objective function value. * @param evaluationPoint point at which the objective function must be evaluated * @return objective function value at specified point * @exception FunctionEvaluationException if the function cannot be evaluated * or its dimension doesn't match problem dimension or the maximal number * of iterations is exceeded */ protected double computeObjectiveValue(final double[] evaluationPoint) throws FunctionEvaluationException { if (++evaluations > maxEvaluations) { throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), evaluationPoint); } return function.value(evaluationPoint); } /** {@inheritDoc} */ public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, final GoalType goalType, final double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { // reset counters iterations = 0; evaluations = 0; gradientEvaluations = 0; // store optimization problem characteristics function = f; gradient = f.gradient(); goal = goalType; point = startPoint.clone(); return doOptimize(); } /** Perform the bulk of optimization algorithm. * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ protected abstract RealPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; } ././@LongLink100644 0 0 163 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquares100644 1750 1750 32264 11532241244 32560 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization.general; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; import org.apache.commons.math.analysis.MultivariateMatrixFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.InvalidMatrixException; import org.apache.commons.math.linear.LUDecompositionImpl; import org.apache.commons.math.linear.MatrixUtils; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.SimpleVectorialValueChecker; import org.apache.commons.math.optimization.VectorialConvergenceChecker; import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; import org.apache.commons.math.optimization.VectorialPointValuePair; import org.apache.commons.math.util.FastMath; /** * Base class for implementing least squares optimizers. *

                      This base class handles the boilerplate methods associated to thresholds * settings, jacobian and error estimation.

                      * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 * */ public abstract class AbstractLeastSquaresOptimizer implements DifferentiableMultivariateVectorialOptimizer { /** Default maximal number of iterations allowed. */ public static final int DEFAULT_MAX_ITERATIONS = 100; /** Convergence checker. */ protected VectorialConvergenceChecker checker; /** * Jacobian matrix. *

                      This matrix is in canonical form just after the calls to * {@link #updateJacobian()}, but may be modified by the solver * in the derived class (the {@link LevenbergMarquardtOptimizer * Levenberg-Marquardt optimizer} does this).

                      */ protected double[][] jacobian; /** Number of columns of the jacobian matrix. */ protected int cols; /** Number of rows of the jacobian matrix. */ protected int rows; /** * Target value for the objective functions at optimum. * @since 2.1 */ protected double[] targetValues; /** * Weight for the least squares cost computation. * @since 2.1 */ protected double[] residualsWeights; /** Current point. */ protected double[] point; /** Current objective function value. */ protected double[] objective; /** Current residuals. */ protected double[] residuals; /** Weighted Jacobian */ protected double[][] wjacobian; /** Weighted residuals */ protected double[] wresiduals; /** Cost value (square root of the sum of the residuals). */ protected double cost; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed. */ private int iterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int objectiveEvaluations; /** Number of jacobian evaluations. */ private int jacobianEvaluations; /** Objective function. */ private DifferentiableMultivariateVectorialFunction function; /** Objective function derivatives. */ private MultivariateMatrixFunction jF; /** Simple constructor with default settings. *

                      The convergence check is set to a {@link SimpleVectorialValueChecker} * and the maximal number of evaluation is set to its default value.

                      */ protected AbstractLeastSquaresOptimizer() { setConvergenceChecker(new SimpleVectorialValueChecker()); setMaxIterations(DEFAULT_MAX_ITERATIONS); setMaxEvaluations(Integer.MAX_VALUE); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return iterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return objectiveEvaluations; } /** {@inheritDoc} */ public int getJacobianEvaluations() { return jacobianEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(VectorialConvergenceChecker convergenceChecker) { this.checker = convergenceChecker; } /** {@inheritDoc} */ public VectorialConvergenceChecker getConvergenceChecker() { return checker; } /** Increment the iterations counter by 1. * @exception OptimizationException if the maximal number * of iterations is exceeded */ protected void incrementIterationsCounter() throws OptimizationException { if (++iterations > maxIterations) { throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); } } /** * Update the jacobian matrix. * @exception FunctionEvaluationException if the function jacobian * cannot be evaluated or its dimension doesn't match problem dimension */ protected void updateJacobian() throws FunctionEvaluationException { ++jacobianEvaluations; jacobian = jF.value(point); if (jacobian.length != rows) { throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, jacobian.length, rows); } for (int i = 0; i < rows; i++) { final double[] ji = jacobian[i]; double wi = FastMath.sqrt(residualsWeights[i]); for (int j = 0; j < cols; ++j) { ji[j] *= -1.0; wjacobian[i][j] = ji[j]*wi; } } } /** * Update the residuals array and cost function value. * @exception FunctionEvaluationException if the function cannot be evaluated * or its dimension doesn't match problem dimension or maximal number of * of evaluations is exceeded */ protected void updateResidualsAndCost() throws FunctionEvaluationException { if (++objectiveEvaluations > maxEvaluations) { throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point); } objective = function.value(point); if (objective.length != rows) { throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, objective.length, rows); } cost = 0; int index = 0; for (int i = 0; i < rows; i++) { final double residual = targetValues[i] - objective[i]; residuals[i] = residual; wresiduals[i]= residual*FastMath.sqrt(residualsWeights[i]); cost += residualsWeights[i] * residual * residual; index += cols; } cost = FastMath.sqrt(cost); } /** * Get the Root Mean Square value. * Get the Root Mean Square value, i.e. the root of the arithmetic * mean of the square of all weighted residuals. This is related to the * criterion that is minimized by the optimizer as follows: if * c if the criterion, and n is the number of * measurements, then the RMS is sqrt (c/n). * * @return RMS value */ public double getRMS() { return FastMath.sqrt(getChiSquare() / rows); } /** * Get a Chi-Square-like value assuming the N residuals follow N * distinct normal distributions centered on 0 and whose variances are * the reciprocal of the weights. * @return chi-square value */ public double getChiSquare() { return cost*cost; } /** * Get the covariance matrix of optimized parameters. * @return covariance matrix * @exception FunctionEvaluationException if the function jacobian cannot * be evaluated * @exception OptimizationException if the covariance matrix * cannot be computed (singular problem) */ public double[][] getCovariances() throws FunctionEvaluationException, OptimizationException { // set up the jacobian updateJacobian(); // compute transpose(J).J, avoiding building big intermediate matrices double[][] jTj = new double[cols][cols]; for (int i = 0; i < cols; ++i) { for (int j = i; j < cols; ++j) { double sum = 0; for (int k = 0; k < rows; ++k) { sum += wjacobian[k][i] * wjacobian[k][j]; } jTj[i][j] = sum; jTj[j][i] = sum; } } try { // compute the covariance matrix RealMatrix inverse = new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse(); return inverse.getData(); } catch (InvalidMatrixException ime) { throw new OptimizationException(LocalizedFormats.UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM); } } /** * Guess the errors in optimized parameters. *

                      Guessing is covariance-based, it only gives rough order of magnitude.

                      * @return errors in optimized parameters * @exception FunctionEvaluationException if the function jacobian cannot b evaluated * @exception OptimizationException if the covariances matrix cannot be computed * or the number of degrees of freedom is not positive (number of measurements * lesser or equal to number of parameters) */ public double[] guessParametersErrors() throws FunctionEvaluationException, OptimizationException { if (rows <= cols) { throw new OptimizationException( LocalizedFormats.NO_DEGREES_OF_FREEDOM, rows, cols); } double[] errors = new double[cols]; final double c = FastMath.sqrt(getChiSquare() / (rows - cols)); double[][] covar = getCovariances(); for (int i = 0; i < errors.length; ++i) { errors[i] = FastMath.sqrt(covar[i][i]) * c; } return errors; } /** {@inheritDoc} */ public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f, final double[] target, final double[] weights, final double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { if (target.length != weights.length) { throw new OptimizationException(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, target.length, weights.length); } // reset counters iterations = 0; objectiveEvaluations = 0; jacobianEvaluations = 0; // store least squares problem characteristics function = f; jF = f.jacobian(); targetValues = target.clone(); residualsWeights = weights.clone(); this.point = startPoint.clone(); this.residuals = new double[target.length]; // arrays shared with the other private methods rows = target.length; cols = point.length; jacobian = new double[rows][cols]; wjacobian = new double[rows][cols]; wresiduals = new double[rows]; cost = Double.POSITIVE_INFINITY; return doOptimize(); } /** Perform the bulk of optimization algorithm. * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ protected abstract VectorialPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; } ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOp100644 1750 1750 20072 11532241244 32637 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.util.Arrays; import java.util.Comparator; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomVectorGenerator; /** * Special implementation of the {@link MultivariateRealOptimizer} interface adding * multi-start features to an existing optimizer. *

                      * This class wraps a classical optimizer to use it several times in * turn with different starting points in order to avoid being trapped * into a local extremum when looking for a global one. *

                      * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class MultiStartMultivariateRealOptimizer implements MultivariateRealOptimizer { /** Underlying classical optimizer. */ private final MultivariateRealOptimizer optimizer; /** Maximal number of iterations allowed. */ private int maxIterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of iterations already performed for all starts. */ private int totalIterations; /** Number of evaluations already performed for all starts. */ private int totalEvaluations; /** Number of starts to go. */ private int starts; /** Random generator for multi-start. */ private RandomVectorGenerator generator; /** Found optima. */ private RealPointValuePair[] optima; /** * Create a multi-start optimizer from a single-start optimizer * @param optimizer single-start optimizer to wrap * @param starts number of starts to perform (including the * first one), multi-start is disabled if value is less than or * equal to 1 * @param generator random vector generator to use for restarts */ public MultiStartMultivariateRealOptimizer(final MultivariateRealOptimizer optimizer, final int starts, final RandomVectorGenerator generator) { this.optimizer = optimizer; this.totalIterations = 0; this.totalEvaluations = 0; this.starts = starts; this.generator = generator; this.optima = null; setMaxIterations(Integer.MAX_VALUE); setMaxEvaluations(Integer.MAX_VALUE); } /** Get all the optima found during the last call to {@link * #optimize(MultivariateRealFunction, GoalType, double[]) optimize}. *

                      The optimizer stores all the optima found during a set of * restarts. The {@link #optimize(MultivariateRealFunction, GoalType, * double[]) optimize} method returns the best point only. This * method returns all the points found at the end of each starts, * including the best one already returned by the {@link * #optimize(MultivariateRealFunction, GoalType, double[]) optimize} * method. *

                      *

                      * The returned array as one element for each start as specified * in the constructor. It is ordered with the results from the * runs that did converge first, sorted from best to worst * objective value (i.e in ascending order if minimizing and in * descending order if maximizing), followed by and null elements * corresponding to the runs that did not converge. This means all * elements will be null if the {@link #optimize(MultivariateRealFunction, * GoalType, double[]) optimize} method did throw a {@link * org.apache.commons.math.ConvergenceException ConvergenceException}). * This also means that if the first element is non null, it is the best * point found across all starts.

                      * @return array containing the optima * @exception IllegalStateException if {@link #optimize(MultivariateRealFunction, * GoalType, double[]) optimize} has not been called */ public RealPointValuePair[] getOptima() throws IllegalStateException { if (optima == null) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET); } return optima.clone(); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getIterations() { return totalIterations; } /** {@inheritDoc} */ public int getEvaluations() { return totalEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(RealConvergenceChecker checker) { optimizer.setConvergenceChecker(checker); } /** {@inheritDoc} */ public RealConvergenceChecker getConvergenceChecker() { return optimizer.getConvergenceChecker(); } /** {@inheritDoc} */ public RealPointValuePair optimize(final MultivariateRealFunction f, final GoalType goalType, double[] startPoint) throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException { optima = new RealPointValuePair[starts]; totalIterations = 0; totalEvaluations = 0; // multi-start loop for (int i = 0; i < starts; ++i) { try { optimizer.setMaxIterations(maxIterations - totalIterations); optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); optima[i] = optimizer.optimize(f, goalType, (i == 0) ? startPoint : generator.nextVector()); } catch (FunctionEvaluationException fee) { optima[i] = null; } catch (OptimizationException oe) { optima[i] = null; } totalIterations += optimizer.getIterations(); totalEvaluations += optimizer.getEvaluations(); } // sort the optima from best to worst, followed by null elements Arrays.sort(optima, new Comparator() { public int compare(final RealPointValuePair o1, final RealPointValuePair o2) { if (o1 == null) { return (o2 == null) ? 0 : +1; } else if (o2 == null) { return -1; } final double v1 = o1.getValue(); final double v2 = o2.getValue(); return (goalType == GoalType.MINIMIZE) ? Double.compare(v1, v2) : Double.compare(v2, v1); } }); if (optima[0] == null) { throw new OptimizationException( LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, starts); } // return the found point given the best objective function value return optima[0]; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/SimpleRealPointChecker.java100644 1750 1750 6675 11532241244 32306 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Simple implementation of the {@link RealConvergenceChecker} interface using * only point coordinates. *

                      * Convergence is considered to have been reached if either the relative * difference between each point coordinate are smaller than a threshold * or if either the absolute difference between the point coordinates are * smaller than another threshold. *

                      * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class SimpleRealPointChecker implements RealConvergenceChecker { /** Default relative threshold. */ private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; /** Default absolute threshold. */ private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; /** Relative tolerance threshold. */ private final double relativeThreshold; /** Absolute tolerance threshold. */ private final double absoluteThreshold; /** Build an instance with default threshold. */ public SimpleRealPointChecker() { this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; } /** Build an instance with a specified threshold. *

                      * In order to perform only relative checks, the absolute tolerance * must be set to a negative value. In order to perform only absolute * checks, the relative tolerance must be set to a negative value. *

                      * @param relativeThreshold relative tolerance threshold * @param absoluteThreshold absolute tolerance threshold */ public SimpleRealPointChecker(final double relativeThreshold, final double absoluteThreshold) { this.relativeThreshold = relativeThreshold; this.absoluteThreshold = absoluteThreshold; } /** {@inheritDoc} */ public boolean converged(final int iteration, final RealPointValuePair previous, final RealPointValuePair current) { final double[] p = previous.getPoint(); final double[] c = current.getPoint(); for (int i = 0; i < p.length; ++i) { final double difference = FastMath.abs(p[i] - c[i]); final double size = FastMath.max(FastMath.abs(p[i]), FastMath.abs(c[i])); if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) { return false; } } return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/RealPointValuePair.java100644 1750 1750 6341 11532241244 31446 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import java.io.Serializable; /** * This class holds a point and the value of an objective function at this point. *

                      This is a simple immutable container.

                      * @see VectorialPointValuePair * @see org.apache.commons.math.analysis.MultivariateRealFunction * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $ * @since 2.0 */ public class RealPointValuePair implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = 1003888396256744753L; /** Point coordinates. */ private final double[] point; /** Value of the objective function at the point. */ private final double value; /** Build a point/objective function value pair. * @param point point coordinates (the built instance will store * a copy of the array, not the array passed as argument) * @param value value of an objective function at the point */ public RealPointValuePair(final double[] point, final double value) { this.point = (point == null) ? null : point.clone(); this.value = value; } /** Build a point/objective function value pair. * @param point point coordinates (the built instance will store * a copy of the array, not the array passed as argument) * @param value value of an objective function at the point * @param copyArray if true, the input array will be copied, otherwise * it will be referenced */ public RealPointValuePair(final double[] point, final double value, final boolean copyArray) { this.point = copyArray ? ((point == null) ? null : point.clone()) : point; this.value = value; } /** Get the point. * @return a copy of the stored point */ public double[] getPoint() { return (point == null) ? null : point.clone(); } /** Get a reference to the point. *

                      This method is provided as a convenience to avoid copying * the array, the elements of the array should not be modified.

                      * @return a reference to the internal array storing the point */ public double[] getPointRef() { return point; } /** Get the value of the objective function. * @return the stored value of the objective function */ public double getValue() { return value; } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.ja100644 1750 1750 10023 11532241244 32576 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.optimization; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.MultivariateRealFunction; /** * This interface represents an optimization algorithm for {@link MultivariateRealFunction * scalar objective functions}. *

                      Optimization algorithms find the input point set that either {@link GoalType * maximize or minimize} an objective function.

                      * @see DifferentiableMultivariateRealOptimizer * @see DifferentiableMultivariateVectorialOptimizer * @version $Revision: 1065481 $ $Date: 2011-01-31 06:31:41 +0100 (lun. 31 janv. 2011) $ * @since 2.0 */ public interface MultivariateRealOptimizer { /** Set the maximal number of iterations of the algorithm. * @param maxIterations maximal number of algorithm iterations */ void setMaxIterations(int maxIterations); /** Get the maximal number of iterations of the algorithm. * @return maximal number of iterations */ int getMaxIterations(); /** Set the maximal number of functions evaluations. * @param maxEvaluations maximal number of function evaluations */ void setMaxEvaluations(int maxEvaluations); /** Get the maximal number of functions evaluations. * @return maximal number of functions evaluations */ int getMaxEvaluations(); /** Get the number of iterations realized by the algorithm. *

                      * The number of evaluations corresponds to the last call to the * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize} * method. It is 0 if the method has not been called yet. *

                      * @return number of iterations */ int getIterations(); /** Get the number of evaluations of the objective function. *

                      * The number of evaluations corresponds to the last call to the * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize} * method. It is 0 if the method has not been called yet. *

                      * @return number of evaluations of the objective function */ int getEvaluations(); /** Set the convergence checker. * @param checker object to use to check for convergence */ void setConvergenceChecker(RealConvergenceChecker checker); /** Get the convergence checker. * @return object used to check for convergence */ RealConvergenceChecker getConvergenceChecker(); /** Optimizes an objective function. * @param f objective function * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} * or {@link GoalType#MINIMIZE} * @param startPoint the start point for optimization * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ RealPointValuePair optimize(MultivariateRealFunction f, GoalType goalType, double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/FirstOrderDifferentialEquations.java100644 1750 1750 5177 11532241246 32262 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** This interface represents a first order differential equations set. * *

                      This interface should be implemented by all real first order * differential equation problems before they can be handled by the * integrators {@link FirstOrderIntegrator#integrate} method.

                      * *

                      A first order differential equations problem, as seen by an * integrator is the time derivative dY/dt of a state * vector Y, both being one dimensional arrays. From the * integrator point of view, this derivative depends only on the * current time t and on the state vector * Y.

                      * *

                      For real problems, the derivative depends also on parameters * that do not belong to the state vector (dynamical model constants * for example). These constants are completely outside of the scope * of this interface, the classes that implement it are allowed to * handle them as they want.

                      * * @see FirstOrderIntegrator * @see FirstOrderConverter * @see SecondOrderDifferentialEquations * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface FirstOrderDifferentialEquations { /** Get the dimension of the problem. * @return dimension of the problem */ int getDimension(); /** Get the current time derivative of the state vector. * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param yDot placeholder array where to put the time derivative of the state vector * @throws DerivativeException this user-defined exception should be used if an error is * is triggered by user code */ void computeDerivatives(double t, double[] y, double[] yDot) throws DerivativeException; } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.j100644 1750 1750 27670 11532241246 32301 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import org.apache.commons.math.ode.events.EventException; /** This interface represents a handler for discrete events triggered * during ODE integration. * *

                      Some events can be triggered at discrete times as an ODE problem * is solved. This occurs for example when the integration process * should be stopped as some state is reached (G-stop facility) when the * precise date is unknown a priori, or when the derivatives have * discontinuities, or simply when the user wants to monitor some * states boundaries crossings. *

                      * *

                      These events are defined as occurring when a g * switching function sign changes.

                      * *

                      Since events are only problem-dependent and are triggered by the * independent time variable and the state vector, they can * occur at virtually any time, unknown in advance. The integrators will * take care to avoid sign changes inside the steps, they will reduce * the step size when such an event is detected in order to put this * event exactly at the end of the current step. This guarantees that * step interpolation (which always has a one step scope) is relevant * even in presence of discontinuities. This is independent from the * stepsize control provided by integrators that monitor the local * error (this event handling feature is available for all integrators, * including fixed step ones).

                      * *

                      Note that is is possible to register a {@link * org.apache.commons.math.ode.events.EventHandler classical event handler} * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians} * rather than implementing this class. The event handlers registered at low level * will see the big compound state whether the event handlers defined by this interface * see the original state, and its jacobians in separate arrays.

                      * *

                      The compound state is guaranteed to contain the original state in the first * elements, followed by the jacobian with respect to initial state (in row order), * followed by the jacobian with respect to parameters (in row order). If for example * the original state dimension is 6 and there are 3 parameters, the compound state will * be a 60 elements array. The first 6 elements will be the original state, the next 36 * elements will be the jacobian with respect to initial state, and the remaining 18 elements * will be the jacobian with respect to parameters.

                      * *

                      Dealing with low level event handlers is cumbersome if one really needs the jacobians * in these methods, but it also prevents many data being copied back and forth between * state and jacobians on one side and compound state on the other side. So for performance * reasons, it is recommended to use this interface only if jacobians are really * needed and to use lower level handlers if only state is needed.

                      * * @version $Revision: 1037341 $ $Date: 2010-11-20 22:58:35 +0100 (sam. 20 nov. 2010) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public interface EventHandlerWithJacobians { /** Stop indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should be * stopped after the event ending the current step.

                      */ int STOP = 0; /** Reset state indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should * go on after the event ending the current step, with a new state * vector (which will be retrieved thanks to the {@link #resetState * resetState} method).

                      */ int RESET_STATE = 1; /** Reset derivatives indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should * go on after the event ending the current step, with a new derivatives * vector (which will be retrieved thanks to the {@link * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives} * method).

                      */ int RESET_DERIVATIVES = 2; /** Continue indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should go * on after the event ending the current step.

                      */ int CONTINUE = 3; /** Compute the value of the switching function. *

                      The discrete events are generated when the sign of this * switching function changes. The integrator will take care to change * the stepsize in such a way these events occur exactly at step boundaries. * The switching function must be continuous in its roots neighborhood * (but not necessarily smooth), as the integrator will need to find its * roots to locate precisely the events.

                      * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param dydy0 array containing the current value of the jacobian of * the state vector with respect to initial state * @param dydp array containing the current value of the jacobian of * the state vector with respect to parameters * @return value of the g switching function * @exception EventException if the switching function cannot be evaluated */ double g(double t, double[] y, double[][] dydy0, double[][] dydp) throws EventException; /** Handle an event and choose what to do next. *

                      This method is called when the integrator has accepted a step * ending exactly on a sign change of the function, just before * the step handler itself is called (see below for scheduling). It * allows the user to update his internal data to acknowledge the fact * the event has been handled (for example setting a flag in the {@link * org.apache.commons.math.ode.jacobians.ODEWithJacobians * differential equations} to switch the derivatives computation in * case of discontinuity), or to direct the integrator to either stop * or continue integration, possibly with a reset state or derivatives.

                      *
                        *
                      • if {@link #STOP} is returned, the step handler will be called * with the isLast flag of the {@link * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep( * StepInterpolatorWithJacobians, boolean) handleStep} method set to true and * the integration will be stopped,
                      • *
                      • if {@link #RESET_STATE} is returned, the {@link #resetState * resetState} method will be called once the step handler has * finished its task, and the integrator will also recompute the * derivatives,
                      • *
                      • if {@link #RESET_DERIVATIVES} is returned, the integrator * will recompute the derivatives, *
                      • if {@link #CONTINUE} is returned, no specific action will * be taken (apart from having called this method) and integration * will continue.
                      • *
                      *

                      The scheduling between this method and the {@link * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians * StepHandlerWithJacobians} method {@link * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep( * StepInterpolatorWithJacobians, boolean) handleStep(interpolator, isLast)} * is to call this method first and handleStep afterwards. This * scheduling allows the integrator to pass true as the * isLast parameter to the step handler to make it aware the step * will be the last one if this method returns {@link #STOP}. As the * interpolator may be used to navigate back throughout the last step (as {@link * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} * does for example), user code called by this method and user * code called by step handlers may experience apparently out of order values * of the independent time variable. As an example, if the same user object * implements both this {@link EventHandlerWithJacobians EventHandler} interface and the * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} * interface, a forward integration may call its * eventOccurred method with t = 10 first and call its * handleStep method with t = 9 afterwards. Such out of order * calls are limited to the size of the integration step for {@link * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and * to the size of the fixed step for {@link * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.

                      * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param dydy0 array containing the current value of the jacobian of * the state vector with respect to initial state * @param dydp array containing the current value of the jacobian of * the state vector with respect to parameters * @param increasing if true, the value of the switching function increases * when times increases around event (note that increase is measured with respect * to physical time, not with respect to integration which may go backward in time) * @return indication of what the integrator should do next, this * value must be one of {@link #STOP}, {@link #RESET_STATE}, * {@link #RESET_DERIVATIVES} or {@link #CONTINUE} * @exception EventException if the event occurrence triggers an error */ int eventOccurred(double t, double[] y, double[][] dydy0, double[][] dydp, boolean increasing) throws EventException; /** Reset the state prior to continue the integration. *

                      This method is called after the step handler has returned and * before the next step is started, but only when {@link * #eventOccurred} has itself returned the {@link #RESET_STATE} * indicator. It allows the user to reset the state vector for the * next step, without perturbing the step handler of the finishing * step. If the {@link #eventOccurred} never returns the {@link * #RESET_STATE} indicator, this function will never be called, and it is * safe to leave its body empty.

                      * @param t current value of the independent time variable * @param y array containing the current value of the state vector * the new state should be put in the same array * @param dydy0 array containing the current value of the jacobian of * the state vector with respect to initial state, the new jacobian * should be put in the same array * @param dydp array containing the current value of the jacobian of * the state vector with respect to parameters, the new jacobian * should be put in the same array * @exception EventException if the state cannot be reseted */ void resetState(double t, double[] y, double[][] dydy0, double[][] dydp) throws EventException; } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobia100644 1750 1750 17526 11532241246 32446 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import java.io.Externalizable; import org.apache.commons.math.ode.DerivativeException; /** This interface represents an interpolator over the last step * during an ODE integration. * *

                      The various ODE integrators provide objects implementing this * interface to the step handlers. These objects are often custom * objects tightly bound to the integrator internal algorithms. The * handlers can use these objects to retrieve the state vector at * intermediate times between the previous and the current grid points * (this feature is often called dense output).

                      *

                      One important thing to note is that the step handlers may be so * tightly bound to the integrators that they often share some internal * state arrays. This imply that one should never use a direct * reference to a step interpolator outside of the step handler, either * for future use or for use in another thread. If such a need arise, the * step interpolator must be copied using the dedicated * {@link #copy()} method. *

                      * * @see FirstOrderIntegratorWithJacobians * @see StepHandlerWithJacobians * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public interface StepInterpolatorWithJacobians extends Externalizable { /** * Get the previous grid point time. * @return previous grid point time */ double getPreviousTime(); /** * Get the current grid point time. * @return current grid point time */ double getCurrentTime(); /** * Get the time of the interpolated point. * If {@link #setInterpolatedTime} has not been called, it returns * the current grid point time. * @return interpolation point time */ double getInterpolatedTime(); /** * Set the time of the interpolated point. *

                      Setting the time outside of the current step is now allowed, but * should be used with care since the accuracy of the interpolator will * probably be very poor far from this step. This allowance has been * added to simplify implementation of search algorithms near the * step endpoints.

                      *

                      Setting the time changes the instance internal state. If a * specific state must be preserved, a copy of the instance must be * created using {@link #copy()}.

                      * @param time time of the interpolated point */ void setInterpolatedTime(double time); /** * Get the state vector of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return state vector at time {@link #getInterpolatedTime} * @see #getInterpolatedYDot() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[] getInterpolatedY() throws DerivativeException; /** * Get the partial derivatives of the state vector with respect to * the initial state of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return partial derivatives of the state vector with respect to * the initial state at time {@link #getInterpolatedTime} * @see #getInterpolatedY() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[][] getInterpolatedDyDy0() throws DerivativeException; /** * Get the partial derivatives of the state vector with respect to * the ODE parameters of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return partial derivatives of the state vector with respect to * the ODE parameters at time {@link #getInterpolatedTime} * @see #getInterpolatedY() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[][] getInterpolatedDyDp() throws DerivativeException; /** * Get the time derivatives of the state vector of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return derivatives of the state vector at time {@link #getInterpolatedTime} * @see #getInterpolatedY() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[] getInterpolatedYDot() throws DerivativeException; /** * Get the time derivatives of the jacobian of the state vector * with respect to the initial state of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return time derivatives of the jacobian of the state vector * with respect to the initial state at time {@link #getInterpolatedTime} * @see #getInterpolatedY() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[][] getInterpolatedDyDy0Dot() throws DerivativeException; /** * Get the time derivatives of the jacobian of the state vector * with respect to the ODE parameters of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return time derivatives of the jacobian of the state vector * with respect to the ODE parameters at time {@link #getInterpolatedTime} * @see #getInterpolatedY() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ double[][] getInterpolatedDyDpDot() throws DerivativeException; /** Check if the natural integration direction is forward. *

                      This method provides the integration direction as specified by * the integrator itself, it avoid some nasty problems in * degenerated cases like null steps due to cancellation at step * initialization, step control or discrete events * triggering.

                      * @return true if the integration variable (time) increases during * integration */ boolean isForward(); /** Copy the instance. *

                      The copied instance is guaranteed to be independent from the * original one. Both can be used with different settings for * interpolated time without any side effect.

                      * @return a deep copy of the instance, which can be used independently. * @throws DerivativeException if this call induces an automatic * step finalization that throws one * @see #setInterpolatedTime(double) */ StepInterpolatorWithJacobians copy() throws DerivativeException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/package.html100644 1750 1750 2305 11532241246 27326 0ustarlucluc 0 0

                      This package was intended to solve Ordinary Differential Equations problems and also compute derivatives of the solution. It was introduced in 2.1 but is difficult to use and clumsy. It is completely deprecated in 2.2 and will be removed in 3.0, to be replaced by a completely new implementation, much more tightly bound to the top level ode package.

                      commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/ODEWithJacobians.java100644 1750 1750 4540 11532241246 30770 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; /** This interface represents {@link ParameterizedODE * first order differential equations} with parameters and partial derivatives. * * @see FirstOrderIntegratorWithJacobians * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public interface ODEWithJacobians extends FirstOrderDifferentialEquations { /** Get the number of parameters. * @return number of parameters */ int getParametersDimension(); /** Compute the partial derivatives of ODE with respect to state. * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param yDot array containing the current value of the time derivative of the state vector * @param dFdY placeholder array where to put the jacobian of the ODE with respect to the state vector * @param dFdP placeholder array where to put the jacobian of the ODE with respect to the parameters * @throws DerivativeException this exception is propagated to the caller if the * underlying user function triggers one */ void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) throws DerivativeException; } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.ja100644 1750 1750 11347 11532241246 32266 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import org.apache.commons.math.ode.DerivativeException; /** * This interface represents a handler that should be called after * each successful step. * *

                      The ODE integrators compute the evolution of the state vector at * some grid points that depend on their own internal algorithm. Once * they have found a new grid point (possibly after having computed * several evaluation of the derivative at intermediate points), they * provide it to objects implementing this interface. These objects * typically either ignore the intermediate steps and wait for the * last one, store the points in an ephemeris, or forward them to * specialized processing or output methods.

                      * *

                      Note that is is possible to register a {@link * org.apache.commons.math.ode.sampling.StepHandler classical step handler} * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians} * rather than implementing this class. The step handlers registered at low level * will see the big compound state whether the step handlers defined by this interface * see the original state, and its jacobians in separate arrays.

                      * *

                      The compound state is guaranteed to contain the original state in the first * elements, followed by the jacobian with respect to initial state (in row order), * followed by the jacobian with respect to parameters (in row order). If for example * the original state dimension is 6 and there are 3 parameters, the compound state will * be a 60 elements array. The first 6 elements will be the original state, the next 36 * elements will be the jacobian with respect to initial state, and the remaining 18 elements * will be the jacobian with respect to parameters.

                      * *

                      Dealing with low level step handlers is cumbersome if one really needs the jacobians * in these methods, but it also prevents many data being copied back and forth between * state and jacobians on one side and compound state on the other side. So for performance * reasons, it is recommended to use this interface only if jacobians are really * needed and to use lower level handlers if only state is needed.

                      * * @see FirstOrderIntegratorWithJacobians * @see StepInterpolatorWithJacobians * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public interface StepHandlerWithJacobians { /** Determines whether this handler needs dense output. *

                      This method allows the integrator to avoid performing extra * computation if the handler does not need dense output.

                      * @return true if the handler needs dense output */ boolean requiresDenseOutput(); /** Reset the step handler. * Initialize the internal data as required before the first step is * handled. */ void reset(); /** * Handle the last accepted step * @param interpolator interpolator for the last accepted step. For * efficiency purposes, the various integrators reuse the same * object on each call, so if the instance wants to keep it across * all calls (for example to provide at the end of the integration a * continuous model valid throughout the integration range, as the * {@link org.apache.commons.math.ode.ContinuousOutputModel * ContinuousOutputModel} class does), it should build a local copy * using the clone method of the interpolator and store this copy. * Keeping only a reference to the interpolator and reusing it will * result in unpredictable behavior (potentially crashing the application). * @param isLast true if the step is the last one * @throws DerivativeException this exception is propagated to the * caller if the underlying user function triggers one */ void handleStep(StepInterpolatorWithJacobians interpolator, boolean isLast) throws DerivativeException; } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJac100644 1750 1750 104270 11532241246 32430 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.ExtendedFirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderIntegrator; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.events.EventException; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; /** This class enhances a first order integrator for differential equations to * compute also partial derivatives of the solution with respect to initial state * and parameters. *

                      In order to compute both the state and its derivatives, the ODE problem * is extended with jacobians of the raw ODE and the variational equations are * added to form a new compound problem of higher dimension. If the original ODE * problem has dimension n and there are p parameters, the compound problem will * have dimension n × (1 + n + p).

                      * @see ParameterizedODE * @see ODEWithJacobians * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public class FirstOrderIntegratorWithJacobians { /** Underlying integrator for compound problem. */ private final FirstOrderIntegrator integrator; /** Raw equations to integrate. */ private final ODEWithJacobians ode; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Build an enhanced integrator using internal differentiation to compute jacobians. * @param integrator underlying integrator to solve the compound problem * @param ode original problem (f in the equation y' = f(t, y)) * @param p parameters array (may be null if {@link * ParameterizedODE#getParametersDimension() * getParametersDimension()} from original problem is zero) * @param hY step sizes to use for computing the jacobian df/dy, must have the * same dimension as the original problem * @param hP step sizes to use for computing the jacobian df/dp, must have the * same dimension as the original problem parameters dimension * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator, * ODEWithJacobians) */ public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, final ParameterizedODE ode, final double[] p, final double[] hY, final double[] hP) { checkDimension(ode.getDimension(), hY); checkDimension(ode.getParametersDimension(), p); checkDimension(ode.getParametersDimension(), hP); this.integrator = integrator; this.ode = new FiniteDifferencesWrapper(ode, p, hY, hP); setMaxEvaluations(-1); } /** Build an enhanced integrator using ODE builtin jacobian computation features. * @param integrator underlying integrator to solve the compound problem * @param ode original problem, which can compute the jacobians by itself * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator, * ParameterizedODE, double[], double[], double[]) */ public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, final ODEWithJacobians ode) { this.integrator = integrator; this.ode = ode; setMaxEvaluations(-1); } /** Add a step handler to this integrator. *

                      The handler will be called by the integrator for each accepted * step.

                      * @param handler handler for the accepted steps * @see #getStepHandlers() * @see #clearStepHandlers() */ public void addStepHandler(StepHandlerWithJacobians handler) { final int n = ode.getDimension(); final int k = ode.getParametersDimension(); integrator.addStepHandler(new StepHandlerWrapper(handler, n, k)); } /** Get all the step handlers that have been added to the integrator. * @return an unmodifiable collection of the added events handlers * @see #addStepHandler(StepHandlerWithJacobians) * @see #clearStepHandlers() */ public Collection getStepHandlers() { final Collection handlers = new ArrayList(); for (final StepHandler handler : integrator.getStepHandlers()) { if (handler instanceof StepHandlerWrapper) { handlers.add(((StepHandlerWrapper) handler).getHandler()); } } return handlers; } /** Remove all the step handlers that have been added to the integrator. * @see #addStepHandler(StepHandlerWithJacobians) * @see #getStepHandlers() */ public void clearStepHandlers() { integrator.clearStepHandlers(); } /** Add an event handler to the integrator. * @param handler event handler * @param maxCheckInterval maximal time interval between switching * function checks (this interval prevents missing sign changes in * case the integration steps becomes very large) * @param convergence convergence threshold in the event time search * @param maxIterationCount upper limit of the iteration count in * the event time search * @see #getEventHandlers() * @see #clearEventHandlers() */ public void addEventHandler(EventHandlerWithJacobians handler, double maxCheckInterval, double convergence, int maxIterationCount) { final int n = ode.getDimension(); final int k = ode.getParametersDimension(); integrator.addEventHandler(new EventHandlerWrapper(handler, n, k), maxCheckInterval, convergence, maxIterationCount); } /** Get all the event handlers that have been added to the integrator. * @return an unmodifiable collection of the added events handlers * @see #addEventHandler(EventHandlerWithJacobians, double, double, int) * @see #clearEventHandlers() */ public Collection getEventHandlers() { final Collection handlers = new ArrayList(); for (final EventHandler handler : integrator.getEventHandlers()) { if (handler instanceof EventHandlerWrapper) { handlers.add(((EventHandlerWrapper) handler).getHandler()); } } return handlers; } /** Remove all the event handlers that have been added to the integrator. * @see #addEventHandler(EventHandlerWithJacobians, double, double, int) * @see #getEventHandlers() */ public void clearEventHandlers() { integrator.clearEventHandlers(); } /** Integrate the differential equations and the variational equations up to the given time. *

                      This method solves an Initial Value Problem (IVP) and also computes the derivatives * of the solution with respect to initial state and parameters. This can be used as * a basis to solve Boundary Value Problems (BVP).

                      *

                      Since this method stores some internal state variables made * available in its public interface during integration ({@link * #getCurrentSignedStepsize()}), it is not thread-safe.

                      * @param t0 initial time * @param y0 initial value of the state vector at t0 * @param dY0dP initial value of the state vector derivative with respect to the * parameters at t0 * @param t target time for the integration * (can be set to a value smaller than t0 for backward integration) * @param y placeholder where to put the state vector at each successful * step (and hence at the end of integration), can be the same object as y0 * @param dYdY0 placeholder where to put the state vector derivative with respect * to the initial state (dy[i]/dy0[j] is in element array dYdY0[i][j]) at each successful * step (and hence at the end of integration) * @param dYdP placeholder where to put the state vector derivative with respect * to the parameters (dy[i]/dp[j] is in element array dYdP[i][j]) at each successful * step (and hence at the end of integration) * @return stop time, will be the same as target time if integration reached its * target, but may be different if some event handler stops it at some point. * @throws IntegratorException if the integrator cannot perform integration * @throws DerivativeException this exception is propagated to the caller if * the underlying user function triggers one */ public double integrate(final double t0, final double[] y0, final double[][] dY0dP, final double t, final double[] y, final double[][] dYdY0, final double[][] dYdP) throws DerivativeException, IntegratorException { final int n = ode.getDimension(); final int k = ode.getParametersDimension(); checkDimension(n, y0); checkDimension(n, y); checkDimension(n, dYdY0); checkDimension(n, dYdY0[0]); if (k != 0) { checkDimension(n, dY0dP); checkDimension(k, dY0dP[0]); checkDimension(n, dYdP); checkDimension(k, dYdP[0]); } // set up initial state, including partial derivatives // the compound state z contains the raw state y and its derivatives // with respect to initial state y0 and to parameters p // y[i] is stored in z[i] // dy[i]/dy0[j] is stored in z[n + i * n + j] // dy[i]/dp[j] is stored in z[n * (n + 1) + i * k + j] final double[] z = new double[n * (1 + n + k)]; System.arraycopy(y0, 0, z, 0, n); for (int i = 0; i < n; ++i) { // set diagonal element of dy/dy0 to 1.0 at t = t0 z[i * (1 + n) + n] = 1.0; // set initial derivatives with respect to parameters System.arraycopy(dY0dP[i], 0, z, n * (n + 1) + i * k, k); } // integrate the compound state variational equations evaluations = 0; final double stopTime = integrator.integrate(new MappingWrapper(), t0, z, t, z); // dispatch the final compound state into the state and partial derivatives arrays dispatchCompoundState(z, y, dYdY0, dYdP); return stopTime; } /** Dispatch a compound state array into state and jacobians arrays. * @param z compound state * @param y raw state array to fill * @param dydy0 jacobian array to fill * @param dydp jacobian array to fill */ private static void dispatchCompoundState(final double[] z, final double[] y, final double[][] dydy0, final double[][] dydp) { final int n = y.length; final int k = dydp[0].length; // state System.arraycopy(z, 0, y, 0, n); // jacobian with respect to initial state for (int i = 0; i < n; ++i) { System.arraycopy(z, n * (i + 1), dydy0[i], 0, n); } // jacobian with respect to parameters for (int i = 0; i < n; ++i) { System.arraycopy(z, n * (n + 1) + i * k, dydp[i], 0, k); } } /** Get the current value of the step start time ti. *

                      This method can be called during integration (typically by * the object implementing the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations * differential equations} problem) if the value of the current step that * is attempted is needed.

                      *

                      The result is undefined if the method is called outside of * calls to integrate.

                      * @return current value of the step start time ti */ public double getCurrentStepStart() { return integrator.getCurrentStepStart(); } /** Get the current signed value of the integration stepsize. *

                      This method can be called during integration (typically by * the object implementing the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations * differential equations} problem) if the signed value of the current stepsize * that is tried is needed.

                      *

                      The result is undefined if the method is called outside of * calls to integrate.

                      * @return current signed value of the stepsize */ public double getCurrentSignedStepsize() { return integrator.getCurrentSignedStepsize(); } /** Set the maximal number of differential equations function evaluations. *

                      The purpose of this method is to avoid infinite loops which can occur * for example when stringent error constraints are set or when lots of * discrete events are triggered, thus leading to many rejected steps.

                      * @param maxEvaluations maximal number of function evaluations (negative * values are silently converted to maximal integer value, thus representing * almost unlimited evaluations) */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations; } /** Get the maximal number of functions evaluations. * @return maximal number of functions evaluations */ public int getMaxEvaluations() { return maxEvaluations; } /** Get the number of evaluations of the differential equations function. *

                      * The number of evaluations corresponds to the last call to the * integrate method. It is 0 if the method has not been called yet. *

                      * @return number of evaluations of the differential equations function */ public int getEvaluations() { return evaluations; } /** Check array dimensions. * @param expected expected dimension * @param array (may be null if expected is 0) * @throws IllegalArgumentException if the array dimension does not match the expected one */ private void checkDimension(final int expected, final Object array) throws IllegalArgumentException { int arrayDimension = (array == null) ? 0 : Array.getLength(array); if (arrayDimension != expected) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, arrayDimension, expected); } } /** Wrapper class used to map state and jacobians into compound state. */ private class MappingWrapper implements ExtendedFirstOrderDifferentialEquations { /** Current state. */ private final double[] y; /** Time derivative of the current state. */ private final double[] yDot; /** Derivatives of yDot with respect to state. */ private final double[][] dFdY; /** Derivatives of yDot with respect to parameters. */ private final double[][] dFdP; /** Simple constructor. */ public MappingWrapper() { final int n = ode.getDimension(); final int k = ode.getParametersDimension(); y = new double[n]; yDot = new double[n]; dFdY = new double[n][n]; dFdP = new double[n][k]; } /** {@inheritDoc} */ public int getDimension() { final int n = y.length; final int k = dFdP[0].length; return n * (1 + n + k); } /** {@inheritDoc} */ public int getMainSetDimension() { return ode.getDimension(); } /** {@inheritDoc} */ public void computeDerivatives(final double t, final double[] z, final double[] zDot) throws DerivativeException { final int n = y.length; final int k = dFdP[0].length; // compute raw ODE and its jacobians: dy/dt, d[dy/dt]/dy0 and d[dy/dt]/dp System.arraycopy(z, 0, y, 0, n); if (++evaluations > maxEvaluations) { throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); } ode.computeDerivatives(t, y, yDot); ode.computeJacobians(t, y, yDot, dFdY, dFdP); // state part of the compound equations System.arraycopy(yDot, 0, zDot, 0, n); // variational equations: from d[dy/dt]/dy0 to d[dy/dy0]/dt for (int i = 0; i < n; ++i) { final double[] dFdYi = dFdY[i]; for (int j = 0; j < n; ++j) { double s = 0; final int startIndex = n + j; int zIndex = startIndex; for (int l = 0; l < n; ++l) { s += dFdYi[l] * z[zIndex]; zIndex += n; } zDot[startIndex + i * n] = s; } } // variational equations: from d[dy/dt]/dy0 and d[dy/dt]/dp to d[dy/dp]/dt for (int i = 0; i < n; ++i) { final double[] dFdYi = dFdY[i]; final double[] dFdPi = dFdP[i]; for (int j = 0; j < k; ++j) { double s = dFdPi[j]; final int startIndex = n * (n + 1) + j; int zIndex = startIndex; for (int l = 0; l < n; ++l) { s += dFdYi[l] * z[zIndex]; zIndex += k; } zDot[startIndex + i * k] = s; } } } } /** Wrapper class to compute jacobians by finite differences for ODE which do not compute them themselves. */ private class FiniteDifferencesWrapper implements ODEWithJacobians { /** Raw ODE without jacobians computation. */ private final ParameterizedODE ode; /** Parameters array (may be null if parameters dimension from original problem is zero) */ private final double[] p; /** Step sizes to use for computing the jacobian df/dy. */ private final double[] hY; /** Step sizes to use for computing the jacobian df/dp. */ private final double[] hP; /** Temporary array for state derivatives used to compute jacobians. */ private final double[] tmpDot; /** Simple constructor. * @param ode original ODE problem, without jacobians computations * @param p parameters array (may be null if parameters dimension from original problem is zero) * @param hY step sizes to use for computing the jacobian df/dy * @param hP step sizes to use for computing the jacobian df/dp */ public FiniteDifferencesWrapper(final ParameterizedODE ode, final double[] p, final double[] hY, final double[] hP) { this.ode = ode; this.p = p.clone(); this.hY = hY.clone(); this.hP = hP.clone(); tmpDot = new double[ode.getDimension()]; } /** {@inheritDoc} */ public int getDimension() { return ode.getDimension(); } /** {@inheritDoc} */ public void computeDerivatives(double t, double[] y, double[] yDot) throws DerivativeException { // this call to computeDerivatives has already been counted, // we must not increment the counter again ode.computeDerivatives(t, y, yDot); } /** {@inheritDoc} */ public int getParametersDimension() { return ode.getParametersDimension(); } /** {@inheritDoc} */ public void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) throws DerivativeException { final int n = hY.length; final int k = hP.length; evaluations += n + k; if (evaluations > maxEvaluations) { throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); } // compute df/dy where f is the ODE and y is the state array for (int j = 0; j < n; ++j) { final double savedYj = y[j]; y[j] += hY[j]; ode.computeDerivatives(t, y, tmpDot); for (int i = 0; i < n; ++i) { dFdY[i][j] = (tmpDot[i] - yDot[i]) / hY[j]; } y[j] = savedYj; } // compute df/dp where f is the ODE and p is the parameters array for (int j = 0; j < k; ++j) { ode.setParameter(j, p[j] + hP[j]); ode.computeDerivatives(t, y, tmpDot); for (int i = 0; i < n; ++i) { dFdP[i][j] = (tmpDot[i] - yDot[i]) / hP[j]; } ode.setParameter(j, p[j]); } } } /** Wrapper for step handlers. */ private static class StepHandlerWrapper implements StepHandler { /** Underlying step handler with jacobians. */ private final StepHandlerWithJacobians handler; /** Dimension of the original ODE. */ private final int n; /** Number of parameters. */ private final int k; /** Simple constructor. * @param handler underlying step handler with jacobians * @param n dimension of the original ODE * @param k number of parameters */ public StepHandlerWrapper(final StepHandlerWithJacobians handler, final int n, final int k) { this.handler = handler; this.n = n; this.k = k; } /** Get the underlying step handler with jacobians. * @return underlying step handler with jacobians */ public StepHandlerWithJacobians getHandler() { return handler; } /** {@inheritDoc} */ public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { handler.handleStep(new StepInterpolatorWrapper(interpolator, n, k), isLast); } /** {@inheritDoc} */ public boolean requiresDenseOutput() { return handler.requiresDenseOutput(); } /** {@inheritDoc} */ public void reset() { handler.reset(); } } /** Wrapper for step interpolators. */ private static class StepInterpolatorWrapper implements StepInterpolatorWithJacobians { /** Wrapped interpolator. */ private StepInterpolator interpolator; /** State array. */ private double[] y; /** Jacobian with respect to initial state dy/dy0. */ private double[][] dydy0; /** Jacobian with respect to parameters dy/dp. */ private double[][] dydp; /** Time derivative of the state array. */ private double[] yDot; /** Time derivative of the sacobian with respect to initial state dy/dy0. */ private double[][] dydy0Dot; /** Time derivative of the jacobian with respect to parameters dy/dp. */ private double[][] dydpDot; /** Simple constructor. *

                      This constructor is used only for externalization. It does nothing.

                      */ @SuppressWarnings("unused") public StepInterpolatorWrapper() { } /** Simple constructor. * @param interpolator wrapped interpolator * @param n dimension of the original ODE * @param k number of parameters */ public StepInterpolatorWrapper(final StepInterpolator interpolator, final int n, final int k) { this.interpolator = interpolator; y = new double[n]; dydy0 = new double[n][n]; dydp = new double[n][k]; yDot = new double[n]; dydy0Dot = new double[n][n]; dydpDot = new double[n][k]; } /** {@inheritDoc} */ public void setInterpolatedTime(double time) { interpolator.setInterpolatedTime(time); } /** {@inheritDoc} */ public boolean isForward() { return interpolator.isForward(); } /** {@inheritDoc} */ public double getPreviousTime() { return interpolator.getPreviousTime(); } /** {@inheritDoc} */ public double getInterpolatedTime() { return interpolator.getInterpolatedTime(); } /** {@inheritDoc} */ public double[] getInterpolatedY() throws DerivativeException { double[] extendedState = interpolator.getInterpolatedState(); System.arraycopy(extendedState, 0, y, 0, y.length); return y; } /** {@inheritDoc} */ public double[][] getInterpolatedDyDy0() throws DerivativeException { double[] extendedState = interpolator.getInterpolatedState(); final int n = y.length; int start = n; for (int i = 0; i < n; ++i) { System.arraycopy(extendedState, start, dydy0[i], 0, n); start += n; } return dydy0; } /** {@inheritDoc} */ public double[][] getInterpolatedDyDp() throws DerivativeException { double[] extendedState = interpolator.getInterpolatedState(); final int n = y.length; final int k = dydp[0].length; int start = n * (n + 1); for (int i = 0; i < n; ++i) { System.arraycopy(extendedState, start, dydp[i], 0, k); start += k; } return dydp; } /** {@inheritDoc} */ public double[] getInterpolatedYDot() throws DerivativeException { double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); System.arraycopy(extendedDerivatives, 0, yDot, 0, yDot.length); return yDot; } /** {@inheritDoc} */ public double[][] getInterpolatedDyDy0Dot() throws DerivativeException { double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); final int n = y.length; int start = n; for (int i = 0; i < n; ++i) { System.arraycopy(extendedDerivatives, start, dydy0Dot[i], 0, n); start += n; } return dydy0Dot; } /** {@inheritDoc} */ public double[][] getInterpolatedDyDpDot() throws DerivativeException { double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); final int n = y.length; final int k = dydpDot[0].length; int start = n * (n + 1); for (int i = 0; i < n; ++i) { System.arraycopy(extendedDerivatives, start, dydpDot[i], 0, k); start += k; } return dydpDot; } /** {@inheritDoc} */ public double getCurrentTime() { return interpolator.getCurrentTime(); } /** {@inheritDoc} */ public StepInterpolatorWithJacobians copy() throws DerivativeException { final int n = y.length; final int k = dydp[0].length; StepInterpolatorWrapper copied = new StepInterpolatorWrapper(interpolator.copy(), n, k); copyArray(y, copied.y); copyArray(dydy0, copied.dydy0); copyArray(dydp, copied.dydp); copyArray(yDot, copied.yDot); copyArray(dydy0Dot, copied.dydy0Dot); copyArray(dydpDot, copied.dydpDot); return copied; } /** {@inheritDoc} */ public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(interpolator); out.writeInt(y.length); out.writeInt(dydp[0].length); writeArray(out, y); writeArray(out, dydy0); writeArray(out, dydp); writeArray(out, yDot); writeArray(out, dydy0Dot); writeArray(out, dydpDot); } /** {@inheritDoc} */ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { interpolator = (StepInterpolator) in.readObject(); final int n = in.readInt(); final int k = in.readInt(); y = new double[n]; dydy0 = new double[n][n]; dydp = new double[n][k]; yDot = new double[n]; dydy0Dot = new double[n][n]; dydpDot = new double[n][k]; readArray(in, y); readArray(in, dydy0); readArray(in, dydp); readArray(in, yDot); readArray(in, dydy0Dot); readArray(in, dydpDot); } /** Copy an array. * @param src source array * @param dest destination array */ private static void copyArray(final double[] src, final double[] dest) { System.arraycopy(src, 0, dest, 0, src.length); } /** Copy an array. * @param src source array * @param dest destination array */ private static void copyArray(final double[][] src, final double[][] dest) { for (int i = 0; i < src.length; ++i) { copyArray(src[i], dest[i]); } } /** Write an array. * @param out output stream * @param array array to write * @exception IOException if array cannot be read */ private static void writeArray(final ObjectOutput out, final double[] array) throws IOException { for (int i = 0; i < array.length; ++i) { out.writeDouble(array[i]); } } /** Write an array. * @param out output stream * @param array array to write * @exception IOException if array cannot be read */ private static void writeArray(final ObjectOutput out, final double[][] array) throws IOException { for (int i = 0; i < array.length; ++i) { writeArray(out, array[i]); } } /** Read an array. * @param in input stream * @param array array to read * @exception IOException if array cannot be read */ private static void readArray(final ObjectInput in, final double[] array) throws IOException { for (int i = 0; i < array.length; ++i) { array[i] = in.readDouble(); } } /** Read an array. * @param in input stream * @param array array to read * @exception IOException if array cannot be read */ private static void readArray(final ObjectInput in, final double[][] array) throws IOException { for (int i = 0; i < array.length; ++i) { readArray(in, array[i]); } } } /** Wrapper for event handlers. */ private static class EventHandlerWrapper implements EventHandler { /** Underlying event handler with jacobians. */ private final EventHandlerWithJacobians handler; /** State array. */ private double[] y; /** Jacobian with respect to initial state dy/dy0. */ private double[][] dydy0; /** Jacobian with respect to parameters dy/dp. */ private double[][] dydp; /** Simple constructor. * @param handler underlying event handler with jacobians * @param n dimension of the original ODE * @param k number of parameters */ public EventHandlerWrapper(final EventHandlerWithJacobians handler, final int n, final int k) { this.handler = handler; y = new double[n]; dydy0 = new double[n][n]; dydp = new double[n][k]; } /** Get the underlying event handler with jacobians. * @return underlying event handler with jacobians */ public EventHandlerWithJacobians getHandler() { return handler; } /** {@inheritDoc} */ public int eventOccurred(double t, double[] z, boolean increasing) throws EventException { dispatchCompoundState(z, y, dydy0, dydp); return handler.eventOccurred(t, y, dydy0, dydp, increasing); } /** {@inheritDoc} */ public double g(double t, double[] z) throws EventException { dispatchCompoundState(z, y, dydy0, dydp); return handler.g(t, y, dydy0, dydp); } /** {@inheritDoc} */ public void resetState(double t, double[] z) throws EventException { dispatchCompoundState(z, y, dydy0, dydp); handler.resetState(t, y, dydy0, dydp); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java100644 1750 1750 3405 11532241246 31036 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.jacobians; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; /** This interface represents {@link FirstOrderDifferentialEquations * first order differential equations} with parameters. * * @see FirstOrderIntegratorWithJacobians * * @version $Revision: 1037341 $ $Date: 2010-11-20 22:58:35 +0100 (sam. 20 nov. 2010) $ * @since 2.1 * @deprecated as of 2.2 the complete package is deprecated, it will be replaced * in 3.0 by a completely rewritten implementation */ @Deprecated public interface ParameterizedODE extends FirstOrderDifferentialEquations { /** Get the number of parameters. * @return number of parameters */ int getParametersDimension(); /** Set a parameter. * @param i index of the parameters (must be between 0 * and {@link #getParametersDimension() getParametersDimension() - 1}) * @param value value for the parameter */ void setParameter(int i, double value); } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/ExtendedFirstOrderDifferentialEquations.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/ExtendedFirstOrderDifferentialEquatio100644 1750 1750 5372 11532241246 32457 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** This interface represents a first order differential equations set * with a main set of equations and an extension set. * *

                      * This interface is a simple extension on the {@link * FirstOrderDifferentialEquations} that allows to identify which part * of a complete set of differential equations correspond to the main * set and which part correspond to the extension set. *

                      *

                      * One typical use case is the computation of Jacobians. The main * set of equations correspond to the raw ode, and we add to this set * another bunch of equations which represent the jacobians of the * main set. In that case, we want the integrator to use only * the main set to estimate the errors and hence the step sizes. It should * not use the additional equations in this computation. If the * complete ode implements this interface, the {@link FirstOrderIntegrator * integrator} will be able to know where the main set ends and where the * extended set begins. *

                      *

                      * We consider that the main set always corresponds to the first equations * and the extended set to the last equations. *

                      * * @see FirstOrderDifferentialEquations * * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $ * @since 2.2 */ public interface ExtendedFirstOrderDifferentialEquations extends FirstOrderDifferentialEquations { /** Return the dimension of the main set of equations. *

                      * The main set of equations represent the first part of an ODE state. * The error estimations and adaptive step size computation should be * done on this first part only, not on the final part of the state * which represent an extension set of equations which are considered * secondary. *

                      * @return dimension of the main set of equations, must be lesser than or * equal to the {@link #getDimension() total dimension} */ int getMainSetDimension(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/SecondOrderIntegrator.java100644 1750 1750 5040 11532241246 30224 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.DerivativeException; /** This interface represents a second order integrator for * differential equations. * *

                      The classes which are devoted to solve second order differential * equations should implement this interface. The problems which can * be handled should implement the {@link * SecondOrderDifferentialEquations} interface.

                      * * @see SecondOrderDifferentialEquations * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface SecondOrderIntegrator extends ODEIntegrator { /** Integrate the differential equations up to the given time * @param equations differential equations to integrate * @param t0 initial time * @param y0 initial value of the state vector at t0 * @param yDot0 initial value of the first derivative of the state * vector at t0 * @param t target time for the integration * (can be set to a value smaller thant t0 for backward integration) * @param y placeholder where to put the state vector at each * successful step (and hence at the end of integration), can be the * same object as y0 * @param yDot placeholder where to put the first derivative of * the state vector at time t, can be the same object as yDot0 * @throws IntegratorException if the integrator cannot perform integration * @throws DerivativeException this exception is propagated to the caller if the * underlying user function triggers one */ void integrate(SecondOrderDifferentialEquations equations, double t0, double[] y0, double[] yDot0, double t, double[] y, double[] yDot) throws DerivativeException, IntegratorException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/FirstOrderIntegrator.java100644 1750 1750 5465 11532241246 30113 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; /** This interface represents a first order integrator for * differential equations. *

                      The classes which are devoted to solve first order differential * equations should implement this interface. The problems which can * be handled should implement the {@link * FirstOrderDifferentialEquations} interface.

                      * * @see FirstOrderDifferentialEquations * @see org.apache.commons.math.ode.sampling.StepHandler * @see org.apache.commons.math.ode.events.EventHandler * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface FirstOrderIntegrator extends ODEIntegrator { /** Integrate the differential equations up to the given time. *

                      This method solves an Initial Value Problem (IVP).

                      *

                      Since this method stores some internal state variables made * available in its public interface during integration ({@link * #getCurrentSignedStepsize()}), it is not thread-safe.

                      * @param equations differential equations to integrate * @param t0 initial time * @param y0 initial value of the state vector at t0 * @param t target time for the integration * (can be set to a value smaller than t0 for backward integration) * @param y placeholder where to put the state vector at each successful * step (and hence at the end of integration), can be the same object as y0 * @return stop time, will be the same as target time if integration reached its * target, but may be different if some {@link * org.apache.commons.math.ode.events.EventHandler} stops it at some point. * @throws DerivativeException this exception is propagated to the caller if * the underlying user function triggers one * @throws IntegratorException if the integrator cannot perform integration */ double integrate (FirstOrderDifferentialEquations equations, double t0, double[] y0, double t, double[] y) throws DerivativeException, IntegratorException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/IntegratorException.java100644 1750 1750 4523 11532241246 27760 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.Localizable; /** * This exception is made available to users to report * the error conditions that are triggered during integration * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 1.2 */ public class IntegratorException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -1607588949778036796L; /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @deprecated as of 2.2 replaced by {@link #IntegratorException(Localizable, Object...)} */ @Deprecated public IntegratorException(final String specifier, final Object ... parts) { super(specifier, parts); } /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public IntegratorException(final Localizable specifier, final Object ... parts) { super(specifier, parts); } /** * Create an exception with a given root cause. * @param cause the exception or error that caused this exception to be thrown */ public IntegratorException(final Throwable cause) { super(cause); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/ODEIntegrator.java100644 1750 1750 12732 11532241246 26452 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import java.util.Collection; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.sampling.StepHandler; /** * This interface defines the common parts shared by integrators * for first and second order differential equations. * @see FirstOrderIntegrator * @see SecondOrderIntegrator * @version $Revision: 1061507 $ $Date: 2011-01-20 21:55:00 +0100 (jeu. 20 janv. 2011) $ * @since 2.0 */ public interface ODEIntegrator { /** Get the name of the method. * @return name of the method */ String getName(); /** Add a step handler to this integrator. *

                      The handler will be called by the integrator for each accepted * step.

                      * @param handler handler for the accepted steps * @see #getStepHandlers() * @see #clearStepHandlers() * @since 2.0 */ void addStepHandler(StepHandler handler); /** Get all the step handlers that have been added to the integrator. * @return an unmodifiable collection of the added events handlers * @see #addStepHandler(StepHandler) * @see #clearStepHandlers() * @since 2.0 */ Collection getStepHandlers(); /** Remove all the step handlers that have been added to the integrator. * @see #addStepHandler(StepHandler) * @see #getStepHandlers() * @since 2.0 */ void clearStepHandlers(); /** Add an event handler to the integrator. * @param handler event handler * @param maxCheckInterval maximal time interval between switching * function checks (this interval prevents missing sign changes in * case the integration steps becomes very large) * @param convergence convergence threshold in the event time search * @param maxIterationCount upper limit of the iteration count in * the event time search * @see #getEventHandlers() * @see #clearEventHandlers() */ void addEventHandler(EventHandler handler, double maxCheckInterval, double convergence, int maxIterationCount); /** Get all the event handlers that have been added to the integrator. * @return an unmodifiable collection of the added events handlers * @see #addEventHandler(EventHandler, double, double, int) * @see #clearEventHandlers() */ Collection getEventHandlers(); /** Remove all the event handlers that have been added to the integrator. * @see #addEventHandler(EventHandler, double, double, int) * @see #getEventHandlers() */ void clearEventHandlers(); /** Get the current value of the step start time ti. *

                      This method can be called during integration (typically by * the object implementing the {@link FirstOrderDifferentialEquations * differential equations} problem) if the value of the current step that * is attempted is needed.

                      *

                      The result is undefined if the method is called outside of * calls to integrate.

                      * @return current value of the step start time ti */ double getCurrentStepStart(); /** Get the current signed value of the integration stepsize. *

                      This method can be called during integration (typically by * the object implementing the {@link FirstOrderDifferentialEquations * differential equations} problem) if the signed value of the current stepsize * that is tried is needed.

                      *

                      The result is undefined if the method is called outside of * calls to integrate.

                      * @return current signed value of the stepsize */ double getCurrentSignedStepsize(); /** Set the maximal number of differential equations function evaluations. *

                      The purpose of this method is to avoid infinite loops which can occur * for example when stringent error constraints are set or when lots of * discrete events are triggered, thus leading to many rejected steps.

                      * @param maxEvaluations maximal number of function evaluations (negative * values are silently converted to maximal integer value, thus representing * almost unlimited evaluations) */ void setMaxEvaluations(int maxEvaluations); /** Get the maximal number of functions evaluations. * @return maximal number of functions evaluations */ int getMaxEvaluations(); /** Get the number of evaluations of the differential equations function. *

                      * The number of evaluations corresponds to the last call to the * integrate method. It is 0 if the method has not been called yet. *

                      * @return number of evaluations of the differential equations function */ int getEvaluations(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/package.html100644 1750 1750 20733 11532241246 25422 0ustarlucluc 0 0

                      This package provides classes to solve Ordinary Differential Equations problems.

                      This package solves Initial Value Problems of the form y'=f(t,y) with t0 and y(t0)=y0 known. The provided integrators compute an estimate of y(t) from t=t0 to t=t1. If in addition to y(t) users need to get the derivatives with respect to the initial state dy(t)/dy(t0) or the derivatives with respect to some ODE parameters dy(t)/dp, then the classes from the org.apache.commons.math.ode.jacobians package must be used instead of the classes in this package.

                      All integrators provide dense output. This means that besides computing the state vector at discrete times, they also provide a cheap mean to get the state between the time steps. They do so through classes extending the {@link org.apache.commons.math.ode.sampling.StepInterpolator StepInterpolator} abstract class, which are made available to the user at the end of each step.

                      All integrators handle multiple discrete events detection based on switching functions. This means that the integrator can be driven by user specified discrete events. The steps are shortened as needed to ensure the events occur at step boundaries (even if the integrator is a fixed-step integrator). When the events are triggered, integration can be stopped (this is called a G-stop facility), the state vector can be changed, or integration can simply go on. The latter case is useful to handle discontinuities in the differential equations gracefully and get accurate dense output even close to the discontinuity.

                      The user should describe his problem in his own classes (UserProblem in the diagram below) which should implement the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations FirstOrderDifferentialEquations} interface. Then he should pass it to the integrator he prefers among all the classes that implement the {@link org.apache.commons.math.ode.FirstOrderIntegrator FirstOrderIntegrator} interface.

                      The solution of the integration problem is provided by two means. The first one is aimed towards simple use: the state vector at the end of the integration process is copied in the y array of the {@link org.apache.commons.math.ode.FirstOrderIntegrator#integrate FirstOrderIntegrator.integrate} method. The second one should be used when more in-depth information is needed throughout the integration process. The user can register an object implementing the {@link org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface or a {@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} object wrapping a user-specified object implementing the {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} interface into the integrator before calling the {@link org.apache.commons.math.ode.FirstOrderIntegrator#integrate FirstOrderIntegrator.integrate} method. The user object will be called appropriately during the integration process, allowing the user to process intermediate results. The default step handler does nothing.

                      {@link org.apache.commons.math.ode.ContinuousOutputModel ContinuousOutputModel} is a special-purpose step handler that is able to store all steps and to provide transparent access to any intermediate result once the integration is over. An important feature of this class is that it implements the Serializable interface. This means that a complete continuous model of the integrated function throughout the integration range can be serialized and reused later (if stored into a persistent medium like a filesystem or a database) or elsewhere (if sent to another application). Only the result of the integration is stored, there is no reference to the integrated problem by itself.

                      Other default implementations of the {@link org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface are available for general needs ({@link org.apache.commons.math.ode.sampling.DummyStepHandler DummyStepHandler}, {@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer}) and custom implementations can be developed for specific needs. As an example, if an application is to be completely driven by the integration process, then most of the application code will be run inside a step handler specific to this application.

                      Some integrators (the simple ones) use fixed steps that are set at creation time. The more efficient integrators use variable steps that are handled internally in order to control the integration error with respect to a specified accuracy (these integrators extend the {@link org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator AdaptiveStepsizeIntegrator} abstract class). In this case, the step handler which is called after each successful step shows up the variable stepsize. The {@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} class can be used to convert the variable stepsize into a fixed stepsize that can be handled by classes implementing the {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} interface. Adaptive stepsize integrators can automatically compute the initial stepsize by themselves, however the user can specify it if he prefers to retain full control over the integration or if the automatic guess is wrong.

                      Fixed Step Integrators
                      NameOrder
                      {@link org.apache.commons.math.ode.nonstiff.EulerIntegrator Euler}1
                      {@link org.apache.commons.math.ode.nonstiff.MidpointIntegrator Midpoint}2
                      {@link org.apache.commons.math.ode.nonstiff.ClassicalRungeKuttaIntegrator Classical Runge-Kutta}4
                      {@link org.apache.commons.math.ode.nonstiff.GillIntegrator Gill}4
                      {@link org.apache.commons.math.ode.nonstiff.ThreeEighthesIntegrator 3/8}4

                      Adaptive Stepsize Integrators
                      NameIntegration OrderError Estimation Order
                      {@link org.apache.commons.math.ode.nonstiff.HighamHall54Integrator Higham and Hall}54
                      {@link org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator Dormand-Prince 5(4)}54
                      {@link org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator Dormand-Prince 8(5,3)}85 and 3
                      {@link org.apache.commons.math.ode.nonstiff.GraggBulirschStoerIntegrator Gragg-Bulirsch-Stoer}variable (up to 18 by default)variable
                      {@link org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator Adams-Bashforth}variablevariable
                      {@link org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator Adams-Moulton}variablevariable

                      In the table above, the {@link org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator Adams-Bashforth} and {@link org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator Adams-Moulton} integrators appear as variable-step ones. This is an experimental extension to the classical algorithms using the Nordsieck vector representation.

                      ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.java100644 1750 1750 4310 11532241246 32372 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; /** * This class implements the 3/8 fourth order Runge-Kutta * integrator for Ordinary Differential Equations. * *

                      This method is an explicit Runge-Kutta method, its Butcher-array * is the following one : *

                       *    0  |  0    0    0    0
                       *   1/3 | 1/3   0    0    0
                       *   2/3 |-1/3   1    0    0
                       *    1  |  1   -1    1    0
                       *       |--------------------
                       *       | 1/8  3/8  3/8  1/8
                       * 
                      *

                      * * @see EulerIntegrator * @see ClassicalRungeKuttaIntegrator * @see GillIntegrator * @see MidpointIntegrator * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $ * @since 1.2 */ public class ThreeEighthesIntegrator extends RungeKuttaIntegrator { /** Time steps Butcher array. */ private static final double[] STATIC_C = { 1.0 / 3.0, 2.0 / 3.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { { 1.0 / 3.0 }, { -1.0 / 3.0, 1.0 }, { 1.0, -1.0, 1.0 } }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 1.0 / 8.0, 3.0 / 8.0, 3.0 / 8.0, 1.0 / 8.0 }; /** Simple constructor. * Build a 3/8 integrator with the given step. * @param step integration step */ public ThreeEighthesIntegrator(final double step) { super("3/8", STATIC_C, STATIC_A, STATIC_B, new ThreeEighthesStepInterpolator(), step); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.java100644 1750 1750 14455 11532241246 30722 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.MultistepIntegrator; /** Base class for {@link AdamsBashforthIntegrator Adams-Bashforth} and * {@link AdamsMoultonIntegrator Adams-Moulton} integrators. * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public abstract class AdamsIntegrator extends MultistepIntegrator { /** Transformer. */ private final AdamsNordsieckTransformer transformer; /** * Build an Adams integrator with the given order and step control prameters. * @param name name of the method * @param nSteps number of steps of the method excluding the one being computed * @param order order of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsIntegrator(final String name, final int nSteps, final int order, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) throws IllegalArgumentException { super(name, nSteps, order, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); transformer = AdamsNordsieckTransformer.getInstance(nSteps); } /** * Build an Adams integrator with the given order and step control parameters. * @param name name of the method * @param nSteps number of steps of the method excluding the one being computed * @param order order of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsIntegrator(final String name, final int nSteps, final int order, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) throws IllegalArgumentException { super(name, nSteps, order, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); transformer = AdamsNordsieckTransformer.getInstance(nSteps); } /** {@inheritDoc} */ @Override public abstract double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException; /** {@inheritDoc} */ @Override protected Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, final double[][] multistep) { return transformer.initializeHighOrderDerivatives(first, multistep); } /** Update the high order scaled derivatives for Adams integrators (phase 1). *

                      The complete update of high order derivatives has a form similar to: *

                           * rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                           * 
                      * this method computes the P-1 A P rn part.

                      * @param highOrder high order scaled derivatives * (h2/2 y'', ... hk/k! y(k)) * @return updated high order derivatives * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix) */ public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) { return transformer.updateHighOrderDerivativesPhase1(highOrder); } /** Update the high order scaled derivatives Adams integrators (phase 2). *

                      The complete update of high order derivatives has a form similar to: *

                           * rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                           * 
                      * this method computes the (s1(n) - s1(n+1)) P-1 u part.

                      *

                      Phase 1 of the update must already have been performed.

                      * @param start first order scaled derivatives at step start * @param end first order scaled derivatives at step end * @param highOrder high order scaled derivatives, will be modified * (h2/2 y'', ... hk/k! y(k)) * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix) */ public void updateHighOrderDerivativesPhase2(final double[] start, final double[] end, final Array2DRowRealMatrix highOrder) { transformer.updateHighOrderDerivativesPhase2(start, end, highOrder); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator100644 1750 1750 32473 11532241246 32460 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; /** * This class implements the common part of all embedded Runge-Kutta * integrators for Ordinary Differential Equations. * *

                      These methods are embedded explicit Runge-Kutta methods with two * sets of coefficients allowing to estimate the error, their Butcher * arrays are as follows : *

                       *    0  |
                       *   c2  | a21
                       *   c3  | a31  a32
                       *   ... |        ...
                       *   cs  | as1  as2  ...  ass-1
                       *       |--------------------------
                       *       |  b1   b2  ...   bs-1  bs
                       *       |  b'1  b'2 ...   b's-1 b's
                       * 
                      *

                      * *

                      In fact, we rather use the array defined by ej = bj - b'j to * compute directly the error rather than computing two estimates and * then comparing them.

                      * *

                      Some methods are qualified as fsal (first same as last) * methods. This means the last evaluation of the derivatives in one * step is the same as the first in the next step. Then, this * evaluation can be reused from one step to the next one and the cost * of such a method is really s-1 evaluations despite the method still * has s stages. This behaviour is true only for successful steps, if * the step is rejected after the error estimation phase, no * evaluation is saved. For an fsal method, we have cs = 1 and * asi = bi for all i.

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public abstract class EmbeddedRungeKuttaIntegrator extends AdaptiveStepsizeIntegrator { /** Indicator for fsal methods. */ private final boolean fsal; /** Time steps from Butcher array (without the first zero). */ private final double[] c; /** Internal weights from Butcher array (without the first empty row). */ private final double[][] a; /** External weights for the high order method from Butcher array. */ private final double[] b; /** Prototype of the step interpolator. */ private final RungeKuttaStepInterpolator prototype; /** Stepsize control exponent. */ private final double exp; /** Safety factor for stepsize control. */ private double safety; /** Minimal reduction factor for stepsize control. */ private double minReduction; /** Maximal growth factor for stepsize control. */ private double maxGrowth; /** Build a Runge-Kutta integrator with the given Butcher array. * @param name name of the method * @param fsal indicate that the method is an fsal * @param c time steps from Butcher array (without the first zero) * @param a internal weights from Butcher array (without the first empty row) * @param b propagation weights for the high order method from Butcher array * @param prototype prototype of the step interpolator to use * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal, final double[] c, final double[][] a, final double[] b, final RungeKuttaStepInterpolator prototype, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); this.fsal = fsal; this.c = c; this.a = a; this.b = b; this.prototype = prototype; exp = -1.0 / getOrder(); // set the default values of the algorithm control parameters setSafety(0.9); setMinReduction(0.2); setMaxGrowth(10.0); } /** Build a Runge-Kutta integrator with the given Butcher array. * @param name name of the method * @param fsal indicate that the method is an fsal * @param c time steps from Butcher array (without the first zero) * @param a internal weights from Butcher array (without the first empty row) * @param b propagation weights for the high order method from Butcher array * @param prototype prototype of the step interpolator to use * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal, final double[] c, final double[][] a, final double[] b, final RungeKuttaStepInterpolator prototype, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); this.fsal = fsal; this.c = c; this.a = a; this.b = b; this.prototype = prototype; exp = -1.0 / getOrder(); // set the default values of the algorithm control parameters setSafety(0.9); setMinReduction(0.2); setMaxGrowth(10.0); } /** Get the order of the method. * @return order of the method */ public abstract int getOrder(); /** Get the safety factor for stepsize control. * @return safety factor */ public double getSafety() { return safety; } /** Set the safety factor for stepsize control. * @param safety safety factor */ public void setSafety(final double safety) { this.safety = safety; } /** {@inheritDoc} */ @Override public double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException { sanityChecks(equations, t0, y0, t, y); setEquations(equations); resetEvaluations(); final boolean forward = t > t0; // create some internal working arrays final int stages = c.length + 1; if (y != y0) { System.arraycopy(y0, 0, y, 0, y0.length); } final double[][] yDotK = new double[stages][y0.length]; final double[] yTmp = new double[y0.length]; final double[] yDotTmp = new double[y0.length]; // set up an interpolator sharing the integrator arrays AbstractStepInterpolator interpolator; if (requiresDenseOutput()) { final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy(); rki.reinitialize(this, yTmp, yDotK, forward); interpolator = rki; } else { interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward); } interpolator.storeTime(t0); // set up integration control objects stepStart = t0; double hNew = 0; boolean firstTime = true; for (StepHandler handler : stepHandlers) { handler.reset(); } setStateInitialized(false); // main integration loop isLastStep = false; do { interpolator.shift(); // iterate over step size, ensuring local normalized error is smaller than 1 double error = 10; while (error >= 1.0) { if (firstTime || !fsal) { // first stage computeDerivatives(stepStart, y, yDotK[0]); } if (firstTime) { final double[] scale = new double[mainSetDimension]; if (vecAbsoluteTolerance == null) { for (int i = 0; i < scale.length; ++i) { scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * FastMath.abs(y[i]); } } else { for (int i = 0; i < scale.length; ++i) { scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * FastMath.abs(y[i]); } } hNew = initializeStep(equations, forward, getOrder(), scale, stepStart, y, yDotK[0], yTmp, yDotK[1]); firstTime = false; } stepSize = hNew; // next stages for (int k = 1; k < stages; ++k) { for (int j = 0; j < y0.length; ++j) { double sum = a[k-1][0] * yDotK[0][j]; for (int l = 1; l < k; ++l) { sum += a[k-1][l] * yDotK[l][j]; } yTmp[j] = y[j] + stepSize * sum; } computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]); } // estimate the state at the end of the step for (int j = 0; j < y0.length; ++j) { double sum = b[0] * yDotK[0][j]; for (int l = 1; l < stages; ++l) { sum += b[l] * yDotK[l][j]; } yTmp[j] = y[j] + stepSize * sum; } // estimate the error at the end of the step error = estimateError(yDotK, y, yTmp, stepSize); if (error >= 1.0) { // reject the step and attempt to reduce error by stepsize control final double factor = FastMath.min(maxGrowth, FastMath.max(minReduction, safety * FastMath.pow(error, exp))); hNew = filterStep(stepSize * factor, forward, false); } } // local error is small enough: accept the step, trigger events and step handlers interpolator.storeTime(stepStart + stepSize); System.arraycopy(yTmp, 0, y, 0, y0.length); System.arraycopy(yDotK[stages - 1], 0, yDotTmp, 0, y0.length); stepStart = acceptStep(interpolator, y, yDotTmp, t); if (!isLastStep) { // prepare next step interpolator.storeTime(stepStart); if (fsal) { // save the last evaluation for the next step System.arraycopy(yDotTmp, 0, yDotK[0], 0, y0.length); } // stepsize control for next step final double factor = FastMath.min(maxGrowth, FastMath.max(minReduction, safety * FastMath.pow(error, exp))); final double scaledH = stepSize * factor; final double nextT = stepStart + scaledH; final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); hNew = filterStep(scaledH, forward, nextIsLast); final double filteredNextT = stepStart + hNew; final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t); if (filteredNextIsLast) { hNew = t - stepStart; } } } while (!isLastStep); final double stopTime = stepStart; resetInternalState(); return stopTime; } /** Get the minimal reduction factor for stepsize control. * @return minimal reduction factor */ public double getMinReduction() { return minReduction; } /** Set the minimal reduction factor for stepsize control. * @param minReduction minimal reduction factor */ public void setMinReduction(final double minReduction) { this.minReduction = minReduction; } /** Get the maximal growth factor for stepsize control. * @return maximal growth factor */ public double getMaxGrowth() { return maxGrowth; } /** Set the maximal growth factor for stepsize control. * @param maxGrowth maximal growth factor */ public void setMaxGrowth(final double maxGrowth) { this.maxGrowth = maxGrowth; } /** Compute the error ratio. * @param yDotK derivatives computed during the first stages * @param y0 estimate of the step at the start of the step * @param y1 estimate of the step at the end of the step * @param h current step * @return error ratio, greater than 1 if step should be rejected */ protected abstract double estimateError(double[][] yDotK, double[] y0, double[] y1, double h); } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/EulerIntegrator.java100644 1750 1750 4773 11532241246 30733 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; /** * This class implements a simple Euler integrator for Ordinary * Differential Equations. * *

                      The Euler algorithm is the simplest one that can be used to * integrate ordinary differential equations. It is a simple inversion * of the forward difference expression : * f'=(f(t+h)-f(t))/h which leads to * f(t+h)=f(t)+hf'. The interpolation scheme used for * dense output is the linear scheme already used for integration.

                      * *

                      This algorithm looks cheap because it needs only one function * evaluation per step. However, as it uses linear estimates, it needs * very small steps to achieve high accuracy, and small steps lead to * numerical errors and instabilities.

                      * *

                      This algorithm is almost never used and has been included in * this package only as a comparison reference for more useful * integrators.

                      * * @see MidpointIntegrator * @see ClassicalRungeKuttaIntegrator * @see GillIntegrator * @see ThreeEighthesIntegrator * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $ * @since 1.2 */ public class EulerIntegrator extends RungeKuttaIntegrator { /** Time steps Butcher array. */ private static final double[] STATIC_C = { }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 1.0 }; /** Simple constructor. * Build an Euler integrator with the given step. * @param step integration step */ public EulerIntegrator(final double step) { super("Euler", STATIC_C, STATIC_A, STATIC_B, new EulerStepInterpolator(), step); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GillIntegrator.java100644 1750 1750 4730 11532241246 30537 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.util.FastMath; /** * This class implements the Gill fourth order Runge-Kutta * integrator for Ordinary Differential Equations . *

                      This method is an explicit Runge-Kutta method, its Butcher-array * is the following one : *

                       *    0  |    0        0       0      0
                       *   1/2 |   1/2       0       0      0
                       *   1/2 | (q-1)/2  (2-q)/2    0      0
                       *    1  |    0       -q/2  (2+q)/2   0
                       *       |-------------------------------
                       *       |   1/6    (2-q)/6 (2+q)/6  1/6
                       * 
                      * where q = sqrt(2)

                      * * @see EulerIntegrator * @see ClassicalRungeKuttaIntegrator * @see MidpointIntegrator * @see ThreeEighthesIntegrator * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class GillIntegrator extends RungeKuttaIntegrator { /** Time steps Butcher array. */ private static final double[] STATIC_C = { 1.0 / 2.0, 1.0 / 2.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { { 1.0 / 2.0 }, { (FastMath.sqrt(2.0) - 1.0) / 2.0, (2.0 - FastMath.sqrt(2.0)) / 2.0 }, { 0.0, -FastMath.sqrt(2.0) / 2.0, (2.0 + FastMath.sqrt(2.0)) / 2.0 } }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 1.0 / 6.0, (2.0 - FastMath.sqrt(2.0)) / 6.0, (2.0 + FastMath.sqrt(2.0)) / 6.0, 1.0 / 6.0 }; /** Simple constructor. * Build a fourth-order Gill integrator with the given step. * @param step integration step */ public GillIntegrator(final double step) { super("Gill", STATIC_C, STATIC_A, STATIC_B, new GillStepInterpolator(), step); } } ././@LongLink100644 0 0 156 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpol100644 1750 1750 44557 11532241246 32262 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.commons.math.ode.AbstractIntegrator; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class represents an interpolator over the last step during an * ODE integration for the 8(5,3) Dormand-Prince integrator. * * @see DormandPrince853Integrator * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class DormandPrince853StepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = 7152276390558450974L; /** Propagation weights, element 1. */ private static final double B_01 = 104257.0 / 1920240.0; // elements 2 to 5 are zero, so they are neither stored nor used /** Propagation weights, element 6. */ private static final double B_06 = 3399327.0 / 763840.0; /** Propagation weights, element 7. */ private static final double B_07 = 66578432.0 / 35198415.0; /** Propagation weights, element 8. */ private static final double B_08 = -1674902723.0 / 288716400.0; /** Propagation weights, element 9. */ private static final double B_09 = 54980371265625.0 / 176692375811392.0; /** Propagation weights, element 10. */ private static final double B_10 = -734375.0 / 4826304.0; /** Propagation weights, element 11. */ private static final double B_11 = 171414593.0 / 851261400.0; /** Propagation weights, element 12. */ private static final double B_12 = 137909.0 / 3084480.0; /** Time step for stage 14 (interpolation only). */ private static final double C14 = 1.0 / 10.0; /** Internal weights for stage 14, element 1. */ private static final double K14_01 = 13481885573.0 / 240030000000.0 - B_01; // elements 2 to 5 are zero, so they are neither stored nor used /** Internal weights for stage 14, element 6. */ private static final double K14_06 = 0.0 - B_06; /** Internal weights for stage 14, element 7. */ private static final double K14_07 = 139418837528.0 / 549975234375.0 - B_07; /** Internal weights for stage 14, element 8. */ private static final double K14_08 = -11108320068443.0 / 45111937500000.0 - B_08; /** Internal weights for stage 14, element 9. */ private static final double K14_09 = -1769651421925959.0 / 14249385146080000.0 - B_09; /** Internal weights for stage 14, element 10. */ private static final double K14_10 = 57799439.0 / 377055000.0 - B_10; /** Internal weights for stage 14, element 11. */ private static final double K14_11 = 793322643029.0 / 96734250000000.0 - B_11; /** Internal weights for stage 14, element 12. */ private static final double K14_12 = 1458939311.0 / 192780000000.0 - B_12; /** Internal weights for stage 14, element 13. */ private static final double K14_13 = -4149.0 / 500000.0; /** Time step for stage 15 (interpolation only). */ private static final double C15 = 1.0 / 5.0; /** Internal weights for stage 15, element 1. */ private static final double K15_01 = 1595561272731.0 / 50120273500000.0 - B_01; // elements 2 to 5 are zero, so they are neither stored nor used /** Internal weights for stage 15, element 6. */ private static final double K15_06 = 975183916491.0 / 34457688031250.0 - B_06; /** Internal weights for stage 15, element 7. */ private static final double K15_07 = 38492013932672.0 / 718912673015625.0 - B_07; /** Internal weights for stage 15, element 8. */ private static final double K15_08 = -1114881286517557.0 / 20298710767500000.0 - B_08; /** Internal weights for stage 15, element 9. */ private static final double K15_09 = 0.0 - B_09; /** Internal weights for stage 15, element 10. */ private static final double K15_10 = 0.0 - B_10; /** Internal weights for stage 15, element 11. */ private static final double K15_11 = -2538710946863.0 / 23431227861250000.0 - B_11; /** Internal weights for stage 15, element 12. */ private static final double K15_12 = 8824659001.0 / 23066716781250.0 - B_12; /** Internal weights for stage 15, element 13. */ private static final double K15_13 = -11518334563.0 / 33831184612500.0; /** Internal weights for stage 15, element 14. */ private static final double K15_14 = 1912306948.0 / 13532473845.0; /** Time step for stage 16 (interpolation only). */ private static final double C16 = 7.0 / 9.0; /** Internal weights for stage 16, element 1. */ private static final double K16_01 = -13613986967.0 / 31741908048.0 - B_01; // elements 2 to 5 are zero, so they are neither stored nor used /** Internal weights for stage 16, element 6. */ private static final double K16_06 = -4755612631.0 / 1012344804.0 - B_06; /** Internal weights for stage 16, element 7. */ private static final double K16_07 = 42939257944576.0 / 5588559685701.0 - B_07; /** Internal weights for stage 16, element 8. */ private static final double K16_08 = 77881972900277.0 / 19140370552944.0 - B_08; /** Internal weights for stage 16, element 9. */ private static final double K16_09 = 22719829234375.0 / 63689648654052.0 - B_09; /** Internal weights for stage 16, element 10. */ private static final double K16_10 = 0.0 - B_10; /** Internal weights for stage 16, element 11. */ private static final double K16_11 = 0.0 - B_11; /** Internal weights for stage 16, element 12. */ private static final double K16_12 = 0.0 - B_12; /** Internal weights for stage 16, element 13. */ private static final double K16_13 = -1199007803.0 / 857031517296.0; /** Internal weights for stage 16, element 14. */ private static final double K16_14 = 157882067000.0 / 53564469831.0; /** Internal weights for stage 16, element 15. */ private static final double K16_15 = -290468882375.0 / 31741908048.0; /** Interpolation weights. * (beware that only the non-null values are in the table) */ private static final double[][] D = { { -17751989329.0 / 2106076560.0, 4272954039.0 / 7539864640.0, -118476319744.0 / 38604839385.0, 755123450731.0 / 316657731600.0, 3692384461234828125.0 / 1744130441634250432.0, -4612609375.0 / 5293382976.0, 2091772278379.0 / 933644586600.0, 2136624137.0 / 3382989120.0, -126493.0 / 1421424.0, 98350000.0 / 5419179.0, -18878125.0 / 2053168.0, -1944542619.0 / 438351368.0}, { 32941697297.0 / 3159114840.0, 456696183123.0 / 1884966160.0, 19132610714624.0 / 115814518155.0, -177904688592943.0 / 474986597400.0, -4821139941836765625.0 / 218016305204281304.0, 30702015625.0 / 3970037232.0, -85916079474274.0 / 2800933759800.0, -5919468007.0 / 634310460.0, 2479159.0 / 157936.0, -18750000.0 / 602131.0, -19203125.0 / 2053168.0, 15700361463.0 / 438351368.0}, { 12627015655.0 / 631822968.0, -72955222965.0 / 188496616.0, -13145744952320.0 / 69488710893.0, 30084216194513.0 / 56998391688.0, -296858761006640625.0 / 25648977082856624.0, 569140625.0 / 82709109.0, -18684190637.0 / 18672891732.0, 69644045.0 / 89549712.0, -11847025.0 / 4264272.0, -978650000.0 / 16257537.0, 519371875.0 / 6159504.0, 5256837225.0 / 438351368.0}, { -450944925.0 / 17550638.0, -14532122925.0 / 94248308.0, -595876966400.0 / 2573655959.0, 188748653015.0 / 527762886.0, 2545485458115234375.0 / 27252038150535163.0, -1376953125.0 / 36759604.0, 53995596795.0 / 518691437.0, 210311225.0 / 7047894.0, -1718875.0 / 39484.0, 58000000.0 / 602131.0, -1546875.0 / 39484.0, -1262172375.0 / 8429834.0} }; /** Last evaluations. */ private double[][] yDotKLast; /** Vectors for interpolation. */ private double[][] v; /** Initialization indicator for the interpolation vectors. */ private boolean vectorsInitialized; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link #reinitialize} method should be called before using the * instance in order to initialize the internal arrays. This * constructor is used only in order to delay the initialization in * some cases. The {@link EmbeddedRungeKuttaIntegrator} uses the * prototyping design pattern to create the step interpolators by * cloning an uninitialized model and latter initializing the copy. */ public DormandPrince853StepInterpolator() { super(); yDotKLast = null; v = null; vectorsInitialized = false; } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public DormandPrince853StepInterpolator(final DormandPrince853StepInterpolator interpolator) { super(interpolator); if (interpolator.currentState == null) { yDotKLast = null; v = null; vectorsInitialized = false; } else { final int dimension = interpolator.currentState.length; yDotKLast = new double[3][]; for (int k = 0; k < yDotKLast.length; ++k) { yDotKLast[k] = new double[dimension]; System.arraycopy(interpolator.yDotKLast[k], 0, yDotKLast[k], 0, dimension); } v = new double[7][]; for (int k = 0; k < v.length; ++k) { v[k] = new double[dimension]; System.arraycopy(interpolator.v[k], 0, v[k], 0, dimension); } vectorsInitialized = interpolator.vectorsInitialized; } } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new DormandPrince853StepInterpolator(this); } /** {@inheritDoc} */ @Override public void reinitialize(final AbstractIntegrator integrator, final double[] y, final double[][] yDotK, final boolean forward) { super.reinitialize(integrator, y, yDotK, forward); final int dimension = currentState.length; yDotKLast = new double[3][]; for (int k = 0; k < yDotKLast.length; ++k) { yDotKLast[k] = new double[dimension]; } v = new double[7][]; for (int k = 0; k < v.length; ++k) { v[k] = new double[dimension]; } vectorsInitialized = false; } /** {@inheritDoc} */ @Override public void storeTime(final double t) { super.storeTime(t); vectorsInitialized = false; } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { if (! vectorsInitialized) { if (v == null) { v = new double[7][]; for (int k = 0; k < 7; ++k) { v[k] = new double[interpolatedState.length]; } } // perform the last evaluations if they have not been done yet finalizeStep(); // compute the interpolation vectors for this time step for (int i = 0; i < interpolatedState.length; ++i) { final double yDot1 = yDotK[0][i]; final double yDot6 = yDotK[5][i]; final double yDot7 = yDotK[6][i]; final double yDot8 = yDotK[7][i]; final double yDot9 = yDotK[8][i]; final double yDot10 = yDotK[9][i]; final double yDot11 = yDotK[10][i]; final double yDot12 = yDotK[11][i]; final double yDot13 = yDotK[12][i]; final double yDot14 = yDotKLast[0][i]; final double yDot15 = yDotKLast[1][i]; final double yDot16 = yDotKLast[2][i]; v[0][i] = B_01 * yDot1 + B_06 * yDot6 + B_07 * yDot7 + B_08 * yDot8 + B_09 * yDot9 + B_10 * yDot10 + B_11 * yDot11 + B_12 * yDot12; v[1][i] = yDot1 - v[0][i]; v[2][i] = v[0][i] - v[1][i] - yDotK[12][i]; for (int k = 0; k < D.length; ++k) { v[k+3][i] = D[k][0] * yDot1 + D[k][1] * yDot6 + D[k][2] * yDot7 + D[k][3] * yDot8 + D[k][4] * yDot9 + D[k][5] * yDot10 + D[k][6] * yDot11 + D[k][7] * yDot12 + D[k][8] * yDot13 + D[k][9] * yDot14 + D[k][10] * yDot15 + D[k][11] * yDot16; } } vectorsInitialized = true; } final double eta = 1 - theta; final double twoTheta = 2 * theta; final double theta2 = theta * theta; final double dot1 = 1 - twoTheta; final double dot2 = theta * (2 - 3 * theta); final double dot3 = twoTheta * (1 + theta * (twoTheta -3)); final double dot4 = theta2 * (3 + theta * (5 * theta - 8)); final double dot5 = theta2 * (3 + theta * (-12 + theta * (15 - 6 * theta))); final double dot6 = theta2 * theta * (4 + theta * (-15 + theta * (18 - 7 * theta))); for (int i = 0; i < interpolatedState.length; ++i) { interpolatedState[i] = currentState[i] - oneMinusThetaH * (v[0][i] - theta * (v[1][i] + theta * (v[2][i] + eta * (v[3][i] + theta * (v[4][i] + eta * (v[5][i] + theta * (v[6][i]))))))); interpolatedDerivatives[i] = v[0][i] + dot1 * v[1][i] + dot2 * v[2][i] + dot3 * v[3][i] + dot4 * v[4][i] + dot5 * v[5][i] + dot6 * v[6][i]; } } /** {@inheritDoc} */ @Override protected void doFinalize() throws DerivativeException { if (currentState == null) { // we are finalizing an uninitialized instance return; } double s; final double[] yTmp = new double[currentState.length]; final double pT = getGlobalPreviousTime(); // k14 for (int j = 0; j < currentState.length; ++j) { s = K14_01 * yDotK[0][j] + K14_06 * yDotK[5][j] + K14_07 * yDotK[6][j] + K14_08 * yDotK[7][j] + K14_09 * yDotK[8][j] + K14_10 * yDotK[9][j] + K14_11 * yDotK[10][j] + K14_12 * yDotK[11][j] + K14_13 * yDotK[12][j]; yTmp[j] = currentState[j] + h * s; } integrator.computeDerivatives(pT + C14 * h, yTmp, yDotKLast[0]); // k15 for (int j = 0; j < currentState.length; ++j) { s = K15_01 * yDotK[0][j] + K15_06 * yDotK[5][j] + K15_07 * yDotK[6][j] + K15_08 * yDotK[7][j] + K15_09 * yDotK[8][j] + K15_10 * yDotK[9][j] + K15_11 * yDotK[10][j] + K15_12 * yDotK[11][j] + K15_13 * yDotK[12][j] + K15_14 * yDotKLast[0][j]; yTmp[j] = currentState[j] + h * s; } integrator.computeDerivatives(pT + C15 * h, yTmp, yDotKLast[1]); // k16 for (int j = 0; j < currentState.length; ++j) { s = K16_01 * yDotK[0][j] + K16_06 * yDotK[5][j] + K16_07 * yDotK[6][j] + K16_08 * yDotK[7][j] + K16_09 * yDotK[8][j] + K16_10 * yDotK[9][j] + K16_11 * yDotK[10][j] + K16_12 * yDotK[11][j] + K16_13 * yDotK[12][j] + K16_14 * yDotKLast[0][j] + K16_15 * yDotKLast[1][j]; yTmp[j] = currentState[j] + h * s; } integrator.computeDerivatives(pT + C16 * h, yTmp, yDotKLast[2]); } /** {@inheritDoc} */ @Override public void writeExternal(final ObjectOutput out) throws IOException { try { // save the local attributes finalizeStep(); } catch (DerivativeException e) { IOException ioe = new IOException(e.getLocalizedMessage()); ioe.initCause(e); throw ioe; } final int dimension = (currentState == null) ? -1 : currentState.length; out.writeInt(dimension); for (int i = 0; i < dimension; ++i) { out.writeDouble(yDotKLast[0][i]); out.writeDouble(yDotKLast[1][i]); out.writeDouble(yDotKLast[2][i]); } // save the state of the base class super.writeExternal(out); } /** {@inheritDoc} */ @Override public void readExternal(final ObjectInput in) throws IOException { // read the local attributes yDotKLast = new double[3][]; final int dimension = in.readInt(); yDotKLast[0] = (dimension < 0) ? null : new double[dimension]; yDotKLast[1] = (dimension < 0) ? null : new double[dimension]; yDotKLast[2] = (dimension < 0) ? null : new double[dimension]; for (int i = 0; i < dimension; ++i) { yDotKLast[0][i] = in.readDouble(); yDotKLast[1][i] = in.readDouble(); yDotKLast[2][i] = in.readDouble(); } // read the base state super.readExternal(in); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.j100644 1750 1750 26771 11532241246 32176 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.util.FastMath; /** * This class implements the 8(5,3) Dormand-Prince integrator for Ordinary * Differential Equations. * *

                      This integrator is an embedded Runge-Kutta integrator * of order 8(5,3) used in local extrapolation mode (i.e. the solution * is computed using the high order formula) with stepsize control * (and automatic step initialization) and continuous output. This * method uses 12 functions evaluations per step for integration and 4 * evaluations for interpolation. However, since the first * interpolation evaluation is the same as the first integration * evaluation of the next step, we have included it in the integrator * rather than in the interpolator and specified the method was an * fsal. Hence, despite we have 13 stages here, the cost is * really 12 evaluations per step even if no interpolation is done, * and the overcost of interpolation is only 3 evaluations.

                      * *

                      This method is based on an 8(6) method by Dormand and Prince * (i.e. order 8 for the integration and order 6 for error estimation) * modified by Hairer and Wanner to use a 5th order error estimator * with 3rd order correction. This modification was introduced because * the original method failed in some cases (wrong steps can be * accepted when step size is too large, for example in the * Brusselator problem) and also had severe difficulties when * applied to problems with discontinuities. This modification is * explained in the second edition of the first volume (Nonstiff * Problems) of the reference book by Hairer, Norsett and Wanner: * Solving Ordinary Differential Equations (Springer-Verlag, * ISBN 3-540-56670-8).

                      * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class DormandPrince853Integrator extends EmbeddedRungeKuttaIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Dormand-Prince 8 (5, 3)"; /** Time steps Butcher array. */ private static final double[] STATIC_C = { (12.0 - 2.0 * FastMath.sqrt(6.0)) / 135.0, (6.0 - FastMath.sqrt(6.0)) / 45.0, (6.0 - FastMath.sqrt(6.0)) / 30.0, (6.0 + FastMath.sqrt(6.0)) / 30.0, 1.0/3.0, 1.0/4.0, 4.0/13.0, 127.0/195.0, 3.0/5.0, 6.0/7.0, 1.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { // k2 {(12.0 - 2.0 * FastMath.sqrt(6.0)) / 135.0}, // k3 {(6.0 - FastMath.sqrt(6.0)) / 180.0, (6.0 - FastMath.sqrt(6.0)) / 60.0}, // k4 {(6.0 - FastMath.sqrt(6.0)) / 120.0, 0.0, (6.0 - FastMath.sqrt(6.0)) / 40.0}, // k5 {(462.0 + 107.0 * FastMath.sqrt(6.0)) / 3000.0, 0.0, (-402.0 - 197.0 * FastMath.sqrt(6.0)) / 1000.0, (168.0 + 73.0 * FastMath.sqrt(6.0)) / 375.0}, // k6 {1.0 / 27.0, 0.0, 0.0, (16.0 + FastMath.sqrt(6.0)) / 108.0, (16.0 - FastMath.sqrt(6.0)) / 108.0}, // k7 {19.0 / 512.0, 0.0, 0.0, (118.0 + 23.0 * FastMath.sqrt(6.0)) / 1024.0, (118.0 - 23.0 * FastMath.sqrt(6.0)) / 1024.0, -9.0 / 512.0}, // k8 {13772.0 / 371293.0, 0.0, 0.0, (51544.0 + 4784.0 * FastMath.sqrt(6.0)) / 371293.0, (51544.0 - 4784.0 * FastMath.sqrt(6.0)) / 371293.0, -5688.0 / 371293.0, 3072.0 / 371293.0}, // k9 {58656157643.0 / 93983540625.0, 0.0, 0.0, (-1324889724104.0 - 318801444819.0 * FastMath.sqrt(6.0)) / 626556937500.0, (-1324889724104.0 + 318801444819.0 * FastMath.sqrt(6.0)) / 626556937500.0, 96044563816.0 / 3480871875.0, 5682451879168.0 / 281950621875.0, -165125654.0 / 3796875.0}, // k10 {8909899.0 / 18653125.0, 0.0, 0.0, (-4521408.0 - 1137963.0 * FastMath.sqrt(6.0)) / 2937500.0, (-4521408.0 + 1137963.0 * FastMath.sqrt(6.0)) / 2937500.0, 96663078.0 / 4553125.0, 2107245056.0 / 137915625.0, -4913652016.0 / 147609375.0, -78894270.0 / 3880452869.0}, // k11 {-20401265806.0 / 21769653311.0, 0.0, 0.0, (354216.0 + 94326.0 * FastMath.sqrt(6.0)) / 112847.0, (354216.0 - 94326.0 * FastMath.sqrt(6.0)) / 112847.0, -43306765128.0 / 5313852383.0, -20866708358144.0 / 1126708119789.0, 14886003438020.0 / 654632330667.0, 35290686222309375.0 / 14152473387134411.0, -1477884375.0 / 485066827.0}, // k12 {39815761.0 / 17514443.0, 0.0, 0.0, (-3457480.0 - 960905.0 * FastMath.sqrt(6.0)) / 551636.0, (-3457480.0 + 960905.0 * FastMath.sqrt(6.0)) / 551636.0, -844554132.0 / 47026969.0, 8444996352.0 / 302158619.0, -2509602342.0 / 877790785.0, -28388795297996250.0 / 3199510091356783.0, 226716250.0 / 18341897.0, 1371316744.0 / 2131383595.0}, // k13 should be for interpolation only, but since it is the same // stage as the first evaluation of the next step, we perform it // here at no cost by specifying this is an fsal method {104257.0/1920240.0, 0.0, 0.0, 0.0, 0.0, 3399327.0/763840.0, 66578432.0/35198415.0, -1674902723.0/288716400.0, 54980371265625.0/176692375811392.0, -734375.0/4826304.0, 171414593.0/851261400.0, 137909.0/3084480.0} }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 104257.0/1920240.0, 0.0, 0.0, 0.0, 0.0, 3399327.0/763840.0, 66578432.0/35198415.0, -1674902723.0/288716400.0, 54980371265625.0/176692375811392.0, -734375.0/4826304.0, 171414593.0/851261400.0, 137909.0/3084480.0, 0.0 }; /** First error weights array, element 1. */ private static final double E1_01 = 116092271.0 / 8848465920.0; // elements 2 to 5 are zero, so they are neither stored nor used /** First error weights array, element 6. */ private static final double E1_06 = -1871647.0 / 1527680.0; /** First error weights array, element 7. */ private static final double E1_07 = -69799717.0 / 140793660.0; /** First error weights array, element 8. */ private static final double E1_08 = 1230164450203.0 / 739113984000.0; /** First error weights array, element 9. */ private static final double E1_09 = -1980813971228885.0 / 5654156025964544.0; /** First error weights array, element 10. */ private static final double E1_10 = 464500805.0 / 1389975552.0; /** First error weights array, element 11. */ private static final double E1_11 = 1606764981773.0 / 19613062656000.0; /** First error weights array, element 12. */ private static final double E1_12 = -137909.0 / 6168960.0; /** Second error weights array, element 1. */ private static final double E2_01 = -364463.0 / 1920240.0; // elements 2 to 5 are zero, so they are neither stored nor used /** Second error weights array, element 6. */ private static final double E2_06 = 3399327.0 / 763840.0; /** Second error weights array, element 7. */ private static final double E2_07 = 66578432.0 / 35198415.0; /** Second error weights array, element 8. */ private static final double E2_08 = -1674902723.0 / 288716400.0; /** Second error weights array, element 9. */ private static final double E2_09 = -74684743568175.0 / 176692375811392.0; /** Second error weights array, element 10. */ private static final double E2_10 = -734375.0 / 4826304.0; /** Second error weights array, element 11. */ private static final double E2_11 = 171414593.0 / 851261400.0; /** Second error weights array, element 12. */ private static final double E2_12 = 69869.0 / 3084480.0; /** Simple constructor. * Build an eighth order Dormand-Prince integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ public DormandPrince853Integrator(final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince853StepInterpolator(), minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); } /** Simple constructor. * Build an eighth order Dormand-Prince integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ public DormandPrince853Integrator(final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince853StepInterpolator(), minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); } /** {@inheritDoc} */ @Override public int getOrder() { return 8; } /** {@inheritDoc} */ @Override protected double estimateError(final double[][] yDotK, final double[] y0, final double[] y1, final double h) { double error1 = 0; double error2 = 0; for (int j = 0; j < mainSetDimension; ++j) { final double errSum1 = E1_01 * yDotK[0][j] + E1_06 * yDotK[5][j] + E1_07 * yDotK[6][j] + E1_08 * yDotK[7][j] + E1_09 * yDotK[8][j] + E1_10 * yDotK[9][j] + E1_11 * yDotK[10][j] + E1_12 * yDotK[11][j]; final double errSum2 = E2_01 * yDotK[0][j] + E2_06 * yDotK[5][j] + E2_07 * yDotK[6][j] + E2_08 * yDotK[7][j] + E2_09 * yDotK[8][j] + E2_10 * yDotK[9][j] + E2_11 * yDotK[10][j] + E2_12 * yDotK[11][j]; final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j])); final double tol = (vecAbsoluteTolerance == null) ? (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); final double ratio1 = errSum1 / tol; error1 += ratio1 * ratio1; final double ratio2 = errSum2 / tol; error2 += ratio2 * ratio2; } double den = error1 + 0.01 * error2; if (den <= 0.0) { den = 1.0; } return FastMath.abs(h) * error1 / FastMath.sqrt(mainSetDimension * den); } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator100644 1750 1750 10160 11532241246 32311 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class represents an interpolator over the last step during an * ODE integration for the 5(4) Higham and Hall integrator. * * @see HighamHall54Integrator * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class HighamHall54StepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -3583240427587318654L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize} * method should be called before using the instance in order to * initialize the internal arrays. This constructor is used only * in order to delay the initialization in some cases. The {@link * EmbeddedRungeKuttaIntegrator} uses the prototyping design pattern * to create the step interpolators by cloning an uninitialized model * and later initializing the copy. */ public HighamHall54StepInterpolator() { super(); } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public HighamHall54StepInterpolator(final HighamHall54StepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new HighamHall54StepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { final double theta2 = theta * theta; final double b0 = h * (-1.0/12.0 + theta * (1.0 + theta * (-15.0/4.0 + theta * (16.0/3.0 + theta * -5.0/2.0)))); final double b2 = h * (-27.0/32.0 + theta2 * (459.0/32.0 + theta * (-243.0/8.0 + theta * 135.0/8.0))); final double b3 = h * (4.0/3.0 + theta2 * (-22.0 + theta * (152.0/3.0 + theta * -30.0))); final double b4 = h * (-125.0/96.0 + theta2 * (375.0/32.0 + theta * (-625.0/24.0 + theta * 125.0/8.0))); final double b5 = h * (-5.0/48.0 + theta2 * (-5.0/16.0 + theta * 5.0/12.0)); final double bDot0 = 1 + theta * (-15.0/2.0 + theta * (16.0 - 10.0 * theta)); final double bDot2 = theta * (459.0/16.0 + theta * (-729.0/8.0 + 135.0/2.0 * theta)); final double bDot3 = theta * (-44.0 + theta * (152.0 - 120.0 * theta)); final double bDot4 = theta * (375.0/16.0 + theta * (-625.0/8.0 + 125.0/2.0 * theta)); final double bDot5 = theta * 5.0/8.0 * (2 * theta - 1); for (int i = 0; i < interpolatedState.length; ++i) { final double yDot0 = yDotK[0][i]; final double yDot2 = yDotK[2][i]; final double yDot3 = yDotK[3][i]; final double yDot4 = yDotK[4][i]; final double yDot5 = yDotK[5][i]; interpolatedState[i] = currentState[i] + b0 * yDot0 + b2 * yDot2 + b3 * yDot3 + b4 * yDot4 + b5 * yDot5; interpolatedDerivatives[i] = bDot0 * yDot0 + bDot2 * yDot2 + bDot3 * yDot3 + bDot4 * yDot4 + bDot5 * yDot5; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.java100644 1750 1750 11651 11532241246 32037 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.util.FastMath; /** * This class implements the 5(4) Higham and Hall integrator for * Ordinary Differential Equations. * *

                      This integrator is an embedded Runge-Kutta integrator * of order 5(4) used in local extrapolation mode (i.e. the solution * is computed using the high order formula) with stepsize control * (and automatic step initialization) and continuous output. This * method uses 7 functions evaluations per step.

                      * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class HighamHall54Integrator extends EmbeddedRungeKuttaIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Higham-Hall 5(4)"; /** Time steps Butcher array. */ private static final double[] STATIC_C = { 2.0/9.0, 1.0/3.0, 1.0/2.0, 3.0/5.0, 1.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { {2.0/9.0}, {1.0/12.0, 1.0/4.0}, {1.0/8.0, 0.0, 3.0/8.0}, {91.0/500.0, -27.0/100.0, 78.0/125.0, 8.0/125.0}, {-11.0/20.0, 27.0/20.0, 12.0/5.0, -36.0/5.0, 5.0}, {1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0} }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0, 0.0 }; /** Error weights Butcher array. */ private static final double[] STATIC_E = { -1.0/20.0, 0.0, 81.0/160.0, -6.0/5.0, 25.0/32.0, 1.0/16.0, -1.0/10.0 }; /** Simple constructor. * Build a fifth order Higham and Hall integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ public HighamHall54Integrator(final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(), minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); } /** Simple constructor. * Build a fifth order Higham and Hall integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ public HighamHall54Integrator(final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(), minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); } /** {@inheritDoc} */ @Override public int getOrder() { return 5; } /** {@inheritDoc} */ @Override protected double estimateError(final double[][] yDotK, final double[] y0, final double[] y1, final double h) { double error = 0; for (int j = 0; j < mainSetDimension; ++j) { double errSum = STATIC_E[0] * yDotK[0][j]; for (int l = 1; l < STATIC_E.length; ++l) { errSum += STATIC_E[l] * yDotK[l][j]; } final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j])); final double tol = (vecAbsoluteTolerance == null) ? (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); final double ratio = h * errSum / tol; error += ratio * ratio; } return FastMath.sqrt(error / mainSetDimension); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolator.java100644 1750 1750 6172 11532241246 32126 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class implements a linear interpolator for step. * *

                      This interpolator computes dense output inside the last * step computed. The interpolation equation is consistent with the * integration scheme : * *

                       *   y(t_n + theta h) = y (t_n + h) - (1-theta) h y'
                       * 
                      * * where theta belongs to [0 ; 1] and where y' is the evaluation of * the derivatives already computed during the step.

                      * * @see EulerIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class EulerStepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -7179861704951334960L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize} * method should be called before using the instance in order to * initialize the internal arrays. This constructor is used only * in order to delay the initialization in some cases. The {@link * RungeKuttaIntegrator} class uses the prototyping design pattern * to create the step interpolators by cloning an uninitialized model * and later initializing the copy. */ public EulerStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public EulerStepInterpolator(final EulerStepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new EulerStepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { for (int i = 0; i < interpolatedState.length; ++i) { interpolatedState[i] = currentState[i] - oneMinusThetaH * yDotK[0][i]; } System.arraycopy(yDotK[0], 0, interpolatedDerivatives, 0, interpolatedDerivatives.length); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java100644 1750 1750 14674 11532241246 31771 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.AbstractIntegrator; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; /** * This class implements the common part of all fixed step Runge-Kutta * integrators for Ordinary Differential Equations. * *

                      These methods are explicit Runge-Kutta methods, their Butcher * arrays are as follows : *

                       *    0  |
                       *   c2  | a21
                       *   c3  | a31  a32
                       *   ... |        ...
                       *   cs  | as1  as2  ...  ass-1
                       *       |--------------------------
                       *       |  b1   b2  ...   bs-1  bs
                       * 
                      *

                      * * @see EulerIntegrator * @see ClassicalRungeKuttaIntegrator * @see GillIntegrator * @see MidpointIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public abstract class RungeKuttaIntegrator extends AbstractIntegrator { /** Time steps from Butcher array (without the first zero). */ private final double[] c; /** Internal weights from Butcher array (without the first empty row). */ private final double[][] a; /** External weights for the high order method from Butcher array. */ private final double[] b; /** Prototype of the step interpolator. */ private final RungeKuttaStepInterpolator prototype; /** Integration step. */ private final double step; /** Simple constructor. * Build a Runge-Kutta integrator with the given * step. The default step handler does nothing. * @param name name of the method * @param c time steps from Butcher array (without the first zero) * @param a internal weights from Butcher array (without the first empty row) * @param b propagation weights for the high order method from Butcher array * @param prototype prototype of the step interpolator to use * @param step integration step */ protected RungeKuttaIntegrator(final String name, final double[] c, final double[][] a, final double[] b, final RungeKuttaStepInterpolator prototype, final double step) { super(name); this.c = c; this.a = a; this.b = b; this.prototype = prototype; this.step = FastMath.abs(step); } /** {@inheritDoc} */ public double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException { sanityChecks(equations, t0, y0, t, y); setEquations(equations); resetEvaluations(); final boolean forward = t > t0; // create some internal working arrays final int stages = c.length + 1; if (y != y0) { System.arraycopy(y0, 0, y, 0, y0.length); } final double[][] yDotK = new double[stages][]; for (int i = 0; i < stages; ++i) { yDotK [i] = new double[y0.length]; } final double[] yTmp = new double[y0.length]; final double[] yDotTmp = new double[y0.length]; // set up an interpolator sharing the integrator arrays AbstractStepInterpolator interpolator; if (requiresDenseOutput()) { final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy(); rki.reinitialize(this, yTmp, yDotK, forward); interpolator = rki; } else { interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward); } interpolator.storeTime(t0); // set up integration control objects stepStart = t0; stepSize = forward ? step : -step; for (StepHandler handler : stepHandlers) { handler.reset(); } setStateInitialized(false); // main integration loop isLastStep = false; do { interpolator.shift(); // first stage computeDerivatives(stepStart, y, yDotK[0]); // next stages for (int k = 1; k < stages; ++k) { for (int j = 0; j < y0.length; ++j) { double sum = a[k-1][0] * yDotK[0][j]; for (int l = 1; l < k; ++l) { sum += a[k-1][l] * yDotK[l][j]; } yTmp[j] = y[j] + stepSize * sum; } computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]); } // estimate the state at the end of the step for (int j = 0; j < y0.length; ++j) { double sum = b[0] * yDotK[0][j]; for (int l = 1; l < stages; ++l) { sum += b[l] * yDotK[l][j]; } yTmp[j] = y[j] + stepSize * sum; } // discrete events handling interpolator.storeTime(stepStart + stepSize); System.arraycopy(yTmp, 0, y, 0, y0.length); System.arraycopy(yDotK[stages - 1], 0, yDotTmp, 0, y0.length); stepStart = acceptStep(interpolator, y, yDotTmp, t); if (!isLastStep) { // prepare next step interpolator.storeTime(stepStart); // stepsize control for next step final double nextT = stepStart + stepSize; final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); if (nextIsLast) { stepSize = t - stepStart; } } } while (!isLastStep); final double stopTime = stepStart; stepStart = Double.NaN; stepSize = Double.NaN; return stopTime; } } ././@LongLink100644 0 0 155 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpola100644 1750 1750 15726 11532241246 32330 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.AbstractIntegrator; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class represents an interpolator over the last step during an * ODE integration for the 5(4) Dormand-Prince integrator. * * @see DormandPrince54Integrator * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class DormandPrince54StepInterpolator extends RungeKuttaStepInterpolator { /** Last row of the Butcher-array internal weights, element 0. */ private static final double A70 = 35.0 / 384.0; // element 1 is zero, so it is neither stored nor used /** Last row of the Butcher-array internal weights, element 2. */ private static final double A72 = 500.0 / 1113.0; /** Last row of the Butcher-array internal weights, element 3. */ private static final double A73 = 125.0 / 192.0; /** Last row of the Butcher-array internal weights, element 4. */ private static final double A74 = -2187.0 / 6784.0; /** Last row of the Butcher-array internal weights, element 5. */ private static final double A75 = 11.0 / 84.0; /** Shampine (1986) Dense output, element 0. */ private static final double D0 = -12715105075.0 / 11282082432.0; // element 1 is zero, so it is neither stored nor used /** Shampine (1986) Dense output, element 2. */ private static final double D2 = 87487479700.0 / 32700410799.0; /** Shampine (1986) Dense output, element 3. */ private static final double D3 = -10690763975.0 / 1880347072.0; /** Shampine (1986) Dense output, element 4. */ private static final double D4 = 701980252875.0 / 199316789632.0; /** Shampine (1986) Dense output, element 5. */ private static final double D5 = -1453857185.0 / 822651844.0; /** Shampine (1986) Dense output, element 6. */ private static final double D6 = 69997945.0 / 29380423.0; /** Serializable version identifier */ private static final long serialVersionUID = 4104157279605906956L; /** First vector for interpolation. */ private double[] v1; /** Second vector for interpolation. */ private double[] v2; /** Third vector for interpolation. */ private double[] v3; /** Fourth vector for interpolation. */ private double[] v4; /** Initialization indicator for the interpolation vectors. */ private boolean vectorsInitialized; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link #reinitialize} method should be called before using the * instance in order to initialize the internal arrays. This * constructor is used only in order to delay the initialization in * some cases. The {@link EmbeddedRungeKuttaIntegrator} uses the * prototyping design pattern to create the step interpolators by * cloning an uninitialized model and latter initializing the copy. */ public DormandPrince54StepInterpolator() { super(); v1 = null; v2 = null; v3 = null; v4 = null; vectorsInitialized = false; } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public DormandPrince54StepInterpolator(final DormandPrince54StepInterpolator interpolator) { super(interpolator); if (interpolator.v1 == null) { v1 = null; v2 = null; v3 = null; v4 = null; vectorsInitialized = false; } else { v1 = interpolator.v1.clone(); v2 = interpolator.v2.clone(); v3 = interpolator.v3.clone(); v4 = interpolator.v4.clone(); vectorsInitialized = interpolator.vectorsInitialized; } } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new DormandPrince54StepInterpolator(this); } /** {@inheritDoc} */ @Override public void reinitialize(final AbstractIntegrator integrator, final double[] y, final double[][] yDotK, final boolean forward) { super.reinitialize(integrator, y, yDotK, forward); v1 = null; v2 = null; v3 = null; v4 = null; vectorsInitialized = false; } /** {@inheritDoc} */ @Override public void storeTime(final double t) { super.storeTime(t); vectorsInitialized = false; } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { if (! vectorsInitialized) { if (v1 == null) { v1 = new double[interpolatedState.length]; v2 = new double[interpolatedState.length]; v3 = new double[interpolatedState.length]; v4 = new double[interpolatedState.length]; } // no step finalization is needed for this interpolator // we need to compute the interpolation vectors for this time step for (int i = 0; i < interpolatedState.length; ++i) { final double yDot0 = yDotK[0][i]; final double yDot2 = yDotK[2][i]; final double yDot3 = yDotK[3][i]; final double yDot4 = yDotK[4][i]; final double yDot5 = yDotK[5][i]; final double yDot6 = yDotK[6][i]; v1[i] = A70 * yDot0 + A72 * yDot2 + A73 * yDot3 + A74 * yDot4 + A75 * yDot5; v2[i] = yDot0 - v1[i]; v3[i] = v1[i] - v2[i] - yDot6; v4[i] = D0 * yDot0 + D2 * yDot2 + D3 * yDot3 + D4 * yDot4 + D5 * yDot5 + D6 * yDot6; } vectorsInitialized = true; } // interpolate final double eta = 1 - theta; final double twoTheta = 2 * theta; final double dot2 = 1 - twoTheta; final double dot3 = theta * (2 - 3 * theta); final double dot4 = twoTheta * (1 + theta * (twoTheta - 3)); for (int i = 0; i < interpolatedState.length; ++i) { interpolatedState[i] = currentState[i] - oneMinusThetaH * (v1[i] - theta * (v2[i] + theta * (v3[i] + eta * v4[i]))); interpolatedDerivatives[i] = v1[i] + dot2 * v2[i] + dot3 * v3[i] + dot4 * v4[i]; } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.jav100644 1750 1750 33444 11532241246 32421 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; /** * This class implements explicit Adams-Bashforth integrators for Ordinary * Differential Equations. * *

                      Adams-Bashforth methods (in fact due to Adams alone) are explicit * multistep ODE solvers. This implementation is a variation of the classical * one: it uses adaptive stepsize to implement error control, whereas * classical implementations are fixed step size. The value of state vector * at step n+1 is a simple combination of the value at step n and of the * derivatives at steps n, n-1, n-2 ... Depending on the number k of previous * steps one wants to use for computing the next value, different formulas * are available:

                      *
                        *
                      • k = 1: yn+1 = yn + h y'n
                      • *
                      • k = 2: yn+1 = yn + h (3y'n-y'n-1)/2
                      • *
                      • k = 3: yn+1 = yn + h (23y'n-16y'n-1+5y'n-2)/12
                      • *
                      • k = 4: yn+1 = yn + h (55y'n-59y'n-1+37y'n-2-9y'n-3)/24
                      • *
                      • ...
                      • *
                      * *

                      A k-steps Adams-Bashforth method is of order k.

                      * *

                      Implementation details

                      * *

                      We define scaled derivatives si(n) at step n as: *

                       * s1(n) = h y'n for first derivative
                       * s2(n) = h2/2 y''n for second derivative
                       * s3(n) = h3/6 y'''n for third derivative
                       * ...
                       * sk(n) = hk/k! y(k)n for kth derivative
                       * 

                      * *

                      The definitions above use the classical representation with several previous first * derivatives. Lets define *

                       *   qn = [ s1(n-1) s1(n-2) ... s1(n-(k-1)) ]T
                       * 
                      * (we omit the k index in the notation for clarity). With these definitions, * Adams-Bashforth methods can be written: *
                        *
                      • k = 1: yn+1 = yn + s1(n)
                      • *
                      • k = 2: yn+1 = yn + 3/2 s1(n) + [ -1/2 ] qn
                      • *
                      • k = 3: yn+1 = yn + 23/12 s1(n) + [ -16/12 5/12 ] qn
                      • *
                      • k = 4: yn+1 = yn + 55/24 s1(n) + [ -59/24 37/24 -9/24 ] qn
                      • *
                      • ...
                      • *

                      * *

                      Instead of using the classical representation with first derivatives only (yn, * s1(n) and qn), our implementation uses the Nordsieck vector with * higher degrees scaled derivatives all taken at the same step (yn, s1(n) * and rn) where rn is defined as: *

                       * rn = [ s2(n), s3(n) ... sk(n) ]T
                       * 
                      * (here again we omit the k index in the notation for clarity) *

                      * *

                      Taylor series formulas show that for any index offset i, s1(n-i) can be * computed from s1(n), s2(n) ... sk(n), the formula being exact * for degree k polynomials. *

                       * s1(n-i) = s1(n) + ∑j j (-i)j-1 sj(n)
                       * 
                      * The previous formula can be used with several values for i to compute the transform between * classical representation and Nordsieck vector. The transform between rn * and qn resulting from the Taylor series formulas above is: *
                       * qn = s1(n) u + P rn
                       * 
                      * where u is the [ 1 1 ... 1 ]T vector and P is the (k-1)×(k-1) matrix built * with the j (-i)j-1 terms: *
                       *        [  -2   3   -4    5  ... ]
                       *        [  -4  12  -32   80  ... ]
                       *   P =  [  -6  27 -108  405  ... ]
                       *        [  -8  48 -256 1280  ... ]
                       *        [          ...           ]
                       * 

                      * *

                      Using the Nordsieck vector has several advantages: *

                        *
                      • it greatly simplifies step interpolation as the interpolator mainly applies * Taylor series formulas,
                      • *
                      • it simplifies step changes that occur when discrete events that truncate * the step are triggered,
                      • *
                      • it allows to extend the methods in order to support adaptive stepsize.
                      • *

                      * *

                      The Nordsieck vector at step n+1 is computed from the Nordsieck vector at step n as follows: *

                        *
                      • yn+1 = yn + s1(n) + uT rn
                      • *
                      • s1(n+1) = h f(tn+1, yn+1)
                      • *
                      • rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                      • *
                      * where A is a rows shifting matrix (the lower left part is an identity matrix): *
                       *        [ 0 0   ...  0 0 | 0 ]
                       *        [ ---------------+---]
                       *        [ 1 0   ...  0 0 | 0 ]
                       *    A = [ 0 1   ...  0 0 | 0 ]
                       *        [       ...      | 0 ]
                       *        [ 0 0   ...  1 0 | 0 ]
                       *        [ 0 0   ...  0 1 | 0 ]
                       * 

                      * *

                      The P-1u vector and the P-1 A P matrix do not depend on the state, * they only depend on k and therefore are precomputed once for all.

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class AdamsBashforthIntegrator extends AdamsIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Adams-Bashforth"; /** * Build an Adams-Bashforth integrator with the given order and step control parameters. * @param nSteps number of steps of the method excluding the one being computed * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsBashforthIntegrator(final int nSteps, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) throws IllegalArgumentException { super(METHOD_NAME, nSteps, nSteps, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); } /** * Build an Adams-Bashforth integrator with the given order and step control parameters. * @param nSteps number of steps of the method excluding the one being computed * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsBashforthIntegrator(final int nSteps, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) throws IllegalArgumentException { super(METHOD_NAME, nSteps, nSteps, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); } /** {@inheritDoc} */ @Override public double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException { final int n = y0.length; sanityChecks(equations, t0, y0, t, y); setEquations(equations); resetEvaluations(); final boolean forward = t > t0; // initialize working arrays if (y != y0) { System.arraycopy(y0, 0, y, 0, n); } final double[] yDot = new double[n]; // set up an interpolator sharing the integrator arrays final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator(); interpolator.reinitialize(y, forward); // set up integration control objects for (StepHandler handler : stepHandlers) { handler.reset(); } setStateInitialized(false); // compute the initial Nordsieck vector using the configured starter integrator start(t0, y, t); interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); interpolator.storeTime(stepStart); final int lastRow = nordsieck.getRowDimension() - 1; // reuse the step that was chosen by the starter integrator double hNew = stepSize; interpolator.rescale(hNew); // main integration loop isLastStep = false; do { double error = 10; while (error >= 1.0) { stepSize = hNew; // evaluate error using the last term of the Taylor expansion error = 0; for (int i = 0; i < mainSetDimension; ++i) { final double yScale = FastMath.abs(y[i]); final double tol = (vecAbsoluteTolerance == null) ? (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale); final double ratio = nordsieck.getEntry(lastRow, i) / tol; error += ratio * ratio; } error = FastMath.sqrt(error / mainSetDimension); if (error >= 1.0) { // reject the step and attempt to reduce error by stepsize control final double factor = computeStepGrowShrinkFactor(error); hNew = filterStep(stepSize * factor, forward, false); interpolator.rescale(hNew); } } // predict a first estimate of the state at step end final double stepEnd = stepStart + stepSize; interpolator.shift(); interpolator.setInterpolatedTime(stepEnd); System.arraycopy(interpolator.getInterpolatedState(), 0, y, 0, y0.length); // evaluate the derivative computeDerivatives(stepEnd, y, yDot); // update Nordsieck vector final double[] predictedScaled = new double[y0.length]; for (int j = 0; j < y0.length; ++j) { predictedScaled[j] = stepSize * yDot[j]; } final Array2DRowRealMatrix nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck); updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp); interpolator.reinitialize(stepEnd, stepSize, predictedScaled, nordsieckTmp); // discrete events handling interpolator.storeTime(stepEnd); stepStart = acceptStep(interpolator, y, yDot, t); scaled = predictedScaled; nordsieck = nordsieckTmp; interpolator.reinitialize(stepEnd, stepSize, scaled, nordsieck); if (!isLastStep) { // prepare next step interpolator.storeTime(stepStart); if (resetOccurred) { // some events handler has triggered changes that // invalidate the derivatives, we need to restart from scratch start(stepStart, y, t); interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); } // stepsize control for next step final double factor = computeStepGrowShrinkFactor(error); final double scaledH = stepSize * factor; final double nextT = stepStart + scaledH; final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); hNew = filterStep(scaledH, forward, nextIsLast); final double filteredNextT = stepStart + hNew; final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t); if (filteredNextIsLast) { hNew = t - stepStart; } interpolator.rescale(hNew); } } while (!isLastStep); final double stopTime = stepStart; resetInternalState(); return stopTime; } } ././@LongLink100644 0 0 160 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterp100644 1750 1750 31637 11532241246 32475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** * This class implements an interpolator for the Gragg-Bulirsch-Stoer * integrator. * *

                      This interpolator compute dense output inside the last step * produced by a Gragg-Bulirsch-Stoer integrator.

                      * *

                      * This implementation is basically a reimplementation in Java of the * odex * fortran code by E. Hairer and G. Wanner. The redistribution policy * for this code is available here, for * convenience, it is reproduced below.

                      *

                      * * * * * * * *
                      Copyright (c) 2004, Ernst Hairer
                      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.
                      • *
                      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 OR * 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.
                      * * @see GraggBulirschStoerIntegrator * @version $Revision: 1061507 $ $Date: 2011-01-20 21:55:00 +0100 (jeu. 20 janv. 2011) $ * @since 1.2 */ class GraggBulirschStoerStepInterpolator extends AbstractStepInterpolator { /** Serializable version identifier. */ private static final long serialVersionUID = 7320613236731409847L; /** Slope at the beginning of the step. */ private double[] y0Dot; /** State at the end of the step. */ private double[] y1; /** Slope at the end of the step. */ private double[] y1Dot; /** Derivatives at the middle of the step. * element 0 is state at midpoint, element 1 is first derivative ... */ private double[][] yMidDots; /** Interpolation polynoms. */ private double[][] polynoms; /** Error coefficients for the interpolation. */ private double[] errfac; /** Degree of the interpolation polynoms. */ private int currentDegree; /** Simple constructor. * This constructor should not be used directly, it is only intended * for the serialization process. */ public GraggBulirschStoerStepInterpolator() { y0Dot = null; y1 = null; y1Dot = null; yMidDots = null; resetTables(-1); } /** Simple constructor. * @param y reference to the integrator array holding the current state * @param y0Dot reference to the integrator array holding the slope * at the beginning of the step * @param y1 reference to the integrator array holding the state at * the end of the step * @param y1Dot reference to the integrator array holding the slope * at the end of the step * @param yMidDots reference to the integrator array holding the * derivatives at the middle point of the step * @param forward integration direction indicator */ public GraggBulirschStoerStepInterpolator(final double[] y, final double[] y0Dot, final double[] y1, final double[] y1Dot, final double[][] yMidDots, final boolean forward) { super(y, forward); this.y0Dot = y0Dot; this.y1 = y1; this.y1Dot = y1Dot; this.yMidDots = yMidDots; resetTables(yMidDots.length + 4); } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public GraggBulirschStoerStepInterpolator (final GraggBulirschStoerStepInterpolator interpolator) { super(interpolator); final int dimension = currentState.length; // the interpolator has been finalized, // the following arrays are not needed anymore y0Dot = null; y1 = null; y1Dot = null; yMidDots = null; // copy the interpolation polynoms (up to the current degree only) if (interpolator.polynoms == null) { polynoms = null; currentDegree = -1; } else { resetTables(interpolator.currentDegree); for (int i = 0; i < polynoms.length; ++i) { polynoms[i] = new double[dimension]; System.arraycopy(interpolator.polynoms[i], 0, polynoms[i], 0, dimension); } currentDegree = interpolator.currentDegree; } } /** Reallocate the internal tables. * Reallocate the internal tables in order to be able to handle * interpolation polynoms up to the given degree * @param maxDegree maximal degree to handle */ private void resetTables(final int maxDegree) { if (maxDegree < 0) { polynoms = null; errfac = null; currentDegree = -1; } else { final double[][] newPols = new double[maxDegree + 1][]; if (polynoms != null) { System.arraycopy(polynoms, 0, newPols, 0, polynoms.length); for (int i = polynoms.length; i < newPols.length; ++i) { newPols[i] = new double[currentState.length]; } } else { for (int i = 0; i < newPols.length; ++i) { newPols[i] = new double[currentState.length]; } } polynoms = newPols; // initialize the error factors array for interpolation if (maxDegree <= 4) { errfac = null; } else { errfac = new double[maxDegree - 4]; for (int i = 0; i < errfac.length; ++i) { final int ip5 = i + 5; errfac[i] = 1.0 / (ip5 * ip5); final double e = 0.5 * FastMath.sqrt (((double) (i + 1)) / ip5); for (int j = 0; j <= i; ++j) { errfac[i] *= e / (j + 1); } } } currentDegree = 0; } } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new GraggBulirschStoerStepInterpolator(this); } /** Compute the interpolation coefficients for dense output. * @param mu degree of the interpolation polynomial * @param h current step */ public void computeCoefficients(final int mu, final double h) { if ((polynoms == null) || (polynoms.length <= (mu + 4))) { resetTables(mu + 4); } currentDegree = mu + 4; for (int i = 0; i < currentState.length; ++i) { final double yp0 = h * y0Dot[i]; final double yp1 = h * y1Dot[i]; final double ydiff = y1[i] - currentState[i]; final double aspl = ydiff - yp1; final double bspl = yp0 - ydiff; polynoms[0][i] = currentState[i]; polynoms[1][i] = ydiff; polynoms[2][i] = aspl; polynoms[3][i] = bspl; if (mu < 0) { return; } // compute the remaining coefficients final double ph0 = 0.5 * (currentState[i] + y1[i]) + 0.125 * (aspl + bspl); polynoms[4][i] = 16 * (yMidDots[0][i] - ph0); if (mu > 0) { final double ph1 = ydiff + 0.25 * (aspl - bspl); polynoms[5][i] = 16 * (yMidDots[1][i] - ph1); if (mu > 1) { final double ph2 = yp1 - yp0; polynoms[6][i] = 16 * (yMidDots[2][i] - ph2 + polynoms[4][i]); if (mu > 2) { final double ph3 = 6 * (bspl - aspl); polynoms[7][i] = 16 * (yMidDots[3][i] - ph3 + 3 * polynoms[5][i]); for (int j = 4; j <= mu; ++j) { final double fac1 = 0.5 * j * (j - 1); final double fac2 = 2 * fac1 * (j - 2) * (j - 3); polynoms[j+4][i] = 16 * (yMidDots[j][i] + fac1 * polynoms[j+2][i] - fac2 * polynoms[j][i]); } } } } } } /** Estimate interpolation error. * @param scale scaling array * @return estimate of the interpolation error */ public double estimateError(final double[] scale) { double error = 0; if (currentDegree >= 5) { for (int i = 0; i < scale.length; ++i) { final double e = polynoms[currentDegree][i] / scale[i]; error += e * e; } error = FastMath.sqrt(error / scale.length) * errfac[currentDegree - 5]; } return error; } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) { final int dimension = currentState.length; final double oneMinusTheta = 1.0 - theta; final double theta05 = theta - 0.5; final double tOmT = theta * oneMinusTheta; final double t4 = tOmT * tOmT; final double t4Dot = 2 * tOmT * (1 - 2 * theta); final double dot1 = 1.0 / h; final double dot2 = theta * (2 - 3 * theta) / h; final double dot3 = ((3 * theta - 4) * theta + 1) / h; for (int i = 0; i < dimension; ++i) { final double p0 = polynoms[0][i]; final double p1 = polynoms[1][i]; final double p2 = polynoms[2][i]; final double p3 = polynoms[3][i]; interpolatedState[i] = p0 + theta * (p1 + oneMinusTheta * (p2 * theta + p3 * oneMinusTheta)); interpolatedDerivatives[i] = dot1 * p1 + dot2 * p2 + dot3 * p3; if (currentDegree > 3) { double cDot = 0; double c = polynoms[currentDegree][i]; for (int j = currentDegree - 1; j > 3; --j) { final double d = 1.0 / (j - 3); cDot = d * (theta05 * cDot + c); c = polynoms[j][i] + c * d * theta05; } interpolatedState[i] += t4 * c; interpolatedDerivatives[i] += (t4 * cDot + t4Dot * c) / h; } } if (h == 0) { // in this degenerated case, the previous computation leads to NaN for derivatives // we fix this by using the derivatives at midpoint System.arraycopy(yMidDots[1], 0, interpolatedDerivatives, 0, dimension); } } /** {@inheritDoc} */ @Override public void writeExternal(final ObjectOutput out) throws IOException { final int dimension = (currentState == null) ? -1 : currentState.length; // save the state of the base class writeBaseExternal(out); // save the local attributes (but not the temporary vectors) out.writeInt(currentDegree); for (int k = 0; k <= currentDegree; ++k) { for (int l = 0; l < dimension; ++l) { out.writeDouble(polynoms[k][l]); } } } /** {@inheritDoc} */ @Override public void readExternal(final ObjectInput in) throws IOException { // read the base class final double t = readBaseExternal(in); final int dimension = (currentState == null) ? -1 : currentState.length; // read the local attributes final int degree = in.readInt(); resetTables(degree); currentDegree = degree; for (int k = 0; k <= currentDegree; ++k) { for (int l = 0; l < dimension; ++l) { polynoms[k][l] = in.readDouble(); } } // we can now set the interpolated time and state setInterpolatedTime(t); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/package.html100644 1750 1750 1701 11532241246 27222 0ustarlucluc 0 0

                      This package provides classes to solve non-stiff Ordinary Differential Equations problems.

                      ././@LongLink100644 0 0 161 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInter100644 1750 1750 10631 11532241246 32454 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class implements a step interpolator for the classical fourth * order Runge-Kutta integrator. * *

                      This interpolator allows to compute dense output inside the last * step computed. The interpolation equation is consistent with the * integration scheme : *

                       *   y(t_n + theta h) = y (t_n + h)
                       *                    + (1 - theta) (h/6) [ (-4 theta^2 + 5 theta - 1) y'_1
                       *                                          +(4 theta^2 - 2 theta - 2) (y'_2 + y'_3)
                       *                                          -(4 theta^2 +   theta + 1) y'_4
                       *                                        ]
                       * 
                      * * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four * evaluations of the derivatives already computed during the * step.

                      * * @see ClassicalRungeKuttaIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class ClassicalRungeKuttaStepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -6576285612589783992L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link RungeKuttaStepInterpolator#reinitialize} method should be * called before using the instance in order to initialize the * internal arrays. This constructor is used only in order to delay * the initialization in some cases. The {@link RungeKuttaIntegrator} * class uses the prototyping design pattern to create the step * interpolators by cloning an uninitialized model and latter initializing * the copy. */ public ClassicalRungeKuttaStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public ClassicalRungeKuttaStepInterpolator(final ClassicalRungeKuttaStepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new ClassicalRungeKuttaStepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { final double fourTheta = 4 * theta; final double oneMinusTheta = 1 - theta; final double oneMinus2Theta = 1 - 2 * theta; final double s = oneMinusThetaH / 6.0; final double coeff1 = s * ((-fourTheta + 5) * theta - 1); final double coeff23 = s * (( fourTheta - 2) * theta - 2); final double coeff4 = s * ((-fourTheta - 1) * theta - 1); final double coeffDot1 = oneMinusTheta * oneMinus2Theta; final double coeffDot23 = 2 * theta * oneMinusTheta; final double coeffDot4 = -theta * oneMinus2Theta; for (int i = 0; i < interpolatedState.length; ++i) { final double yDot1 = yDotK[0][i]; final double yDot23 = yDotK[1][i] + yDotK[2][i]; final double yDot4 = yDotK[3][i]; interpolatedState[i] = currentState[i] + coeff1 * yDot1 + coeff23 * yDot23 + coeff4 * yDot4; interpolatedDerivatives[i] = coeffDot1 * yDot1 + coeffDot23 * yDot23 + coeffDot4 * yDot4; } } } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolator.jav100644 1750 1750 6743 11532241246 32500 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class implements a step interpolator for second order * Runge-Kutta integrator. * *

                      This interpolator computes dense output inside the last * step computed. The interpolation equation is consistent with the * integration scheme : * *

                       *   y(t_n + theta h) = y (t_n + h) + (1-theta) h [theta y'_1 - (1+theta) y'_2]
                       * 
                      * * where theta belongs to [0 ; 1] and where y'_1 and y'_2 are the two * evaluations of the derivatives already computed during the * step.

                      * * @see MidpointIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class MidpointStepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -865524111506042509L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize} * method should be called before using the instance in order to * initialize the internal arrays. This constructor is used only * in order to delay the initialization in some cases. The {@link * RungeKuttaIntegrator} class uses the prototyping design pattern * to create the step interpolators by cloning an uninitialized model * and later initializing the copy. */ public MidpointStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public MidpointStepInterpolator(final MidpointStepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new MidpointStepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { final double coeff1 = oneMinusThetaH * theta; final double coeff2 = oneMinusThetaH * (1.0 + theta); final double coeffDot2 = 2 * theta; final double coeffDot1 = 1 - coeffDot2; for (int i = 0; i < interpolatedState.length; ++i) { final double yDot1 = yDotK[0][i]; final double yDot2 = yDotK[1][i]; interpolatedState[i] = currentState[i] + coeff1 * yDot1 - coeff2 * yDot2; interpolatedDerivatives[i] = coeffDot1 * yDot1 + coeffDot2 * yDot2; } } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolato100644 1750 1750 10633 11532241246 32515 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** * This class implements a step interpolator for the 3/8 fourth * order Runge-Kutta integrator. * *

                      This interpolator allows to compute dense output inside the last * step computed. The interpolation equation is consistent with the * integration scheme : * *

                       *   y(t_n + theta h) = y (t_n + h)
                       *                    - (1 - theta) (h/8) [ (1 - 7 theta + 8 theta^2) y'_1
                       *                                      + 3 (1 +   theta - 4 theta^2) y'_2
                       *                                      + 3 (1 +   theta)             y'_3
                       *                                      +   (1 +   theta + 4 theta^2) y'_4
                       *                                        ]
                       * 
                      * * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four * evaluations of the derivatives already computed during the * step.

                      * * @see ThreeEighthesIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class ThreeEighthesStepInterpolator extends RungeKuttaStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -3345024435978721931L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize} * method should be called before using the instance in order to * initialize the internal arrays. This constructor is used only * in order to delay the initialization in some cases. The {@link * RungeKuttaIntegrator} class uses the prototyping design pattern * to create the step interpolators by cloning an uninitialized model * and later initializing the copy. */ public ThreeEighthesStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public ThreeEighthesStepInterpolator(final ThreeEighthesStepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new ThreeEighthesStepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { final double fourTheta2 = 4 * theta * theta; final double s = oneMinusThetaH / 8.0; final double coeff1 = s * (1 - 7 * theta + 2 * fourTheta2); final double coeff2 = 3 * s * (1 + theta - fourTheta2); final double coeff3 = 3 * s * (1 + theta); final double coeff4 = s * (1 + theta + fourTheta2); final double coeffDot3 = 0.75 * theta; final double coeffDot1 = coeffDot3 * (4 * theta - 5) + 1; final double coeffDot2 = coeffDot3 * (5 - 6 * theta); final double coeffDot4 = coeffDot3 * (2 * theta - 1); for (int i = 0; i < interpolatedState.length; ++i) { final double yDot1 = yDotK[0][i]; final double yDot2 = yDotK[1][i]; final double yDot3 = yDotK[2][i]; final double yDot4 = yDotK[3][i]; interpolatedState[i] = currentState[i] - coeff1 * yDot1 - coeff2 * yDot2 - coeff3 * yDot3 - coeff4 * yDot4; interpolatedDerivatives[i] = coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4; } } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.ja100644 1750 1750 14037 11532241246 32240 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.util.FastMath; /** * This class implements the 5(4) Dormand-Prince integrator for Ordinary * Differential Equations. *

                      This integrator is an embedded Runge-Kutta integrator * of order 5(4) used in local extrapolation mode (i.e. the solution * is computed using the high order formula) with stepsize control * (and automatic step initialization) and continuous output. This * method uses 7 functions evaluations per step. However, since this * is an fsal, the last evaluation of one step is the same as * the first evaluation of the next step and hence can be avoided. So * the cost is really 6 functions evaluations per step.

                      * *

                      This method has been published (whithout the continuous output * that was added by Shampine in 1986) in the following article : *

                       *  A family of embedded Runge-Kutta formulae
                       *  J. R. Dormand and P. J. Prince
                       *  Journal of Computational and Applied Mathematics
                       *  volume 6, no 1, 1980, pp. 19-26
                       * 

                      * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 1.2 */ public class DormandPrince54Integrator extends EmbeddedRungeKuttaIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Dormand-Prince 5(4)"; /** Time steps Butcher array. */ private static final double[] STATIC_C = { 1.0/5.0, 3.0/10.0, 4.0/5.0, 8.0/9.0, 1.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { {1.0/5.0}, {3.0/40.0, 9.0/40.0}, {44.0/45.0, -56.0/15.0, 32.0/9.0}, {19372.0/6561.0, -25360.0/2187.0, 64448.0/6561.0, -212.0/729.0}, {9017.0/3168.0, -355.0/33.0, 46732.0/5247.0, 49.0/176.0, -5103.0/18656.0}, {35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0} }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0, 0.0 }; /** Error array, element 1. */ private static final double E1 = 71.0 / 57600.0; // element 2 is zero, so it is neither stored nor used /** Error array, element 3. */ private static final double E3 = -71.0 / 16695.0; /** Error array, element 4. */ private static final double E4 = 71.0 / 1920.0; /** Error array, element 5. */ private static final double E5 = -17253.0 / 339200.0; /** Error array, element 6. */ private static final double E6 = 22.0 / 525.0; /** Error array, element 7. */ private static final double E7 = -1.0 / 40.0; /** Simple constructor. * Build a fifth order Dormand-Prince integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ public DormandPrince54Integrator(final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(), minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); } /** Simple constructor. * Build a fifth order Dormand-Prince integrator with the given step bounds * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ public DormandPrince54Integrator(final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(), minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); } /** {@inheritDoc} */ @Override public int getOrder() { return 5; } /** {@inheritDoc} */ @Override protected double estimateError(final double[][] yDotK, final double[] y0, final double[] y1, final double h) { double error = 0; for (int j = 0; j < mainSetDimension; ++j) { final double errSum = E1 * yDotK[0][j] + E3 * yDotK[2][j] + E4 * yDotK[3][j] + E5 * yDotK[4][j] + E6 * yDotK[5][j] + E7 * yDotK[6][j]; final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j])); final double tol = (vecAbsoluteTolerance == null) ? (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); final double ratio = h * errSum / tol; error += ratio * ratio; } return FastMath.sqrt(error / mainSetDimension); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.j100644 1750 1750 30671 11532241246 32467 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.AbstractIntegrator; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.ExtendedFirstOrderDifferentialEquations; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.util.FastMath; /** * This abstract class holds the common part of all adaptive * stepsize integrators for Ordinary Differential Equations. * *

                      These algorithms perform integration with stepsize control, which * means the user does not specify the integration step but rather a * tolerance on error. The error threshold is computed as *

                       * threshold_i = absTol_i + relTol_i * max (abs (ym), abs (ym+1))
                       * 
                      * where absTol_i is the absolute tolerance for component i of the * state vector and relTol_i is the relative tolerance for the same * component. The user can also use only two scalar values absTol and * relTol which will be used for all components. *

                      * *

                      If the Ordinary Differential Equations is an {@link ExtendedFirstOrderDifferentialEquations * extended ODE} rather than a {@link FirstOrderDifferentialEquations basic ODE}, * then only the {@link ExtendedFirstOrderDifferentialEquations#getMainSetDimension() * main set} part of the state vector is used for stepsize control, not the complete * state vector. *

                      * *

                      If the estimated error for ym+1 is such that *

                       * sqrt((sum (errEst_i / threshold_i)^2 ) / n) < 1
                       * 
                      * * (where n is the main set dimension) then the step is accepted, * otherwise the step is rejected and a new attempt is made with a new * stepsize.

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 * */ public abstract class AdaptiveStepsizeIntegrator extends AbstractIntegrator { /** Allowed absolute scalar error. */ protected final double scalAbsoluteTolerance; /** Allowed relative scalar error. */ protected final double scalRelativeTolerance; /** Allowed absolute vectorial error. */ protected final double[] vecAbsoluteTolerance; /** Allowed relative vectorial error. */ protected final double[] vecRelativeTolerance; /** Main set dimension. */ protected int mainSetDimension; /** User supplied initial step. */ private double initialStep; /** Minimal step. */ private final double minStep; /** Maximal step. */ private final double maxStep; /** Build an integrator with the given stepsize bounds. * The default step handler does nothing. * @param name name of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ public AdaptiveStepsizeIntegrator(final String name, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(name); this.minStep = FastMath.abs(minStep); this.maxStep = FastMath.abs(maxStep); this.initialStep = -1.0; this.scalAbsoluteTolerance = scalAbsoluteTolerance; this.scalRelativeTolerance = scalRelativeTolerance; this.vecAbsoluteTolerance = null; this.vecRelativeTolerance = null; resetInternalState(); } /** Build an integrator with the given stepsize bounds. * The default step handler does nothing. * @param name name of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ public AdaptiveStepsizeIntegrator(final String name, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(name); this.minStep = minStep; this.maxStep = maxStep; this.initialStep = -1.0; this.scalAbsoluteTolerance = 0; this.scalRelativeTolerance = 0; this.vecAbsoluteTolerance = vecAbsoluteTolerance.clone(); this.vecRelativeTolerance = vecRelativeTolerance.clone(); resetInternalState(); } /** Set the initial step size. *

                      This method allows the user to specify an initial positive * step size instead of letting the integrator guess it by * itself. If this method is not called before integration is * started, the initial step size will be estimated by the * integrator.

                      * @param initialStepSize initial step size to use (must be positive even * for backward integration ; providing a negative value or a value * outside of the min/max step interval will lead the integrator to * ignore the value and compute the initial step size by itself) */ public void setInitialStepSize(final double initialStepSize) { if ((initialStepSize < minStep) || (initialStepSize > maxStep)) { initialStep = -1.0; } else { initialStep = initialStepSize; } } /** Perform some sanity checks on the integration parameters. * @param equations differential equations set * @param t0 start time * @param y0 state vector at t0 * @param t target time for the integration * @param y placeholder where to put the state vector * @exception IntegratorException if some inconsistency is detected */ @Override protected void sanityChecks(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws IntegratorException { super.sanityChecks(equations, t0, y0, t, y); if (equations instanceof ExtendedFirstOrderDifferentialEquations) { mainSetDimension = ((ExtendedFirstOrderDifferentialEquations) equations).getMainSetDimension(); } else { mainSetDimension = equations.getDimension(); } if ((vecAbsoluteTolerance != null) && (vecAbsoluteTolerance.length != mainSetDimension)) { throw new IntegratorException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, mainSetDimension, vecAbsoluteTolerance.length); } if ((vecRelativeTolerance != null) && (vecRelativeTolerance.length != mainSetDimension)) { throw new IntegratorException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, mainSetDimension, vecRelativeTolerance.length); } } /** Initialize the integration step. * @param equations differential equations set * @param forward forward integration indicator * @param order order of the method * @param scale scaling vector for the state vector (can be shorter than state vector) * @param t0 start time * @param y0 state vector at t0 * @param yDot0 first time derivative of y0 * @param y1 work array for a state vector * @param yDot1 work array for the first time derivative of y1 * @return first integration step * @exception DerivativeException this exception is propagated to * the caller if the underlying user function triggers one */ public double initializeStep(final FirstOrderDifferentialEquations equations, final boolean forward, final int order, final double[] scale, final double t0, final double[] y0, final double[] yDot0, final double[] y1, final double[] yDot1) throws DerivativeException { if (initialStep > 0) { // use the user provided value return forward ? initialStep : -initialStep; } // very rough first guess : h = 0.01 * ||y/scale|| / ||y'/scale|| // this guess will be used to perform an Euler step double ratio; double yOnScale2 = 0; double yDotOnScale2 = 0; for (int j = 0; j < scale.length; ++j) { ratio = y0[j] / scale[j]; yOnScale2 += ratio * ratio; ratio = yDot0[j] / scale[j]; yDotOnScale2 += ratio * ratio; } double h = ((yOnScale2 < 1.0e-10) || (yDotOnScale2 < 1.0e-10)) ? 1.0e-6 : (0.01 * FastMath.sqrt(yOnScale2 / yDotOnScale2)); if (! forward) { h = -h; } // perform an Euler step using the preceding rough guess for (int j = 0; j < y0.length; ++j) { y1[j] = y0[j] + h * yDot0[j]; } computeDerivatives(t0 + h, y1, yDot1); // estimate the second derivative of the solution double yDDotOnScale = 0; for (int j = 0; j < scale.length; ++j) { ratio = (yDot1[j] - yDot0[j]) / scale[j]; yDDotOnScale += ratio * ratio; } yDDotOnScale = FastMath.sqrt(yDDotOnScale) / h; // step size is computed such that // h^order * max (||y'/tol||, ||y''/tol||) = 0.01 final double maxInv2 = FastMath.max(FastMath.sqrt(yDotOnScale2), yDDotOnScale); final double h1 = (maxInv2 < 1.0e-15) ? FastMath.max(1.0e-6, 0.001 * FastMath.abs(h)) : FastMath.pow(0.01 / maxInv2, 1.0 / order); h = FastMath.min(100.0 * FastMath.abs(h), h1); h = FastMath.max(h, 1.0e-12 * FastMath.abs(t0)); // avoids cancellation when computing t1 - t0 if (h < getMinStep()) { h = getMinStep(); } if (h > getMaxStep()) { h = getMaxStep(); } if (! forward) { h = -h; } return h; } /** Filter the integration step. * @param h signed step * @param forward forward integration indicator * @param acceptSmall if true, steps smaller than the minimal value * are silently increased up to this value, if false such small * steps generate an exception * @return a bounded integration step (h if no bound is reach, or a bounded value) * @exception IntegratorException if the step is too small and acceptSmall is false */ protected double filterStep(final double h, final boolean forward, final boolean acceptSmall) throws IntegratorException { double filteredH = h; if (FastMath.abs(h) < minStep) { if (acceptSmall) { filteredH = forward ? minStep : -minStep; } else { throw new IntegratorException( LocalizedFormats.MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION, minStep, FastMath.abs(h)); } } if (filteredH > maxStep) { filteredH = maxStep; } else if (filteredH < -maxStep) { filteredH = -maxStep; } return filteredH; } /** {@inheritDoc} */ public abstract double integrate (FirstOrderDifferentialEquations equations, double t0, double[] y0, double t, double[] y) throws DerivativeException, IntegratorException; /** {@inheritDoc} */ @Override public double getCurrentStepStart() { return stepStart; } /** Reset internal state to dummy values. */ protected void resetInternalState() { stepStart = Double.NaN; stepSize = FastMath.sqrt(minStep * maxStep); } /** Get the minimal step. * @return minimal step */ public double getMinStep() { return minStep; } /** Get the maximal step. * @return maximal step */ public double getMaxStep() { return maxStep; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.java100644 1750 1750 3735 11532241246 31437 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; /** * This class implements a second order Runge-Kutta integrator for * Ordinary Differential Equations. * *

                      This method is an explicit Runge-Kutta method, its Butcher-array * is the following one : *

                       *    0  |  0    0
                       *   1/2 | 1/2   0
                       *       |----------
                       *       |  0    1
                       * 
                      *

                      * * @see EulerIntegrator * @see ClassicalRungeKuttaIntegrator * @see GillIntegrator * * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $ * @since 1.2 */ public class MidpointIntegrator extends RungeKuttaIntegrator { /** Time steps Butcher array. */ private static final double[] STATIC_C = { 1.0 / 2.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { { 1.0 / 2.0 } }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 0.0, 1.0 }; /** Simple constructor. * Build a midpoint integrator with the given step. * @param step integration step */ public MidpointIntegrator(final double step) { super("midpoint", STATIC_C, STATIC_A, STATIC_B, new MidpointStepInterpolator(), step); } } ././@LongLink100644 0 0 153 11532242443 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrato100644 1750 1750 4476 11532241246 32465 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; /** * This class implements the classical fourth order Runge-Kutta * integrator for Ordinary Differential Equations (it is the most * often used Runge-Kutta method). * *

                      This method is an explicit Runge-Kutta method, its Butcher-array * is the following one : *

                       *    0  |  0    0    0    0
                       *   1/2 | 1/2   0    0    0
                       *   1/2 |  0   1/2   0    0
                       *    1  |  0    0    1    0
                       *       |--------------------
                       *       | 1/6  1/3  1/3  1/6
                       * 
                      *

                      * * @see EulerIntegrator * @see GillIntegrator * @see MidpointIntegrator * @see ThreeEighthesIntegrator * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $ * @since 1.2 */ public class ClassicalRungeKuttaIntegrator extends RungeKuttaIntegrator { /** Time steps Butcher array. */ private static final double[] STATIC_C = { 1.0 / 2.0, 1.0 / 2.0, 1.0 }; /** Internal weights Butcher array. */ private static final double[][] STATIC_A = { { 1.0 / 2.0 }, { 0.0, 1.0 / 2.0 }, { 0.0, 0.0, 1.0 } }; /** Propagation weights Butcher array. */ private static final double[] STATIC_B = { 1.0 / 6.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 6.0 }; /** Simple constructor. * Build a fourth-order Runge-Kutta integrator with the given * step. * @param step integration step */ public ClassicalRungeKuttaIntegrator(final double step) { super("classical Runge-Kutta", STATIC_C, STATIC_A, STATIC_B, new ClassicalRungeKuttaStepInterpolator(), step); } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaStepInterpolator.j100644 1750 1750 14373 11532241246 32475 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.commons.math.ode.AbstractIntegrator; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; /** This class represents an interpolator over the last step during an * ODE integration for Runge-Kutta and embedded Runge-Kutta integrators. * * @see RungeKuttaIntegrator * @see EmbeddedRungeKuttaIntegrator * * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 */ abstract class RungeKuttaStepInterpolator extends AbstractStepInterpolator { /** Slopes at the intermediate points */ protected double[][] yDotK; /** Reference to the integrator. */ protected AbstractIntegrator integrator; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link #reinitialize} method should be called before using the * instance in order to initialize the internal arrays. This * constructor is used only in order to delay the initialization in * some cases. The {@link RungeKuttaIntegrator} and {@link * EmbeddedRungeKuttaIntegrator} classes use the prototyping design * pattern to create the step interpolators by cloning an * uninitialized model and latter initializing the copy. */ protected RungeKuttaStepInterpolator() { super(); yDotK = null; integrator = null; } /** Copy constructor. *

                      The copied interpolator should have been finalized before the * copy, otherwise the copy will not be able to perform correctly any * interpolation and will throw a {@link NullPointerException} * later. Since we don't want this constructor to throw the * exceptions finalization may involve and since we don't want this * method to modify the state of the copied interpolator, * finalization is not done automatically, it * remains under user control.

                      *

                      The copy is a deep copy: its arrays are separated from the * original arrays of the instance.

                      * @param interpolator interpolator to copy from. */ public RungeKuttaStepInterpolator(final RungeKuttaStepInterpolator interpolator) { super(interpolator); if (interpolator.currentState != null) { final int dimension = currentState.length; yDotK = new double[interpolator.yDotK.length][]; for (int k = 0; k < interpolator.yDotK.length; ++k) { yDotK[k] = new double[dimension]; System.arraycopy(interpolator.yDotK[k], 0, yDotK[k], 0, dimension); } } else { yDotK = null; } // we cannot keep any reference to the equations in the copy // the interpolator should have been finalized before integrator = null; } /** Reinitialize the instance *

                      Some Runge-Kutta integrators need fewer functions evaluations * than their counterpart step interpolators. So the interpolator * should perform the last evaluations they need by themselves. The * {@link RungeKuttaIntegrator RungeKuttaIntegrator} and {@link * EmbeddedRungeKuttaIntegrator EmbeddedRungeKuttaIntegrator} * abstract classes call this method in order to let the step * interpolator perform the evaluations it needs. These evaluations * will be performed during the call to doFinalize if * any, i.e. only if the step handler either calls the {@link * AbstractStepInterpolator#finalizeStep finalizeStep} method or the * {@link AbstractStepInterpolator#getInterpolatedState * getInterpolatedState} method (for an interpolator which needs a * finalization) or if it clones the step interpolator.

                      * @param rkIntegrator integrator being used * @param y reference to the integrator array holding the state at * the end of the step * @param yDotArray reference to the integrator array holding all the * intermediate slopes * @param forward integration direction indicator */ public void reinitialize(final AbstractIntegrator rkIntegrator, final double[] y, final double[][] yDotArray, final boolean forward) { reinitialize(y, forward); this.yDotK = yDotArray; this.integrator = rkIntegrator; } /** {@inheritDoc} */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // save the state of the base class writeBaseExternal(out); // save the local attributes final int n = (currentState == null) ? -1 : currentState.length; final int kMax = (yDotK == null) ? -1 : yDotK.length; out.writeInt(kMax); for (int k = 0; k < kMax; ++k) { for (int i = 0; i < n; ++i) { out.writeDouble(yDotK[k][i]); } } // we do not save any reference to the equations } /** {@inheritDoc} */ @Override public void readExternal(final ObjectInput in) throws IOException { // read the base class final double t = readBaseExternal(in); // read the local attributes final int n = (currentState == null) ? -1 : currentState.length; final int kMax = in.readInt(); yDotK = (kMax < 0) ? null : new double[kMax][]; for (int k = 0; k < kMax; ++k) { yDotK[k] = (n < 0) ? null : new double[n]; for (int i = 0; i < n; ++i) { yDotK[k][i] = in.readDouble(); } } integrator = null; if (currentState != null) { // we can now set the interpolated time and state setInterpolatedTime(t); } else { interpolatedTime = t; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolator.java100644 1750 1750 11316 11532241246 31755 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** * This class implements a step interpolator for the Gill fourth * order Runge-Kutta integrator. * *

                      This interpolator allows to compute dense output inside the last * step computed. The interpolation equation is consistent with the * integration scheme : * *

                       *   y(t_n + theta h) = y (t_n + h)
                       *                    - (1 - theta) (h/6) [ (1 - theta) (1 - 4 theta) y'_1
                       *                                        + (1 - theta) (1 + 2 theta) ((2-q) y'_2 + (2+q) y'_3)
                       *                                        + (1 + theta + 4 theta^2) y'_4
                       *                                        ]
                       * 
                      * where theta belongs to [0 ; 1], q = sqrt(2) and where y'_1 to y'_4 * are the four evaluations of the derivatives already computed during * the step.

                      * * @see GillIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ class GillStepInterpolator extends RungeKuttaStepInterpolator { /** First Gill coefficient. */ private static final double TWO_MINUS_SQRT_2 = 2 - FastMath.sqrt(2.0); /** Second Gill coefficient. */ private static final double TWO_PLUS_SQRT_2 = 2 + FastMath.sqrt(2.0); /** Serializable version identifier */ private static final long serialVersionUID = -107804074496313322L; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize} * method should be called before using the instance in order to * initialize the internal arrays. This constructor is used only * in order to delay the initialization in some cases. The {@link * RungeKuttaIntegrator} class uses the prototyping design pattern * to create the step interpolators by cloning an uninitialized model * and later initializing the copy. */ public GillStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public GillStepInterpolator(final GillStepInterpolator interpolator) { super(interpolator); } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new GillStepInterpolator(this); } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) throws DerivativeException { final double twoTheta = 2 * theta; final double fourTheta = 4 * theta; final double s = oneMinusThetaH / 6.0; final double oMt = 1 - theta; final double soMt = s * oMt; final double c23 = soMt * (1 + twoTheta); final double coeff1 = soMt * (1 - fourTheta); final double coeff2 = c23 * TWO_MINUS_SQRT_2; final double coeff3 = c23 * TWO_PLUS_SQRT_2; final double coeff4 = s * (1 + theta * (1 + fourTheta)); final double coeffDot1 = theta * (twoTheta - 3) + 1; final double cDot23 = theta * oMt; final double coeffDot2 = cDot23 * TWO_MINUS_SQRT_2; final double coeffDot3 = cDot23 * TWO_PLUS_SQRT_2; final double coeffDot4 = theta * (twoTheta - 1); for (int i = 0; i < interpolatedState.length; ++i) { final double yDot1 = yDotK[0][i]; final double yDot2 = yDotK[1][i]; final double yDot3 = yDotK[2][i]; final double yDot4 = yDotK[3][i]; interpolatedState[i] = currentState[i] - coeff1 * yDot1 - coeff2 * yDot2 - coeff3 * yDot3 - coeff4 * yDot4; interpolatedDerivatives[i] = coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.java100644 1750 1750 43302 11532241246 32271 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import java.util.Arrays; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealMatrixPreservingVisitor; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; /** * This class implements implicit Adams-Moulton integrators for Ordinary * Differential Equations. * *

                      Adams-Moulton methods (in fact due to Adams alone) are implicit * multistep ODE solvers. This implementation is a variation of the classical * one: it uses adaptive stepsize to implement error control, whereas * classical implementations are fixed step size. The value of state vector * at step n+1 is a simple combination of the value at step n and of the * derivatives at steps n+1, n, n-1 ... Since y'n+1 is needed to * compute yn+1,another method must be used to compute a first * estimate of yn+1, then compute y'n+1, then compute * a final estimate of yn+1 using the following formulas. Depending * on the number k of previous steps one wants to use for computing the next * value, different formulas are available for the final estimate:

                      *
                        *
                      • k = 1: yn+1 = yn + h y'n+1
                      • *
                      • k = 2: yn+1 = yn + h (y'n+1+y'n)/2
                      • *
                      • k = 3: yn+1 = yn + h (5y'n+1+8y'n-y'n-1)/12
                      • *
                      • k = 4: yn+1 = yn + h (9y'n+1+19y'n-5y'n-1+y'n-2)/24
                      • *
                      • ...
                      • *
                      * *

                      A k-steps Adams-Moulton method is of order k+1.

                      * *

                      Implementation details

                      * *

                      We define scaled derivatives si(n) at step n as: *

                       * s1(n) = h y'n for first derivative
                       * s2(n) = h2/2 y''n for second derivative
                       * s3(n) = h3/6 y'''n for third derivative
                       * ...
                       * sk(n) = hk/k! y(k)n for kth derivative
                       * 

                      * *

                      The definitions above use the classical representation with several previous first * derivatives. Lets define *

                       *   qn = [ s1(n-1) s1(n-2) ... s1(n-(k-1)) ]T
                       * 
                      * (we omit the k index in the notation for clarity). With these definitions, * Adams-Moulton methods can be written: *
                        *
                      • k = 1: yn+1 = yn + s1(n+1)
                      • *
                      • k = 2: yn+1 = yn + 1/2 s1(n+1) + [ 1/2 ] qn+1
                      • *
                      • k = 3: yn+1 = yn + 5/12 s1(n+1) + [ 8/12 -1/12 ] qn+1
                      • *
                      • k = 4: yn+1 = yn + 9/24 s1(n+1) + [ 19/24 -5/24 1/24 ] qn+1
                      • *
                      • ...
                      • *

                      * *

                      Instead of using the classical representation with first derivatives only (yn, * s1(n+1) and qn+1), our implementation uses the Nordsieck vector with * higher degrees scaled derivatives all taken at the same step (yn, s1(n) * and rn) where rn is defined as: *

                       * rn = [ s2(n), s3(n) ... sk(n) ]T
                       * 
                      * (here again we omit the k index in the notation for clarity) *

                      * *

                      Taylor series formulas show that for any index offset i, s1(n-i) can be * computed from s1(n), s2(n) ... sk(n), the formula being exact * for degree k polynomials. *

                       * s1(n-i) = s1(n) + ∑j j (-i)j-1 sj(n)
                       * 
                      * The previous formula can be used with several values for i to compute the transform between * classical representation and Nordsieck vector. The transform between rn * and qn resulting from the Taylor series formulas above is: *
                       * qn = s1(n) u + P rn
                       * 
                      * where u is the [ 1 1 ... 1 ]T vector and P is the (k-1)×(k-1) matrix built * with the j (-i)j-1 terms: *
                       *        [  -2   3   -4    5  ... ]
                       *        [  -4  12  -32   80  ... ]
                       *   P =  [  -6  27 -108  405  ... ]
                       *        [  -8  48 -256 1280  ... ]
                       *        [          ...           ]
                       * 

                      * *

                      Using the Nordsieck vector has several advantages: *

                        *
                      • it greatly simplifies step interpolation as the interpolator mainly applies * Taylor series formulas,
                      • *
                      • it simplifies step changes that occur when discrete events that truncate * the step are triggered,
                      • *
                      • it allows to extend the methods in order to support adaptive stepsize.
                      • *

                      * *

                      The predicted Nordsieck vector at step n+1 is computed from the Nordsieck vector at step * n as follows: *

                        *
                      • Yn+1 = yn + s1(n) + uT rn
                      • *
                      • S1(n+1) = h f(tn+1, Yn+1)
                      • *
                      • Rn+1 = (s1(n) - S1(n+1)) P-1 u + P-1 A P rn
                      • *
                      * where A is a rows shifting matrix (the lower left part is an identity matrix): *
                       *        [ 0 0   ...  0 0 | 0 ]
                       *        [ ---------------+---]
                       *        [ 1 0   ...  0 0 | 0 ]
                       *    A = [ 0 1   ...  0 0 | 0 ]
                       *        [       ...      | 0 ]
                       *        [ 0 0   ...  1 0 | 0 ]
                       *        [ 0 0   ...  0 1 | 0 ]
                       * 
                      * From this predicted vector, the corrected vector is computed as follows: *
                        *
                      • yn+1 = yn + S1(n+1) + [ -1 +1 -1 +1 ... ±1 ] rn+1
                      • *
                      • s1(n+1) = h f(tn+1, yn+1)
                      • *
                      • rn+1 = Rn+1 + (s1(n+1) - S1(n+1)) P-1 u
                      • *
                      * where the upper case Yn+1, S1(n+1) and Rn+1 represent the * predicted states whereas the lower case yn+1, sn+1 and rn+1 * represent the corrected states.

                      * *

                      The P-1u vector and the P-1 A P matrix do not depend on the state, * they only depend on k and therefore are precomputed once for all.

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class AdamsMoultonIntegrator extends AdamsIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Adams-Moulton"; /** * Build an Adams-Moulton integrator with the given order and error control parameters. * @param nSteps number of steps of the method excluding the one being computed * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsMoultonIntegrator(final int nSteps, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) throws IllegalArgumentException { super(METHOD_NAME, nSteps, nSteps + 1, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); } /** * Build an Adams-Moulton integrator with the given order and error control parameters. * @param nSteps number of steps of the method excluding the one being computed * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error * @exception IllegalArgumentException if order is 1 or less */ public AdamsMoultonIntegrator(final int nSteps, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) throws IllegalArgumentException { super(METHOD_NAME, nSteps, nSteps + 1, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); } /** {@inheritDoc} */ @Override public double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException { final int n = y0.length; sanityChecks(equations, t0, y0, t, y); setEquations(equations); resetEvaluations(); final boolean forward = t > t0; // initialize working arrays if (y != y0) { System.arraycopy(y0, 0, y, 0, n); } final double[] yDot = new double[y0.length]; final double[] yTmp = new double[y0.length]; final double[] predictedScaled = new double[y0.length]; Array2DRowRealMatrix nordsieckTmp = null; // set up two interpolators sharing the integrator arrays final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator(); interpolator.reinitialize(y, forward); // set up integration control objects for (StepHandler handler : stepHandlers) { handler.reset(); } setStateInitialized(false); // compute the initial Nordsieck vector using the configured starter integrator start(t0, y, t); interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); interpolator.storeTime(stepStart); double hNew = stepSize; interpolator.rescale(hNew); isLastStep = false; do { double error = 10; while (error >= 1.0) { stepSize = hNew; // predict a first estimate of the state at step end (P in the PECE sequence) final double stepEnd = stepStart + stepSize; interpolator.setInterpolatedTime(stepEnd); System.arraycopy(interpolator.getInterpolatedState(), 0, yTmp, 0, y0.length); // evaluate a first estimate of the derivative (first E in the PECE sequence) computeDerivatives(stepEnd, yTmp, yDot); // update Nordsieck vector for (int j = 0; j < y0.length; ++j) { predictedScaled[j] = stepSize * yDot[j]; } nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck); updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp); // apply correction (C in the PECE sequence) error = nordsieckTmp.walkInOptimizedOrder(new Corrector(y, predictedScaled, yTmp)); if (error >= 1.0) { // reject the step and attempt to reduce error by stepsize control final double factor = computeStepGrowShrinkFactor(error); hNew = filterStep(stepSize * factor, forward, false); interpolator.rescale(hNew); } } // evaluate a final estimate of the derivative (second E in the PECE sequence) final double stepEnd = stepStart + stepSize; computeDerivatives(stepEnd, yTmp, yDot); // update Nordsieck vector final double[] correctedScaled = new double[y0.length]; for (int j = 0; j < y0.length; ++j) { correctedScaled[j] = stepSize * yDot[j]; } updateHighOrderDerivativesPhase2(predictedScaled, correctedScaled, nordsieckTmp); // discrete events handling System.arraycopy(yTmp, 0, y, 0, n); interpolator.reinitialize(stepEnd, stepSize, correctedScaled, nordsieckTmp); interpolator.storeTime(stepStart); interpolator.shift(); interpolator.storeTime(stepEnd); stepStart = acceptStep(interpolator, y, yDot, t); scaled = correctedScaled; nordsieck = nordsieckTmp; if (!isLastStep) { // prepare next step interpolator.storeTime(stepStart); if (resetOccurred) { // some events handler has triggered changes that // invalidate the derivatives, we need to restart from scratch start(stepStart, y, t); interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); } // stepsize control for next step final double factor = computeStepGrowShrinkFactor(error); final double scaledH = stepSize * factor; final double nextT = stepStart + scaledH; final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); hNew = filterStep(scaledH, forward, nextIsLast); final double filteredNextT = stepStart + hNew; final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t); if (filteredNextIsLast) { hNew = t - stepStart; } interpolator.rescale(hNew); } } while (!isLastStep); final double stopTime = stepStart; stepStart = Double.NaN; stepSize = Double.NaN; return stopTime; } /** Corrector for current state in Adams-Moulton method. *

                      * This visitor implements the Taylor series formula: *

                           * Yn+1 = yn + s1(n+1) + [ -1 +1 -1 +1 ... ±1 ] rn+1
                           * 
                      *

                      */ private class Corrector implements RealMatrixPreservingVisitor { /** Previous state. */ private final double[] previous; /** Current scaled first derivative. */ private final double[] scaled; /** Current state before correction. */ private final double[] before; /** Current state after correction. */ private final double[] after; /** Simple constructor. * @param previous previous state * @param scaled current scaled first derivative * @param state state to correct (will be overwritten after visit) */ public Corrector(final double[] previous, final double[] scaled, final double[] state) { this.previous = previous; this.scaled = scaled; this.after = state; this.before = state.clone(); } /** {@inheritDoc} */ public void start(int rows, int columns, int startRow, int endRow, int startColumn, int endColumn) { Arrays.fill(after, 0.0); } /** {@inheritDoc} */ public void visit(int row, int column, double value) { if ((row & 0x1) == 0) { after[column] -= value; } else { after[column] += value; } } /** * End visiting the Nordsieck vector. *

                      The correction is used to control stepsize. So its amplitude is * considered to be an error, which must be normalized according to * error control settings. If the normalized value is greater than 1, * the correction was too large and the step must be rejected.

                      * @return the normalized correction, if greater than 1, the step * must be rejected */ public double end() { double error = 0; for (int i = 0; i < after.length; ++i) { after[i] += previous[i] + scaled[i]; if (i < mainSetDimension) { final double yScale = FastMath.max(FastMath.abs(previous[i]), FastMath.abs(after[i])); final double tol = (vecAbsoluteTolerance == null) ? (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale); final double ratio = (after[i] - before[i]) / tol; error += ratio * ratio; } } return FastMath.sqrt(error / mainSetDimension); } } } ././@LongLink100644 0 0 152 11532242443 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator100644 1750 1750 104326 11532241246 32532 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.FirstOrderDifferentialEquations; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.DummyStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; /** * This class implements a Gragg-Bulirsch-Stoer integrator for * Ordinary Differential Equations. * *

                      The Gragg-Bulirsch-Stoer algorithm is one of the most efficient * ones currently available for smooth problems. It uses Richardson * extrapolation to estimate what would be the solution if the step * size could be decreased down to zero.

                      * *

                      * This method changes both the step size and the order during * integration, in order to minimize computation cost. It is * particularly well suited when a very high precision is needed. The * limit where this method becomes more efficient than high-order * embedded Runge-Kutta methods like {@link DormandPrince853Integrator * Dormand-Prince 8(5,3)} depends on the problem. Results given in the * Hairer, Norsett and Wanner book show for example that this limit * occurs for accuracy around 1e-6 when integrating Saltzam-Lorenz * equations (the authors note this problem is extremely sensitive * to the errors in the first integration steps), and around 1e-11 * for a two dimensional celestial mechanics problems with seven * bodies (pleiades problem, involving quasi-collisions for which * automatic step size control is essential). *

                      * *

                      * This implementation is basically a reimplementation in Java of the * odex * fortran code by E. Hairer and G. Wanner. The redistribution policy * for this code is available here, for * convenience, it is reproduced below.

                      *

                      * * * * * * * *
                      Copyright (c) 2004, Ernst Hairer
                      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.
                      • *
                      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 OR * 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.
                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public class GraggBulirschStoerIntegrator extends AdaptiveStepsizeIntegrator { /** Integrator method name. */ private static final String METHOD_NAME = "Gragg-Bulirsch-Stoer"; /** maximal order. */ private int maxOrder; /** step size sequence. */ private int[] sequence; /** overall cost of applying step reduction up to iteration k+1, in number of calls. */ private int[] costPerStep; /** cost per unit step. */ private double[] costPerTimeUnit; /** optimal steps for each order. */ private double[] optimalStep; /** extrapolation coefficients. */ private double[][] coeff; /** stability check enabling parameter. */ private boolean performTest; /** maximal number of checks for each iteration. */ private int maxChecks; /** maximal number of iterations for which checks are performed. */ private int maxIter; /** stepsize reduction factor in case of stability check failure. */ private double stabilityReduction; /** first stepsize control factor. */ private double stepControl1; /** second stepsize control factor. */ private double stepControl2; /** third stepsize control factor. */ private double stepControl3; /** fourth stepsize control factor. */ private double stepControl4; /** first order control factor. */ private double orderControl1; /** second order control factor. */ private double orderControl2; /** use interpolation error in stepsize control. */ private boolean useInterpolationError; /** interpolation order control parameter. */ private int mudif; /** Simple constructor. * Build a Gragg-Bulirsch-Stoer integrator with the given step * bounds. All tuning parameters are set to their default * values. The default step handler does nothing. * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ public GraggBulirschStoerIntegrator(final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(METHOD_NAME, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); setStabilityCheck(true, -1, -1, -1); setStepsizeControl(-1, -1, -1, -1); setOrderControl(-1, -1, -1); setInterpolationControl(true, -1); } /** Simple constructor. * Build a Gragg-Bulirsch-Stoer integrator with the given step * bounds. All tuning parameters are set to their default * values. The default step handler does nothing. * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ public GraggBulirschStoerIntegrator(final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(METHOD_NAME, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); setStabilityCheck(true, -1, -1, -1); setStepsizeControl(-1, -1, -1, -1); setOrderControl(-1, -1, -1); setInterpolationControl(true, -1); } /** Set the stability check controls. *

                      The stability check is performed on the first few iterations of * the extrapolation scheme. If this test fails, the step is rejected * and the stepsize is reduced.

                      *

                      By default, the test is performed, at most during two * iterations at each step, and at most once for each of these * iterations. The default stepsize reduction factor is 0.5.

                      * @param performStabilityCheck if true, stability check will be performed, if false, the check will be skipped * @param maxNumIter maximal number of iterations for which checks are * performed (the number of iterations is reset to default if negative * or null) * @param maxNumChecks maximal number of checks for each iteration * (the number of checks is reset to default if negative or null) * @param stepsizeReductionFactor stepsize reduction factor in case of * failure (the factor is reset to default if lower than 0.0001 or * greater than 0.9999) */ public void setStabilityCheck(final boolean performStabilityCheck, final int maxNumIter, final int maxNumChecks, final double stepsizeReductionFactor) { this.performTest = performStabilityCheck; this.maxIter = (maxNumIter <= 0) ? 2 : maxNumIter; this.maxChecks = (maxNumChecks <= 0) ? 1 : maxNumChecks; if ((stepsizeReductionFactor < 0.0001) || (stepsizeReductionFactor > 0.9999)) { this.stabilityReduction = 0.5; } else { this.stabilityReduction = stepsizeReductionFactor; } } /** Set the step size control factors. *

                      The new step size hNew is computed from the old one h by: *

                         * hNew = h * stepControl2 / (err/stepControl1)^(1/(2k+1))
                         * 
                      * where err is the scaled error and k the iteration number of the * extrapolation scheme (counting from 0). The default values are * 0.65 for stepControl1 and 0.94 for stepControl2.

                      *

                      The step size is subject to the restriction: *

                         * stepControl3^(1/(2k+1))/stepControl4 <= hNew/h <= 1/stepControl3^(1/(2k+1))
                         * 
                      * The default values are 0.02 for stepControl3 and 4.0 for * stepControl4.

                      * @param control1 first stepsize control factor (the factor is * reset to default if lower than 0.0001 or greater than 0.9999) * @param control2 second stepsize control factor (the factor * is reset to default if lower than 0.0001 or greater than 0.9999) * @param control3 third stepsize control factor (the factor is * reset to default if lower than 0.0001 or greater than 0.9999) * @param control4 fourth stepsize control factor (the factor * is reset to default if lower than 1.0001 or greater than 999.9) */ public void setStepsizeControl(final double control1, final double control2, final double control3, final double control4) { if ((control1 < 0.0001) || (control1 > 0.9999)) { this.stepControl1 = 0.65; } else { this.stepControl1 = control1; } if ((control2 < 0.0001) || (control2 > 0.9999)) { this.stepControl2 = 0.94; } else { this.stepControl2 = control2; } if ((control3 < 0.0001) || (control3 > 0.9999)) { this.stepControl3 = 0.02; } else { this.stepControl3 = control3; } if ((control4 < 1.0001) || (control4 > 999.9)) { this.stepControl4 = 4.0; } else { this.stepControl4 = control4; } } /** Set the order control parameters. *

                      The Gragg-Bulirsch-Stoer method changes both the step size and * the order during integration, in order to minimize computation * cost. Each extrapolation step increases the order by 2, so the * maximal order that will be used is always even, it is twice the * maximal number of columns in the extrapolation table.

                      *
                         * order is decreased if w(k-1) <= w(k)   * orderControl1
                         * order is increased if w(k)   <= w(k-1) * orderControl2
                         * 
                      *

                      where w is the table of work per unit step for each order * (number of function calls divided by the step length), and k is * the current order.

                      *

                      The default maximal order after construction is 18 (i.e. the * maximal number of columns is 9). The default values are 0.8 for * orderControl1 and 0.9 for orderControl2.

                      * @param maximalOrder maximal order in the extrapolation table (the * maximal order is reset to default if order <= 6 or odd) * @param control1 first order control factor (the factor is * reset to default if lower than 0.0001 or greater than 0.9999) * @param control2 second order control factor (the factor * is reset to default if lower than 0.0001 or greater than 0.9999) */ public void setOrderControl(final int maximalOrder, final double control1, final double control2) { if ((maximalOrder <= 6) || (maximalOrder % 2 != 0)) { this.maxOrder = 18; } if ((control1 < 0.0001) || (control1 > 0.9999)) { this.orderControl1 = 0.8; } else { this.orderControl1 = control1; } if ((control2 < 0.0001) || (control2 > 0.9999)) { this.orderControl2 = 0.9; } else { this.orderControl2 = control2; } // reinitialize the arrays initializeArrays(); } /** {@inheritDoc} */ @Override public void addStepHandler (final StepHandler handler) { super.addStepHandler(handler); // reinitialize the arrays initializeArrays(); } /** {@inheritDoc} */ @Override public void addEventHandler(final EventHandler function, final double maxCheckInterval, final double convergence, final int maxIterationCount) { super.addEventHandler(function, maxCheckInterval, convergence, maxIterationCount); // reinitialize the arrays initializeArrays(); } /** Initialize the integrator internal arrays. */ private void initializeArrays() { final int size = maxOrder / 2; if ((sequence == null) || (sequence.length != size)) { // all arrays should be reallocated with the right size sequence = new int[size]; costPerStep = new int[size]; coeff = new double[size][]; costPerTimeUnit = new double[size]; optimalStep = new double[size]; } if (requiresDenseOutput()) { // step size sequence: 2, 6, 10, 14, ... for (int k = 0; k < size; ++k) { sequence[k] = 4 * k + 2; } } else { // step size sequence: 2, 4, 6, 8, ... for (int k = 0; k < size; ++k) { sequence[k] = 2 * (k + 1); } } // initialize the order selection cost array // (number of function calls for each column of the extrapolation table) costPerStep[0] = sequence[0] + 1; for (int k = 1; k < size; ++k) { costPerStep[k] = costPerStep[k-1] + sequence[k]; } // initialize the extrapolation tables for (int k = 0; k < size; ++k) { coeff[k] = (k > 0) ? new double[k] : null; for (int l = 0; l < k; ++l) { final double ratio = ((double) sequence[k]) / sequence[k-l-1]; coeff[k][l] = 1.0 / (ratio * ratio - 1.0); } } } /** Set the interpolation order control parameter. * The interpolation order for dense output is 2k - mudif + 1. The * default value for mudif is 4 and the interpolation error is used * in stepsize control by default. * * @param useInterpolationErrorForControl if true, interpolation error is used * for stepsize control * @param mudifControlParameter interpolation order control parameter (the parameter * is reset to default if <= 0 or >= 7) */ public void setInterpolationControl(final boolean useInterpolationErrorForControl, final int mudifControlParameter) { this.useInterpolationError = useInterpolationErrorForControl; if ((mudifControlParameter <= 0) || (mudifControlParameter >= 7)) { this.mudif = 4; } else { this.mudif = mudifControlParameter; } } /** Update scaling array. * @param y1 first state vector to use for scaling * @param y2 second state vector to use for scaling * @param scale scaling array to update (can be shorter than state) */ private void rescale(final double[] y1, final double[] y2, final double[] scale) { if (vecAbsoluteTolerance == null) { for (int i = 0; i < scale.length; ++i) { final double yi = FastMath.max(FastMath.abs(y1[i]), FastMath.abs(y2[i])); scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * yi; } } else { for (int i = 0; i < scale.length; ++i) { final double yi = FastMath.max(FastMath.abs(y1[i]), FastMath.abs(y2[i])); scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yi; } } } /** Perform integration over one step using substeps of a modified * midpoint method. * @param t0 initial time * @param y0 initial value of the state vector at t0 * @param step global step * @param k iteration number (from 0 to sequence.length - 1) * @param scale scaling array (can be shorter than state) * @param f placeholder where to put the state vector derivatives at each substep * (element 0 already contains initial derivative) * @param yMiddle placeholder where to put the state vector at the middle of the step * @param yEnd placeholder where to put the state vector at the end * @param yTmp placeholder for one state vector * @return true if computation was done properly, * false if stability check failed before end of computation * @throws DerivativeException this exception is propagated to the caller if the * underlying user function triggers one */ private boolean tryStep(final double t0, final double[] y0, final double step, final int k, final double[] scale, final double[][] f, final double[] yMiddle, final double[] yEnd, final double[] yTmp) throws DerivativeException { final int n = sequence[k]; final double subStep = step / n; final double subStep2 = 2 * subStep; // first substep double t = t0 + subStep; for (int i = 0; i < y0.length; ++i) { yTmp[i] = y0[i]; yEnd[i] = y0[i] + subStep * f[0][i]; } computeDerivatives(t, yEnd, f[1]); // other substeps for (int j = 1; j < n; ++j) { if (2 * j == n) { // save the point at the middle of the step System.arraycopy(yEnd, 0, yMiddle, 0, y0.length); } t += subStep; for (int i = 0; i < y0.length; ++i) { final double middle = yEnd[i]; yEnd[i] = yTmp[i] + subStep2 * f[j][i]; yTmp[i] = middle; } computeDerivatives(t, yEnd, f[j+1]); // stability check if (performTest && (j <= maxChecks) && (k < maxIter)) { double initialNorm = 0.0; for (int l = 0; l < scale.length; ++l) { final double ratio = f[0][l] / scale[l]; initialNorm += ratio * ratio; } double deltaNorm = 0.0; for (int l = 0; l < scale.length; ++l) { final double ratio = (f[j+1][l] - f[0][l]) / scale[l]; deltaNorm += ratio * ratio; } if (deltaNorm > 4 * FastMath.max(1.0e-15, initialNorm)) { return false; } } } // correction of the last substep (at t0 + step) for (int i = 0; i < y0.length; ++i) { yEnd[i] = 0.5 * (yTmp[i] + yEnd[i] + subStep * f[n][i]); } return true; } /** Extrapolate a vector. * @param offset offset to use in the coefficients table * @param k index of the last updated point * @param diag working diagonal of the Aitken-Neville's * triangle, without the last element * @param last last element */ private void extrapolate(final int offset, final int k, final double[][] diag, final double[] last) { // update the diagonal for (int j = 1; j < k; ++j) { for (int i = 0; i < last.length; ++i) { // Aitken-Neville's recursive formula diag[k-j-1][i] = diag[k-j][i] + coeff[k+offset][j-1] * (diag[k-j][i] - diag[k-j-1][i]); } } // update the last element for (int i = 0; i < last.length; ++i) { // Aitken-Neville's recursive formula last[i] = diag[0][i] + coeff[k+offset][k-1] * (diag[0][i] - last[i]); } } /** {@inheritDoc} */ @Override public double integrate(final FirstOrderDifferentialEquations equations, final double t0, final double[] y0, final double t, final double[] y) throws DerivativeException, IntegratorException { sanityChecks(equations, t0, y0, t, y); setEquations(equations); resetEvaluations(); final boolean forward = t > t0; // create some internal working arrays final double[] yDot0 = new double[y0.length]; final double[] y1 = new double[y0.length]; final double[] yTmp = new double[y0.length]; final double[] yTmpDot = new double[y0.length]; final double[][] diagonal = new double[sequence.length-1][]; final double[][] y1Diag = new double[sequence.length-1][]; for (int k = 0; k < sequence.length-1; ++k) { diagonal[k] = new double[y0.length]; y1Diag[k] = new double[y0.length]; } final double[][][] fk = new double[sequence.length][][]; for (int k = 0; k < sequence.length; ++k) { fk[k] = new double[sequence[k] + 1][]; // all substeps start at the same point, so share the first array fk[k][0] = yDot0; for (int l = 0; l < sequence[k]; ++l) { fk[k][l+1] = new double[y0.length]; } } if (y != y0) { System.arraycopy(y0, 0, y, 0, y0.length); } double[] yDot1 = new double[y0.length]; double[][] yMidDots = null; final boolean denseOutput = requiresDenseOutput(); if (denseOutput) { yMidDots = new double[1 + 2 * sequence.length][]; for (int j = 0; j < yMidDots.length; ++j) { yMidDots[j] = new double[y0.length]; } } else { yMidDots = new double[1][]; yMidDots[0] = new double[y0.length]; } // initial scaling final double[] scale = new double[mainSetDimension]; rescale(y, y, scale); // initial order selection final double tol = (vecRelativeTolerance == null) ? scalRelativeTolerance : vecRelativeTolerance[0]; final double log10R = FastMath.log10(FastMath.max(1.0e-10, tol)); int targetIter = FastMath.max(1, FastMath.min(sequence.length - 2, (int) FastMath.floor(0.5 - 0.6 * log10R))); // set up an interpolator sharing the integrator arrays AbstractStepInterpolator interpolator = null; if (denseOutput) { interpolator = new GraggBulirschStoerStepInterpolator(y, yDot0, y1, yDot1, yMidDots, forward); } else { interpolator = new DummyStepInterpolator(y, yDot1, forward); } interpolator.storeTime(t0); stepStart = t0; double hNew = 0; double maxError = Double.MAX_VALUE; boolean previousRejected = false; boolean firstTime = true; boolean newStep = true; boolean firstStepAlreadyComputed = false; for (StepHandler handler : stepHandlers) { handler.reset(); } setStateInitialized(false); costPerTimeUnit[0] = 0; isLastStep = false; do { double error; boolean reject = false; if (newStep) { interpolator.shift(); // first evaluation, at the beginning of the step if (! firstStepAlreadyComputed) { computeDerivatives(stepStart, y, yDot0); } if (firstTime) { hNew = initializeStep(equations, forward, 2 * targetIter + 1, scale, stepStart, y, yDot0, yTmp, yTmpDot); } newStep = false; } stepSize = hNew; // step adjustment near bounds if ((forward && (stepStart + stepSize > t)) || ((! forward) && (stepStart + stepSize < t))) { stepSize = t - stepStart; } final double nextT = stepStart + stepSize; isLastStep = forward ? (nextT >= t) : (nextT <= t); // iterate over several substep sizes int k = -1; for (boolean loop = true; loop; ) { ++k; // modified midpoint integration with the current substep if ( ! tryStep(stepStart, y, stepSize, k, scale, fk[k], (k == 0) ? yMidDots[0] : diagonal[k-1], (k == 0) ? y1 : y1Diag[k-1], yTmp)) { // the stability check failed, we reduce the global step hNew = FastMath.abs(filterStep(stepSize * stabilityReduction, forward, false)); reject = true; loop = false; } else { // the substep was computed successfully if (k > 0) { // extrapolate the state at the end of the step // using last iteration data extrapolate(0, k, y1Diag, y1); rescale(y, y1, scale); // estimate the error at the end of the step. error = 0; for (int j = 0; j < mainSetDimension; ++j) { final double e = FastMath.abs(y1[j] - y1Diag[0][j]) / scale[j]; error += e * e; } error = FastMath.sqrt(error / mainSetDimension); if ((error > 1.0e15) || ((k > 1) && (error > maxError))) { // error is too big, we reduce the global step hNew = FastMath.abs(filterStep(stepSize * stabilityReduction, forward, false)); reject = true; loop = false; } else { maxError = FastMath.max(4 * error, 1.0); // compute optimal stepsize for this order final double exp = 1.0 / (2 * k + 1); double fac = stepControl2 / FastMath.pow(error / stepControl1, exp); final double pow = FastMath.pow(stepControl3, exp); fac = FastMath.max(pow / stepControl4, FastMath.min(1 / pow, fac)); optimalStep[k] = FastMath.abs(filterStep(stepSize * fac, forward, true)); costPerTimeUnit[k] = costPerStep[k] / optimalStep[k]; // check convergence switch (k - targetIter) { case -1 : if ((targetIter > 1) && ! previousRejected) { // check if we can stop iterations now if (error <= 1.0) { // convergence have been reached just before targetIter loop = false; } else { // estimate if there is a chance convergence will // be reached on next iteration, using the // asymptotic evolution of error final double ratio = ((double) sequence [targetIter] * sequence[targetIter + 1]) / (sequence[0] * sequence[0]); if (error > ratio * ratio) { // we don't expect to converge on next iteration // we reject the step immediately and reduce order reject = true; loop = false; targetIter = k; if ((targetIter > 1) && (costPerTimeUnit[targetIter-1] < orderControl1 * costPerTimeUnit[targetIter])) { --targetIter; } hNew = optimalStep[targetIter]; } } } break; case 0: if (error <= 1.0) { // convergence has been reached exactly at targetIter loop = false; } else { // estimate if there is a chance convergence will // be reached on next iteration, using the // asymptotic evolution of error final double ratio = ((double) sequence[k+1]) / sequence[0]; if (error > ratio * ratio) { // we don't expect to converge on next iteration // we reject the step immediately reject = true; loop = false; if ((targetIter > 1) && (costPerTimeUnit[targetIter-1] < orderControl1 * costPerTimeUnit[targetIter])) { --targetIter; } hNew = optimalStep[targetIter]; } } break; case 1 : if (error > 1.0) { reject = true; if ((targetIter > 1) && (costPerTimeUnit[targetIter-1] < orderControl1 * costPerTimeUnit[targetIter])) { --targetIter; } hNew = optimalStep[targetIter]; } loop = false; break; default : if ((firstTime || isLastStep) && (error <= 1.0)) { loop = false; } break; } } } } } if (! reject) { // derivatives at end of step computeDerivatives(stepStart + stepSize, y1, yDot1); } // dense output handling double hInt = getMaxStep(); if (denseOutput && ! reject) { // extrapolate state at middle point of the step for (int j = 1; j <= k; ++j) { extrapolate(0, j, diagonal, yMidDots[0]); } final int mu = 2 * k - mudif + 3; for (int l = 0; l < mu; ++l) { // derivative at middle point of the step final int l2 = l / 2; double factor = FastMath.pow(0.5 * sequence[l2], l); int middleIndex = fk[l2].length / 2; for (int i = 0; i < y0.length; ++i) { yMidDots[l+1][i] = factor * fk[l2][middleIndex + l][i]; } for (int j = 1; j <= k - l2; ++j) { factor = FastMath.pow(0.5 * sequence[j + l2], l); middleIndex = fk[l2+j].length / 2; for (int i = 0; i < y0.length; ++i) { diagonal[j-1][i] = factor * fk[l2+j][middleIndex+l][i]; } extrapolate(l2, j, diagonal, yMidDots[l+1]); } for (int i = 0; i < y0.length; ++i) { yMidDots[l+1][i] *= stepSize; } // compute centered differences to evaluate next derivatives for (int j = (l + 1) / 2; j <= k; ++j) { for (int m = fk[j].length - 1; m >= 2 * (l + 1); --m) { for (int i = 0; i < y0.length; ++i) { fk[j][m][i] -= fk[j][m-2][i]; } } } } if (mu >= 0) { // estimate the dense output coefficients final GraggBulirschStoerStepInterpolator gbsInterpolator = (GraggBulirschStoerStepInterpolator) interpolator; gbsInterpolator.computeCoefficients(mu, stepSize); if (useInterpolationError) { // use the interpolation error to limit stepsize final double interpError = gbsInterpolator.estimateError(scale); hInt = FastMath.abs(stepSize / FastMath.max(FastMath.pow(interpError, 1.0 / (mu+4)), 0.01)); if (interpError > 10.0) { hNew = hInt; reject = true; } } } } if (! reject) { // Discrete events handling interpolator.storeTime(stepStart + stepSize); stepStart = acceptStep(interpolator, y1, yDot1, t); // prepare next step interpolator.storeTime(stepStart); System.arraycopy(y1, 0, y, 0, y0.length); System.arraycopy(yDot1, 0, yDot0, 0, y0.length); firstStepAlreadyComputed = true; int optimalIter; if (k == 1) { optimalIter = 2; if (previousRejected) { optimalIter = 1; } } else if (k <= targetIter) { optimalIter = k; if (costPerTimeUnit[k-1] < orderControl1 * costPerTimeUnit[k]) { optimalIter = k-1; } else if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1]) { optimalIter = FastMath.min(k+1, sequence.length - 2); } } else { optimalIter = k - 1; if ((k > 2) && (costPerTimeUnit[k-2] < orderControl1 * costPerTimeUnit[k-1])) { optimalIter = k - 2; } if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[optimalIter]) { optimalIter = FastMath.min(k, sequence.length - 2); } } if (previousRejected) { // after a rejected step neither order nor stepsize // should increase targetIter = FastMath.min(optimalIter, k); hNew = FastMath.min(FastMath.abs(stepSize), optimalStep[targetIter]); } else { // stepsize control if (optimalIter <= k) { hNew = optimalStep[optimalIter]; } else { if ((k < targetIter) && (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1])) { hNew = filterStep(optimalStep[k] * costPerStep[optimalIter+1] / costPerStep[k], forward, false); } else { hNew = filterStep(optimalStep[k] * costPerStep[optimalIter] / costPerStep[k], forward, false); } } targetIter = optimalIter; } newStep = true; } hNew = FastMath.min(hNew, hInt); if (! forward) { hNew = -hNew; } firstTime = false; if (reject) { isLastStep = false; previousRejected = true; } else { previousRejected = false; } } while (!isLastStep); final double stopTime = stepStart; resetInternalState(); return stopTime; } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.ja100644 1750 1750 33340 11532241246 32413 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.nonstiff; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.linear.Array2DRowFieldMatrix; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.DefaultFieldMatrixChangingVisitor; import org.apache.commons.math.linear.FieldDecompositionSolver; import org.apache.commons.math.linear.FieldLUDecompositionImpl; import org.apache.commons.math.linear.FieldMatrix; import org.apache.commons.math.linear.MatrixUtils; /** Transformer to Nordsieck vectors for Adams integrators. *

                      This class i used by {@link AdamsBashforthIntegrator Adams-Bashforth} and * {@link AdamsMoultonIntegrator Adams-Moulton} integrators to convert between * classical representation with several previous first derivatives and Nordsieck * representation with higher order scaled derivatives.

                      * *

                      We define scaled derivatives si(n) at step n as: *

                       * s1(n) = h y'n for first derivative
                       * s2(n) = h2/2 y''n for second derivative
                       * s3(n) = h3/6 y'''n for third derivative
                       * ...
                       * sk(n) = hk/k! y(k)n for kth derivative
                       * 

                      * *

                      With the previous definition, the classical representation of multistep methods * uses first derivatives only, i.e. it handles yn, s1(n) and * qn where qn is defined as: *

                       *   qn = [ s1(n-1) s1(n-2) ... s1(n-(k-1)) ]T
                       * 
                      * (we omit the k index in the notation for clarity).

                      * *

                      Another possible representation uses the Nordsieck vector with * higher degrees scaled derivatives all taken at the same step, i.e it handles yn, * s1(n) and rn) where rn is defined as: *

                       * rn = [ s2(n), s3(n) ... sk(n) ]T
                       * 
                      * (here again we omit the k index in the notation for clarity) *

                      * *

                      Taylor series formulas show that for any index offset i, s1(n-i) can be * computed from s1(n), s2(n) ... sk(n), the formula being exact * for degree k polynomials. *

                       * s1(n-i) = s1(n) + ∑j j (-i)j-1 sj(n)
                       * 
                      * The previous formula can be used with several values for i to compute the transform between * classical representation and Nordsieck vector at step end. The transform between rn * and qn resulting from the Taylor series formulas above is: *
                       * qn = s1(n) u + P rn
                       * 
                      * where u is the [ 1 1 ... 1 ]T vector and P is the (k-1)×(k-1) matrix built * with the j (-i)j-1 terms: *
                       *        [  -2   3   -4    5  ... ]
                       *        [  -4  12  -32   80  ... ]
                       *   P =  [  -6  27 -108  405  ... ]
                       *        [  -8  48 -256 1280  ... ]
                       *        [          ...           ]
                       * 

                      * *

                      Changing -i into +i in the formula above can be used to compute a similar transform between * classical representation and Nordsieck vector at step start. The resulting matrix is simply * the absolute value of matrix P.

                      * *

                      For {@link AdamsBashforthIntegrator Adams-Bashforth} method, the Nordsieck vector * at step n+1 is computed from the Nordsieck vector at step n as follows: *

                        *
                      • yn+1 = yn + s1(n) + uT rn
                      • *
                      • s1(n+1) = h f(tn+1, yn+1)
                      • *
                      • rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                      • *
                      * where A is a rows shifting matrix (the lower left part is an identity matrix): *
                       *        [ 0 0   ...  0 0 | 0 ]
                       *        [ ---------------+---]
                       *        [ 1 0   ...  0 0 | 0 ]
                       *    A = [ 0 1   ...  0 0 | 0 ]
                       *        [       ...      | 0 ]
                       *        [ 0 0   ...  1 0 | 0 ]
                       *        [ 0 0   ...  0 1 | 0 ]
                       * 

                      * *

                      For {@link AdamsMoultonIntegrator Adams-Moulton} method, the predicted Nordsieck vector * at step n+1 is computed from the Nordsieck vector at step n as follows: *

                        *
                      • Yn+1 = yn + s1(n) + uT rn
                      • *
                      • S1(n+1) = h f(tn+1, Yn+1)
                      • *
                      • Rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                      • *
                      * From this predicted vector, the corrected vector is computed as follows: *
                        *
                      • yn+1 = yn + S1(n+1) + [ -1 +1 -1 +1 ... ±1 ] rn+1
                      • *
                      • s1(n+1) = h f(tn+1, yn+1)
                      • *
                      • rn+1 = Rn+1 + (s1(n+1) - S1(n+1)) P-1 u
                      • *
                      * where the upper case Yn+1, S1(n+1) and Rn+1 represent the * predicted states whereas the lower case yn+1, sn+1 and rn+1 * represent the corrected states.

                      * *

                      We observe that both methods use similar update formulas. In both cases a P-1u * vector and a P-1 A P matrix are used that do not depend on the state, * they only depend on k. This class handles these transformations.

                      * * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $ * @since 2.0 */ public class AdamsNordsieckTransformer { /** Cache for already computed coefficients. */ private static final Map CACHE = new HashMap(); /** Initialization matrix for the higher order derivatives wrt y'', y''' ... */ private final Array2DRowRealMatrix initialization; /** Update matrix for the higher order derivatives h2/2y'', h3/6 y''' ... */ private final Array2DRowRealMatrix update; /** Update coefficients of the higher order derivatives wrt y'. */ private final double[] c1; /** Simple constructor. * @param nSteps number of steps of the multistep method * (excluding the one being computed) */ private AdamsNordsieckTransformer(final int nSteps) { // compute exact coefficients FieldMatrix bigP = buildP(nSteps); FieldDecompositionSolver pSolver = new FieldLUDecompositionImpl(bigP).getSolver(); BigFraction[] u = new BigFraction[nSteps]; Arrays.fill(u, BigFraction.ONE); BigFraction[] bigC1 = pSolver.solve(u); // update coefficients are computed by combining transform from // Nordsieck to multistep, then shifting rows to represent step advance // then applying inverse transform BigFraction[][] shiftedP = bigP.getData(); for (int i = shiftedP.length - 1; i > 0; --i) { // shift rows shiftedP[i] = shiftedP[i - 1]; } shiftedP[0] = new BigFraction[nSteps]; Arrays.fill(shiftedP[0], BigFraction.ZERO); FieldMatrix bigMSupdate = pSolver.solve(new Array2DRowFieldMatrix(shiftedP, false)); // initialization coefficients, computed from a R matrix = abs(P) bigP.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor(BigFraction.ZERO) { /** {@inheritDoc} */ @Override public BigFraction visit(int row, int column, BigFraction value) { return ((column & 0x1) == 0x1) ? value : value.negate(); } }); FieldMatrix bigRInverse = new FieldLUDecompositionImpl(bigP).getSolver().getInverse(); // convert coefficients to double initialization = MatrixUtils.bigFractionMatrixToRealMatrix(bigRInverse); update = MatrixUtils.bigFractionMatrixToRealMatrix(bigMSupdate); c1 = new double[nSteps]; for (int i = 0; i < nSteps; ++i) { c1[i] = bigC1[i].doubleValue(); } } /** Get the Nordsieck transformer for a given number of steps. * @param nSteps number of steps of the multistep method * (excluding the one being computed) * @return Nordsieck transformer for the specified number of steps */ public static AdamsNordsieckTransformer getInstance(final int nSteps) { synchronized(CACHE) { AdamsNordsieckTransformer t = CACHE.get(nSteps); if (t == null) { t = new AdamsNordsieckTransformer(nSteps); CACHE.put(nSteps, t); } return t; } } /** Get the number of steps of the method * (excluding the one being computed). * @return number of steps of the method * (excluding the one being computed) */ public int getNSteps() { return c1.length; } /** Build the P matrix. *

                      The P matrix general terms are shifted j (-i)j-1 terms: *

                           *        [  -2   3   -4    5  ... ]
                           *        [  -4  12  -32   80  ... ]
                           *   P =  [  -6  27 -108  405  ... ]
                           *        [  -8  48 -256 1280  ... ]
                           *        [          ...           ]
                           * 

                      * @param nSteps number of steps of the multistep method * (excluding the one being computed) * @return P matrix */ private FieldMatrix buildP(final int nSteps) { final BigFraction[][] pData = new BigFraction[nSteps][nSteps]; for (int i = 0; i < pData.length; ++i) { // build the P matrix elements from Taylor series formulas final BigFraction[] pI = pData[i]; final int factor = -(i + 1); int aj = factor; for (int j = 0; j < pI.length; ++j) { pI[j] = new BigFraction(aj * (j + 2)); aj *= factor; } } return new Array2DRowFieldMatrix(pData, false); } /** Initialize the high order scaled derivatives at step start. * @param first first scaled derivative at step start * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) * will be modified * @return high order derivatives at step start */ public Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, final double[][] multistep) { for (int i = 0; i < multistep.length; ++i) { final double[] msI = multistep[i]; for (int j = 0; j < first.length; ++j) { msI[j] -= first[j]; } } return initialization.multiply(new Array2DRowRealMatrix(multistep, false)); } /** Update the high order scaled derivatives for Adams integrators (phase 1). *

                      The complete update of high order derivatives has a form similar to: *

                           * rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                           * 
                      * this method computes the P-1 A P rn part.

                      * @param highOrder high order scaled derivatives * (h2/2 y'', ... hk/k! y(k)) * @return updated high order derivatives * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix) */ public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) { return update.multiply(highOrder); } /** Update the high order scaled derivatives Adams integrators (phase 2). *

                      The complete update of high order derivatives has a form similar to: *

                           * rn+1 = (s1(n) - s1(n+1)) P-1 u + P-1 A P rn
                           * 
                      * this method computes the (s1(n) - s1(n+1)) P-1 u part.

                      *

                      Phase 1 of the update must already have been performed.

                      * @param start first order scaled derivatives at step start * @param end first order scaled derivatives at step end * @param highOrder high order scaled derivatives, will be modified * (h2/2 y'', ... hk/k! y(k)) * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix) */ public void updateHighOrderDerivativesPhase2(final double[] start, final double[] end, final Array2DRowRealMatrix highOrder) { final double[][] data = highOrder.getDataRef(); for (int i = 0; i < data.length; ++i) { final double[] dataI = data[i]; final double c1I = c1[i]; for (int j = 0; j < dataI.length; ++j) { dataI[j] += c1I * (start[j] - end[j]); } } } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/SecondOrderDifferentialEquations.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/SecondOrderDifferentialEquations.java100644 1750 1750 5603 11532241246 32400 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.DerivativeException; /** This interface represents a second order differential equations set. *

                      This interface should be implemented by all real second order * differential equation problems before they can be handled by the * integrators {@link SecondOrderIntegrator#integrate} method.

                      * *

                      A second order differential equations problem, as seen by an * integrator is the second time derivative d2Y/dt^2 of a * state vector Y, both being one dimensional * arrays. From the integrator point of view, this derivative depends * only on the current time t, on the state vector * Y and on the first time derivative of the state * vector.

                      * *

                      For real problems, the derivative depends also on parameters * that do not belong to the state vector (dynamical model constants * for example). These constants are completely outside of the scope * of this interface, the classes that implement it are allowed to * handle them as they want.

                      * * @see SecondOrderIntegrator * @see FirstOrderConverter * @see FirstOrderDifferentialEquations * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface SecondOrderDifferentialEquations { /** Get the dimension of the problem. * @return dimension of the problem */ int getDimension(); /** Get the current time derivative of the state vector. * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param yDot array containing the current value of the first derivative * of the state vector * @param yDDot placeholder array where to put the second time derivative * of the state vector * @throws DerivativeException this user-defined exception should be used if an error is * is triggered by user code */ void computeSecondDerivatives(double t, double[] y, double[] yDot, double[] yDDot) throws DerivativeException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/EventException.java100644 1750 1750 4515 11532241246 30230 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.events; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.Localizable; /** * This exception is made available to users to report * the error conditions that are triggered by {@link EventHandler} * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class EventException extends MathException { /** Serialization UID. */ private static final long serialVersionUID = -898215297400035290L; /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @deprecated as of 2.2 replaced by {@link #EventException(Localizable, Object...)} */ @Deprecated public EventException(final String specifier, final Object ... parts) { super(specifier, parts); } /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public EventException(final Localizable specifier, final Object ... parts) { super(specifier, parts); } /** * Create an exception with a given root cause. * @param cause the exception or error that caused this exception to be thrown */ public EventException(final Throwable cause) { super(cause); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/EventHandler.java100644 1750 1750 21774 11532241246 27675 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.events; /** This interface represents a handler for discrete events triggered * during ODE integration. * *

                      Some events can be triggered at discrete times as an ODE problem * is solved. This occurs for example when the integration process * should be stopped as some state is reached (G-stop facility) when the * precise date is unknown a priori, or when the derivatives have * discontinuities, or simply when the user wants to monitor some * states boundaries crossings. *

                      * *

                      These events are defined as occurring when a g * switching function sign changes.

                      * *

                      Since events are only problem-dependent and are triggered by the * independent time variable and the state vector, they can * occur at virtually any time, unknown in advance. The integrators will * take care to avoid sign changes inside the steps, they will reduce * the step size when such an event is detected in order to put this * event exactly at the end of the current step. This guarantees that * step interpolation (which always has a one step scope) is relevant * even in presence of discontinuities. This is independent from the * stepsize control provided by integrators that monitor the local * error (this event handling feature is available for all integrators, * including fixed step ones).

                      * * @version $Revision: 1067500 $ $Date: 2011-02-05 21:11:30 +0100 (sam. 05 févr. 2011) $ * @since 1.2 */ public interface EventHandler { /** Stop indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should be * stopped after the event ending the current step.

                      */ int STOP = 0; /** Reset state indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should * go on after the event ending the current step, with a new state * vector (which will be retrieved thanks to the {@link #resetState * resetState} method).

                      */ int RESET_STATE = 1; /** Reset derivatives indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should * go on after the event ending the current step, with a new derivatives * vector (which will be retrieved thanks to the {@link * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives} * method).

                      */ int RESET_DERIVATIVES = 2; /** Continue indicator. *

                      This value should be used as the return value of the {@link * #eventOccurred eventOccurred} method when the integration should go * on after the event ending the current step.

                      */ int CONTINUE = 3; /** Compute the value of the switching function. *

                      The discrete events are generated when the sign of this * switching function changes. The integrator will take care to change * the stepsize in such a way these events occur exactly at step boundaries. * The switching function must be continuous in its roots neighborhood * (but not necessarily smooth), as the integrator will need to find its * roots to locate precisely the events.

                      * * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @return value of the g switching function * @exception EventException if the switching function cannot be evaluated */ double g(double t, double[] y) throws EventException; /** Handle an event and choose what to do next. *

                      This method is called when the integrator has accepted a step * ending exactly on a sign change of the function, just before * the step handler itself is called (see below for scheduling). It * allows the user to update his internal data to acknowledge the fact * the event has been handled (for example setting a flag in the {@link * org.apache.commons.math.ode.FirstOrderDifferentialEquations * differential equations} to switch the derivatives computation in * case of discontinuity), or to direct the integrator to either stop * or continue integration, possibly with a reset state or derivatives.

                      * *
                        *
                      • if {@link #STOP} is returned, the step handler will be called * with the isLast flag of the {@link * org.apache.commons.math.ode.sampling.StepHandler#handleStep handleStep} * method set to true and the integration will be stopped,
                      • *
                      • if {@link #RESET_STATE} is returned, the {@link #resetState * resetState} method will be called once the step handler has * finished its task, and the integrator will also recompute the * derivatives,
                      • *
                      • if {@link #RESET_DERIVATIVES} is returned, the integrator * will recompute the derivatives, *
                      • if {@link #CONTINUE} is returned, no specific action will * be taken (apart from having called this method) and integration * will continue.
                      • *
                      * *

                      The scheduling between this method and the {@link * org.apache.commons.math.ode.sampling.StepHandler StepHandler} method {@link * org.apache.commons.math.ode.sampling.StepHandler#handleStep( * org.apache.commons.math.ode.sampling.StepInterpolator, boolean) * handleStep(interpolator, isLast)} is to call this method first and * handleStep afterwards. This scheduling allows the integrator to * pass true as the isLast parameter to the step * handler to make it aware the step will be the last one if this method * returns {@link #STOP}. As the interpolator may be used to navigate back * throughout the last step (as {@link * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} * does for example), user code called by this method and user * code called by step handlers may experience apparently out of order values * of the independent time variable. As an example, if the same user object * implements both this {@link EventHandler EventHandler} interface and the * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} * interface, a forward integration may call its * eventOccurred method with t = 10 first and call its * handleStep method with t = 9 afterwards. Such out of order * calls are limited to the size of the integration step for {@link * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and * to the size of the fixed step for {@link * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.

                      * * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param increasing if true, the value of the switching function increases * when times increases around event (note that increase is measured with respect * to physical time, not with respect to integration which may go backward in time) * @return indication of what the integrator should do next, this * value must be one of {@link #STOP}, {@link #RESET_STATE}, * {@link #RESET_DERIVATIVES} or {@link #CONTINUE} * @exception EventException if the event occurrence triggers an error */ int eventOccurred(double t, double[] y, boolean increasing) throws EventException; /** Reset the state prior to continue the integration. *

                      This method is called after the step handler has returned and * before the next step is started, but only when {@link * #eventOccurred} has itself returned the {@link #RESET_STATE} * indicator. It allows the user to reset the state vector for the * next step, without perturbing the step handler of the finishing * step. If the {@link #eventOccurred} never returns the {@link * #RESET_STATE} indicator, this function will never be called, and it is * safe to leave its body empty.

                      * * @param t current value of the independent time variable * @param y array containing the current value of the state vector * the new state should be put in the same array * @exception EventException if the state cannot be reseted */ void resetState(double t, double[] y) throws EventException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/package.html100644 1750 1750 6623 11532241246 26710 0ustarlucluc 0 0

                      This package provides classes to handle discrete events occurring during Ordinary Differential Equations integration.

                      Discrete events detection is based on switching functions. The user provides a simple {@link org.apache.commons.math.ode.events.EventHandler#g g(t, y)} function depending on the current time and state. The integrator will monitor the value of the function throughout integration range and will trigger the event when its sign changes. The magnitude of the value is almost irrelevant, it should however be continuous (but not necessarily smooth) for the sake of root finding. The steps are shortened as needed to ensure the events occur at step boundaries (even if the integrator is a fixed-step integrator).

                      When an event is triggered, several different options are available:

                      • integration can be stopped (this is called a G-stop facility),
                      • the state vector or the derivatives can be changed,
                      • or integration can simply go on.

                      The first case, G-stop, is the most common one. A typical use case is when an ODE must be solved up to some target state is reached, with a known value of the state but an unknown occurrence time. As an example, if we want to monitor a chemical reaction up to some predefined concentration for the first substance, we can use the following switching function setting:

                        public double g(double t, double[] y) {
                          return y[0] - targetConcentration;
                        }
                      
                        public int eventOccurred(double t, double[] y) {
                          return STOP;
                        }
                      

                      The second case, change state vector or derivatives is encountered when dealing with discontinuous dynamical models. A typical case would be the motion of a spacecraft when thrusters are fired for orbital maneuvers. The acceleration is smooth as long as no maneuver are performed, depending only on gravity, drag, third body attraction, radiation pressure. Firing a thruster introduces a discontinuity that must be handled appropriately by the integrator. In such a case, we would use a switching function setting similar to this:

                        public double g(double t, double[] y) {
                          return (t - tManeuverStart) * (t - tManeuverStop);
                        }
                      
                        public int eventOccurred(double t, double[] y) {
                          return RESET_DERIVATIVES;
                        }
                      

                      The third case is useful mainly for monitoring purposes, a simple example is:

                        public double g(double t, double[] y) {
                          return y[0] - y[1];
                        }
                      
                        public int eventOccurred(double t, double[] y) {
                          logger.log("y0(t) and y1(t) curves cross at t = " + t);
                          return CONTINUE;
                        }
                      

                      commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/EventState.java100644 1750 1750 42410 11532241246 27366 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.events; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.exception.MathInternalError; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** This class handles the state for one {@link EventHandler * event handler} during integration steps. * *

                      Each time the integrator proposes a step, the event handler * switching function should be checked. This class handles the state * of one handler during one integration step, with references to the * state at the end of the preceding step. This information is used to * decide if the handler should trigger an event or not during the * proposed step (and hence the step should be reduced to ensure the * event occurs at a bound rather than inside the step).

                      * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public class EventState { /** Event handler. */ private final EventHandler handler; /** Maximal time interval between events handler checks. */ private final double maxCheckInterval; /** Convergence threshold for event localization. */ private final double convergence; /** Upper limit in the iteration count for event localization. */ private final int maxIterationCount; /** Time at the beginning of the step. */ private double t0; /** Value of the events handler at the beginning of the step. */ private double g0; /** Simulated sign of g0 (we cheat when crossing events). */ private boolean g0Positive; /** Indicator of event expected during the step. */ private boolean pendingEvent; /** Occurrence time of the pending event. */ private double pendingEventTime; /** Occurrence time of the previous event. */ private double previousEventTime; /** Integration direction. */ private boolean forward; /** Variation direction around pending event. * (this is considered with respect to the integration direction) */ private boolean increasing; /** Next action indicator. */ private int nextAction; /** Simple constructor. * @param handler event handler * @param maxCheckInterval maximal time interval between switching * function checks (this interval prevents missing sign changes in * case the integration steps becomes very large) * @param convergence convergence threshold in the event time search * @param maxIterationCount upper limit of the iteration count in * the event time search */ public EventState(final EventHandler handler, final double maxCheckInterval, final double convergence, final int maxIterationCount) { this.handler = handler; this.maxCheckInterval = maxCheckInterval; this.convergence = FastMath.abs(convergence); this.maxIterationCount = maxIterationCount; // some dummy values ... t0 = Double.NaN; g0 = Double.NaN; g0Positive = true; pendingEvent = false; pendingEventTime = Double.NaN; previousEventTime = Double.NaN; increasing = true; nextAction = EventHandler.CONTINUE; } /** Get the underlying event handler. * @return underlying event handler */ public EventHandler getEventHandler() { return handler; } /** Get the maximal time interval between events handler checks. * @return maximal time interval between events handler checks */ public double getMaxCheckInterval() { return maxCheckInterval; } /** Get the convergence threshold for event localization. * @return convergence threshold for event localization */ public double getConvergence() { return convergence; } /** Get the upper limit in the iteration count for event localization. * @return upper limit in the iteration count for event localization */ public int getMaxIterationCount() { return maxIterationCount; } /** Reinitialize the beginning of the step. * @param interpolator valid for the current step * @exception EventException if the event handler * value cannot be evaluated at the beginning of the step */ public void reinitializeBegin(final StepInterpolator interpolator) throws EventException { try { // excerpt from MATH-421 issue: // If an ODE solver is setup with an EventHandler that return STOP // when the even is triggered, the integrator stops (which is exactly // the expected behavior). If however the user want to restart the // solver from the final state reached at the event with the same // configuration (expecting the event to be triggered again at a // later time), then the integrator may fail to start. It can get stuck // at the previous event. // The use case for the bug MATH-421 is fairly general, so events occurring // less than epsilon after the solver start in the first step should be ignored, // where epsilon is the convergence threshold of the event. The sign of the g // function should be evaluated after this initial ignore zone, not exactly at // beginning (if there are no event at the very beginning g(t0) and g(t0+epsilon) // have the same sign, so this does not hurt ; if there is an event at the very // beginning, g(t0) and g(t0+epsilon) have opposite signs and we want to start // with the second one. Of course, the sign of epsilon depend on the integration // direction (forward or backward). This explains what is done below. final double ignoreZone = interpolator.isForward() ? getConvergence() : -getConvergence(); t0 = interpolator.getPreviousTime() + ignoreZone; interpolator.setInterpolatedTime(t0); g0 = handler.g(t0, interpolator.getInterpolatedState()); if (g0 == 0) { // extremely rare case: there is a zero EXACTLY at end of ignore zone // we will use the opposite of sign at step beginning to force ignoring this zero final double tStart = interpolator.getPreviousTime(); interpolator.setInterpolatedTime(tStart); g0Positive = handler.g(tStart, interpolator.getInterpolatedState()) <= 0; } else { g0Positive = g0 >= 0; } } catch (DerivativeException mue) { throw new EventException(mue); } } /** Evaluate the impact of the proposed step on the event handler. * @param interpolator step interpolator for the proposed step * @return true if the event handler triggers an event before * the end of the proposed step * @exception DerivativeException if the interpolator fails to * compute the switching function somewhere within the step * @exception EventException if the switching function * cannot be evaluated * @exception ConvergenceException if an event cannot be located */ public boolean evaluateStep(final StepInterpolator interpolator) throws DerivativeException, EventException, ConvergenceException { try { forward = interpolator.isForward(); final double t1 = interpolator.getCurrentTime(); if (FastMath.abs(t1 - t0) < convergence) { // we cannot do anything on such a small step, don't trigger any events return false; } final double start = forward ? (t0 + convergence) : t0 - convergence; final double dt = t1 - start; final int n = FastMath.max(1, (int) FastMath.ceil(FastMath.abs(dt) / maxCheckInterval)); final double h = dt / n; double ta = t0; double ga = g0; for (int i = 0; i < n; ++i) { // evaluate handler value at the end of the substep final double tb = start + (i + 1) * h; interpolator.setInterpolatedTime(tb); final double gb = handler.g(tb, interpolator.getInterpolatedState()); // check events occurrence if (g0Positive ^ (gb >= 0)) { // there is a sign change: an event is expected during this step // variation direction, with respect to the integration direction increasing = gb >= ga; final UnivariateRealFunction f = new UnivariateRealFunction() { public double value(final double t) { try { interpolator.setInterpolatedTime(t); return handler.g(t, interpolator.getInterpolatedState()); } catch (DerivativeException e) { throw new EmbeddedDerivativeException(e); } catch (EventException e) { throw new EmbeddedEventException(e); } } }; final BrentSolver solver = new BrentSolver(convergence); if (ga * gb >= 0) { // this is a corner case: // - there was an event near ta, // - there is another event between ta and tb // - when ta was computed, convergence was reached on the "wrong side" of the interval // this implies that the real sign of ga is the same as gb, so we need to slightly // shift ta to make sure ga and gb get opposite signs and the solver won't complain // about bracketing final double epsilon = (forward ? 0.25 : -0.25) * convergence; for (int k = 0; (k < 4) && (ga * gb > 0); ++k) { ta += epsilon; try { ga = f.value(ta); } catch (FunctionEvaluationException ex) { throw new DerivativeException(ex); } } if (ga * gb > 0) { // this should never happen throw new MathInternalError(); } } final double root; try { root = (ta <= tb) ? solver.solve(maxIterationCount, f, ta, tb) : solver.solve(maxIterationCount, f, tb, ta); } catch (FunctionEvaluationException ex) { throw new DerivativeException(ex); } if ((!Double.isNaN(previousEventTime)) && (FastMath.abs(root - ta) <= convergence) && (FastMath.abs(root - previousEventTime) <= convergence)) { // we have either found nothing or found (again ?) a past event, we simply ignore it ta = tb; ga = gb; } else if (Double.isNaN(previousEventTime) || (FastMath.abs(previousEventTime - root) > convergence)) { pendingEventTime = root; pendingEvent = true; return true; } else { // no sign change: there is no event for now ta = tb; ga = gb; } } else { // no sign change: there is no event for now ta = tb; ga = gb; } } // no event during the whole step pendingEvent = false; pendingEventTime = Double.NaN; return false; } catch (EmbeddedDerivativeException ede) { throw ede.getDerivativeException(); } catch (EmbeddedEventException eee) { throw eee.getEventException(); } } /** Get the occurrence time of the event triggered in the current step. * @return occurrence time of the event triggered in the current * step or positive infinity if no events are triggered */ public double getEventTime() { return pendingEvent ? pendingEventTime : Double.POSITIVE_INFINITY; } /** Acknowledge the fact the step has been accepted by the integrator. * @param t value of the independent time variable at the * end of the step * @param y array containing the current value of the state vector * at the end of the step * @exception EventException if the value of the event * handler cannot be evaluated */ public void stepAccepted(final double t, final double[] y) throws EventException { t0 = t; g0 = handler.g(t, y); if (pendingEvent && (FastMath.abs(pendingEventTime - t) <= convergence)) { // force the sign to its value "just after the event" previousEventTime = t; g0Positive = increasing; nextAction = handler.eventOccurred(t, y, !(increasing ^ forward)); } else { g0Positive = g0 >= 0; nextAction = EventHandler.CONTINUE; } } /** Check if the integration should be stopped at the end of the * current step. * @return true if the integration should be stopped */ public boolean stop() { return nextAction == EventHandler.STOP; } /** Let the event handler reset the state if it wants. * @param t value of the independent time variable at the * beginning of the next step * @param y array were to put the desired state vector at the beginning * of the next step * @return true if the integrator should reset the derivatives too * @exception EventException if the state cannot be reseted by the event * handler */ public boolean reset(final double t, final double[] y) throws EventException { if (!(pendingEvent && (FastMath.abs(pendingEventTime - t) <= convergence))) { return false; } if (nextAction == EventHandler.RESET_STATE) { handler.resetState(t, y); } pendingEvent = false; pendingEventTime = Double.NaN; return (nextAction == EventHandler.RESET_STATE) || (nextAction == EventHandler.RESET_DERIVATIVES); } /** Local exception for embedding DerivativeException. */ private static class EmbeddedDerivativeException extends RuntimeException { /** Serializable UID. */ private static final long serialVersionUID = 3574188382434584610L; /** Embedded exception. */ private final DerivativeException derivativeException; /** Simple constructor. * @param derivativeException embedded exception */ public EmbeddedDerivativeException(final DerivativeException derivativeException) { this.derivativeException = derivativeException; } /** Get the embedded exception. * @return embedded exception */ public DerivativeException getDerivativeException() { return derivativeException; } } /** Local exception for embedding EventException. */ private static class EmbeddedEventException extends RuntimeException { /** Serializable UID. */ private static final long serialVersionUID = -1337749250090455474L; /** Embedded exception. */ private final EventException eventException; /** Simple constructor. * @param eventException embedded exception */ public EmbeddedEventException(final EventException eventException) { this.eventException = eventException; } /** Get the embedded exception. * @return embedded exception */ public EventException getEventException() { return eventException; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/events/CombinedEventsManager.java100644 1750 1750 21114 11532241246 31502 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.events; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.ode.IntegratorException; import org.apache.commons.math.ode.sampling.StepInterpolator; /** This class manages several {@link EventHandler event handlers} during integration. * * @see EventHandler * @see EventState * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 * @deprecated as of 2.2, this class is not used anymore */ @Deprecated public class CombinedEventsManager { /** Events states. */ private final List states; /** First active event. */ private EventState first; /** Initialization indicator. */ private boolean initialized; /** Simple constructor. * Create an empty manager */ public CombinedEventsManager() { states = new ArrayList(); first = null; initialized = false; } /** Add an events handler. * @param handler event handler * @param maxCheckInterval maximal time interval between events * checks (this interval prevents missing sign changes in * case the integration steps becomes very large) * @param convergence convergence threshold in the event time search * @param maxIterationCount upper limit of the iteration count in * the event time search * @see #getEventsHandlers() * @see #clearEventsHandlers() */ public void addEventHandler(final EventHandler handler, final double maxCheckInterval, final double convergence, final int maxIterationCount) { states.add(new EventState(handler, maxCheckInterval, convergence, maxIterationCount)); } /** Get all the events handlers that have been added to the manager. * @return an unmodifiable collection of the added event handlers * @see #addEventHandler(EventHandler, double, double, int) * @see #clearEventsHandlers() * @see #getEventsStates() */ public Collection getEventsHandlers() { final List list = new ArrayList(); for (EventState state : states) { list.add(state.getEventHandler()); } return Collections.unmodifiableCollection(list); } /** Remove all the events handlers that have been added to the manager. * @see #addEventHandler(EventHandler, double, double, int) * @see #getEventsHandlers() */ public void clearEventsHandlers() { states.clear(); } /** Get all the events state wrapping the handlers that have been added to the manager. * @return a collection of the events states * @see #getEventsHandlers() */ public Collection getEventsStates() { return states; } /** Check if the manager does not manage any event handlers. * @return true if manager is empty */ public boolean isEmpty() { return states.isEmpty(); } /** Evaluate the impact of the proposed step on all managed * event handlers. * @param interpolator step interpolator for the proposed step * @return true if at least one event handler triggers an event * before the end of the proposed step (this implies the step should * be rejected) * @exception DerivativeException if the interpolator fails to * compute the function somewhere within the step * @exception IntegratorException if an event cannot be located */ public boolean evaluateStep(final StepInterpolator interpolator) throws DerivativeException, IntegratorException { try { first = null; if (states.isEmpty()) { // there is nothing to do, return now to avoid setting the // interpolator time (and hence avoid unneeded calls to the // user function due to interpolator finalization) return false; } if (! initialized) { // initialize the events states for (EventState state : states) { state.reinitializeBegin(interpolator); } initialized = true; } // check events occurrence for (EventState state : states) { if (state.evaluateStep(interpolator)) { if (first == null) { first = state; } else { if (interpolator.isForward()) { if (state.getEventTime() < first.getEventTime()) { first = state; } } else { if (state.getEventTime() > first.getEventTime()) { first = state; } } } } } return first != null; } catch (EventException se) { final Throwable cause = se.getCause(); if ((cause != null) && (cause instanceof DerivativeException)) { throw (DerivativeException) cause; } throw new IntegratorException(se); } catch (ConvergenceException ce) { throw new IntegratorException(ce); } } /** Get the occurrence time of the first event triggered in the * last evaluated step. * @return occurrence time of the first event triggered in the last * evaluated step, or
                      Double.NaN
                      if no event is * triggered */ public double getEventTime() { return (first == null) ? Double.NaN : first.getEventTime(); } /** Inform the event handlers that the step has been accepted * by the integrator. * @param t value of the independent time variable at the * end of the step * @param y array containing the current value of the state vector * at the end of the step * @exception IntegratorException if the value of one of the * events states cannot be evaluated */ public void stepAccepted(final double t, final double[] y) throws IntegratorException { try { for (EventState state : states) { state.stepAccepted(t, y); } } catch (EventException se) { throw new IntegratorException(se); } } /** Check if the integration should be stopped at the end of the * current step. * @return true if the integration should be stopped */ public boolean stop() { for (EventState state : states) { if (state.stop()) { return true; } } return false; } /** Let the event handlers reset the state if they want. * @param t value of the independent time variable at the * beginning of the next step * @param y array were to put the desired state vector at the beginning * of the next step * @return true if the integrator should reset the derivatives too * @exception IntegratorException if one of the events states * that should reset the state fails to do it */ public boolean reset(final double t, final double[] y) throws IntegratorException { try { boolean resetDerivatives = false; for (EventState state : states) { if (state.reset(t, y)) { resetDerivatives = true; } } return resetDerivatives; } catch (EventException se) { throw new IntegratorException(se); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/DerivativeException.java100644 1750 1750 4402 11532241246 27740 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * This exception is made available to users to report * the error conditions that are triggered while computing * the differential equations. * @version $Revision: 1072413 $ $Date: 2011-02-19 19:59:39 +0100 (sam. 19 févr. 2011) $ * @since 1.2 */ public class DerivativeException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = 5666710788967425123L; /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) */ public DerivativeException(final String specifier, final Object ... parts) { this(new DummyLocalizable(specifier), parts); } /** Simple constructor. * Build an exception by translating and formating a message * @param specifier format specifier (to be translated) * @param parts to insert in the format (no translation) * @since 2.2 */ public DerivativeException(final Localizable specifier, final Object ... parts) { super(specifier, parts); } /** Build an instance from an underlying cause. * @param cause cause for the exception */ public DerivativeException(final Throwable cause) { super(cause); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/MultistepIntegrator.java100644 1750 1750 37663 11532241246 30043 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.linear.RealMatrix; import org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator; import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** * This class is the base class for multistep integrators for Ordinary * Differential Equations. *

                      We define scaled derivatives si(n) at step n as: *

                       * s1(n) = h y'n for first derivative
                       * s2(n) = h2/2 y''n for second derivative
                       * s3(n) = h3/6 y'''n for third derivative
                       * ...
                       * sk(n) = hk/k! y(k)n for kth derivative
                       * 

                      *

                      Rather than storing several previous steps separately, this implementation uses * the Nordsieck vector with higher degrees scaled derivatives all taken at the same * step (yn, s1(n) and rn) where rn is defined as: *

                       * rn = [ s2(n), s3(n) ... sk(n) ]T
                       * 
                      * (we omit the k index in the notation for clarity)

                      *

                      * Multistep integrators with Nordsieck representation are highly sensitive to * large step changes because when the step is multiplied by a factor a, the * kth component of the Nordsieck vector is multiplied by ak * and the last components are the least accurate ones. The default max growth * factor is therefore set to a quite low value: 21/order. *

                      * * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator { /** First scaled derivative (h y'). */ protected double[] scaled; /** Nordsieck matrix of the higher scaled derivatives. *

                      (h2/2 y'', h3/6 y''' ..., hk/k! y(k))

                      */ protected Array2DRowRealMatrix nordsieck; /** Starter integrator. */ private FirstOrderIntegrator starter; /** Number of steps of the multistep method (excluding the one being computed). */ private final int nSteps; /** Stepsize control exponent. */ private double exp; /** Safety factor for stepsize control. */ private double safety; /** Minimal reduction factor for stepsize control. */ private double minReduction; /** Maximal growth factor for stepsize control. */ private double maxGrowth; /** * Build a multistep integrator with the given stepsize bounds. *

                      The default starter integrator is set to the {@link * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with * some defaults settings.

                      *

                      * The default max growth factor is set to a quite low value: 21/order. *

                      * @param name name of the method * @param nSteps number of steps of the multistep method * (excluding the one being computed) * @param order order of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param scalAbsoluteTolerance allowed absolute error * @param scalRelativeTolerance allowed relative error */ protected MultistepIntegrator(final String name, final int nSteps, final int order, final double minStep, final double maxStep, final double scalAbsoluteTolerance, final double scalRelativeTolerance) { super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); if (nSteps <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INTEGRATION_METHOD_NEEDS_AT_LEAST_ONE_PREVIOUS_POINT, name); } starter = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); this.nSteps = nSteps; exp = -1.0 / order; // set the default values of the algorithm control parameters setSafety(0.9); setMinReduction(0.2); setMaxGrowth(FastMath.pow(2.0, -exp)); } /** * Build a multistep integrator with the given stepsize bounds. *

                      The default starter integrator is set to the {@link * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with * some defaults settings.

                      *

                      * The default max growth factor is set to a quite low value: 21/order. *

                      * @param name name of the method * @param nSteps number of steps of the multistep method * (excluding the one being computed) * @param order order of the method * @param minStep minimal step (must be positive even for backward * integration), the last step can be smaller than this * @param maxStep maximal step (must be positive even for backward * integration) * @param vecAbsoluteTolerance allowed absolute error * @param vecRelativeTolerance allowed relative error */ protected MultistepIntegrator(final String name, final int nSteps, final int order, final double minStep, final double maxStep, final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) { super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); starter = new DormandPrince853Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); this.nSteps = nSteps; exp = -1.0 / order; // set the default values of the algorithm control parameters setSafety(0.9); setMinReduction(0.2); setMaxGrowth(FastMath.pow(2.0, -exp)); } /** * Get the starter integrator. * @return starter integrator */ public ODEIntegrator getStarterIntegrator() { return starter; } /** * Set the starter integrator. *

                      The various step and event handlers for this starter integrator * will be managed automatically by the multi-step integrator. Any * user configuration for these elements will be cleared before use.

                      * @param starterIntegrator starter integrator */ public void setStarterIntegrator(FirstOrderIntegrator starterIntegrator) { this.starter = starterIntegrator; } /** Start the integration. *

                      This method computes one step using the underlying starter integrator, * and initializes the Nordsieck vector at step start. The starter integrator * purpose is only to establish initial conditions, it does not really change * time by itself. The top level multistep integrator remains in charge of * handling time propagation and events handling as it will starts its own * computation right from the beginning. In a sense, the starter integrator * can be seen as a dummy one and so it will never trigger any user event nor * call any user step handler.

                      * @param t0 initial time * @param y0 initial value of the state vector at t0 * @param t target time for the integration * (can be set to a value smaller than t0 for backward integration) * @throws IntegratorException if the integrator cannot perform integration * @throws DerivativeException this exception is propagated to the caller if * the underlying user function triggers one */ protected void start(final double t0, final double[] y0, final double t) throws DerivativeException, IntegratorException { // make sure NO user event nor user step handler is triggered, // this is the task of the top level integrator, not the task // of the starter integrator starter.clearEventHandlers(); starter.clearStepHandlers(); // set up one specific step handler to extract initial Nordsieck vector starter.addStepHandler(new NordsieckInitializer(y0.length)); // start integration, expecting a InitializationCompletedMarkerException try { starter.integrate(new CountingDifferentialEquations(y0.length), t0, y0, t, new double[y0.length]); } catch (DerivativeException mue) { if (!(mue instanceof InitializationCompletedMarkerException)) { // this is not the expected nominal interruption of the start integrator throw mue; } } // remove the specific step handler starter.clearStepHandlers(); } /** Initialize the high order scaled derivatives at step start. * @param first first scaled derivative at step start * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) * will be modified * @return high order scaled derivatives at step start */ protected abstract Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, final double[][] multistep); /** Get the minimal reduction factor for stepsize control. * @return minimal reduction factor */ public double getMinReduction() { return minReduction; } /** Set the minimal reduction factor for stepsize control. * @param minReduction minimal reduction factor */ public void setMinReduction(final double minReduction) { this.minReduction = minReduction; } /** Get the maximal growth factor for stepsize control. * @return maximal growth factor */ public double getMaxGrowth() { return maxGrowth; } /** Set the maximal growth factor for stepsize control. * @param maxGrowth maximal growth factor */ public void setMaxGrowth(final double maxGrowth) { this.maxGrowth = maxGrowth; } /** Get the safety factor for stepsize control. * @return safety factor */ public double getSafety() { return safety; } /** Set the safety factor for stepsize control. * @param safety safety factor */ public void setSafety(final double safety) { this.safety = safety; } /** Compute step grow/shrink factor according to normalized error. * @param error normalized error of the current step * @return grow/shrink factor for next step */ protected double computeStepGrowShrinkFactor(final double error) { return FastMath.min(maxGrowth, FastMath.max(minReduction, safety * FastMath.pow(error, exp))); } /** Transformer used to convert the first step to Nordsieck representation. */ public static interface NordsieckTransformer { /** Initialize the high order scaled derivatives at step start. * @param first first scaled derivative at step start * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) * will be modified * @return high order derivatives at step start */ RealMatrix initializeHighOrderDerivatives(double[] first, double[][] multistep); } /** Specialized step handler storing the first step. */ private class NordsieckInitializer implements StepHandler { /** Problem dimension. */ private final int n; /** Simple constructor. * @param n problem dimension */ public NordsieckInitializer(final int n) { this.n = n; } /** {@inheritDoc} */ public void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException { final double prev = interpolator.getPreviousTime(); final double curr = interpolator.getCurrentTime(); stepStart = prev; stepSize = (curr - prev) / (nSteps + 1); // compute the first scaled derivative interpolator.setInterpolatedTime(prev); scaled = interpolator.getInterpolatedDerivatives().clone(); for (int j = 0; j < n; ++j) { scaled[j] *= stepSize; } // compute the high order scaled derivatives final double[][] multistep = new double[nSteps][]; for (int i = 1; i <= nSteps; ++i) { interpolator.setInterpolatedTime(prev + stepSize * i); final double[] msI = interpolator.getInterpolatedDerivatives().clone(); for (int j = 0; j < n; ++j) { msI[j] *= stepSize; } multistep[i - 1] = msI; } nordsieck = initializeHighOrderDerivatives(scaled, multistep); // stop the integrator after the first step has been handled throw new InitializationCompletedMarkerException(); } /** {@inheritDoc} */ public boolean requiresDenseOutput() { return true; } /** {@inheritDoc} */ public void reset() { // nothing to do } } /** Marker exception used ONLY to stop the starter integrator after first step. */ private static class InitializationCompletedMarkerException extends DerivativeException { /** Serializable version identifier. */ private static final long serialVersionUID = -4105805787353488365L; /** Simple constructor. */ public InitializationCompletedMarkerException() { super((Throwable) null); } } /** Wrapper for differential equations, ensuring start evaluations are counted. */ private class CountingDifferentialEquations implements ExtendedFirstOrderDifferentialEquations { /** Dimension of the problem. */ private final int dimension; /** Simple constructor. * @param dimension dimension of the problem */ public CountingDifferentialEquations(final int dimension) { this.dimension = dimension; } /** {@inheritDoc} */ public void computeDerivatives(double t, double[] y, double[] dot) throws DerivativeException { MultistepIntegrator.this.computeDerivatives(t, y, dot); } /** {@inheritDoc} */ public int getDimension() { return dimension; } /** {@inheritDoc} */ public int getMainSetDimension() { return mainSetDimension; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/FixedStepHandler.java100644 1750 1750 5272 11532241246 30770 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import org.apache.commons.math.ode.DerivativeException; /** * This interface represents a handler that should be called after * each successful fixed step. *

                      This interface should be implemented by anyone who is interested * in getting the solution of an ordinary differential equation at * fixed time steps. Objects implementing this interface should be * wrapped within an instance of {@link StepNormalizer} that itself * is used as the general {@link StepHandler} by the integrator. The * {@link StepNormalizer} object is called according to the integrator * internal algorithms and it calls objects implementing this * interface as necessary at fixed time steps.

                      * * @see StepHandler * @see StepNormalizer * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface FixedStepHandler { /** * Handle the last accepted step * @param t time of the current step * @param y state vector at t. For efficiency purposes, the {@link * StepNormalizer} class reuses the same array on each call, so if * the instance wants to keep it across all calls (for example to * provide at the end of the integration a complete array of all * steps), it should build a local copy store this copy. * @param yDot derivatives of the state vector state vector at t. * For efficiency purposes, the {@link StepNormalizer} class reuses * the same array on each call, so if * the instance wants to keep it across all calls (for example to * provide at the end of the integration a complete array of all * steps), it should build a local copy store this copy. * @param isLast true if the step is the last one * @throws DerivativeException if some error condition is encountered */ void handleStep(double t, double[] y, double[] yDot, boolean isLast) throws DerivativeException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/StepHandler.java100644 1750 1750 6523 11532241246 30010 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import org.apache.commons.math.ode.DerivativeException; /** * This interface represents a handler that should be called after * each successful step. * *

                      The ODE integrators compute the evolution of the state vector at * some grid points that depend on their own internal algorithm. Once * they have found a new grid point (possibly after having computed * several evaluation of the derivative at intermediate points), they * provide it to objects implementing this interface. These objects * typically either ignore the intermediate steps and wait for the * last one, store the points in an ephemeris, or forward them to * specialized processing or output methods.

                      * * @see org.apache.commons.math.ode.FirstOrderIntegrator * @see org.apache.commons.math.ode.SecondOrderIntegrator * @see StepInterpolator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface StepHandler { /** Determines whether this handler needs dense output. *

                      This method allows the integrator to avoid performing extra * computation if the handler does not need dense output. If this * method returns false, the integrator will call the {@link * #handleStep} method with a {@link DummyStepInterpolator} rather * than a custom interpolator.

                      * @return true if the handler needs dense output */ boolean requiresDenseOutput(); /** Reset the step handler. * Initialize the internal data as required before the first step is * handled. */ void reset(); /** * Handle the last accepted step * @param interpolator interpolator for the last accepted step. For * efficiency purposes, the various integrators reuse the same * object on each call, so if the instance wants to keep it across * all calls (for example to provide at the end of the integration a * continuous model valid throughout the integration range, as the * {@link org.apache.commons.math.ode.ContinuousOutputModel * ContinuousOutputModel} class does), it should build a local copy * using the clone method of the interpolator and store this copy. * Keeping only a reference to the interpolator and reusing it will * result in unpredictable behavior (potentially crashing the application). * @param isLast true if the step is the last one * @exception DerivativeException if user code called from step interpolator * finalization triggers one */ void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException; } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.jav100644 1750 1750 41577 11532241246 32470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.commons.math.ode.DerivativeException; /** This abstract class represents an interpolator over the last step * during an ODE integration. * *

                      The various ODE integrators provide objects extending this class * to the step handlers. The handlers can use these objects to * retrieve the state vector at intermediate times between the * previous and the current grid points (dense output).

                      * * @see org.apache.commons.math.ode.FirstOrderIntegrator * @see org.apache.commons.math.ode.SecondOrderIntegrator * @see StepHandler * * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 * */ public abstract class AbstractStepInterpolator implements StepInterpolator { /** current time step */ protected double h; /** current state */ protected double[] currentState; /** interpolated time */ protected double interpolatedTime; /** interpolated state */ protected double[] interpolatedState; /** interpolated derivatives */ protected double[] interpolatedDerivatives; /** global previous time */ private double globalPreviousTime; /** global current time */ private double globalCurrentTime; /** soft previous time */ private double softPreviousTime; /** soft current time */ private double softCurrentTime; /** indicate if the step has been finalized or not. */ private boolean finalized; /** integration direction. */ private boolean forward; /** indicator for dirty state. */ private boolean dirtyState; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link #reinitialize} method should be called before using the * instance in order to initialize the internal arrays. This * constructor is used only in order to delay the initialization in * some cases. As an example, the {@link * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} * class uses the prototyping design pattern to create the step * interpolators by cloning an uninitialized model and latter * initializing the copy. */ protected AbstractStepInterpolator() { globalPreviousTime = Double.NaN; globalCurrentTime = Double.NaN; softPreviousTime = Double.NaN; softCurrentTime = Double.NaN; h = Double.NaN; interpolatedTime = Double.NaN; currentState = null; interpolatedState = null; interpolatedDerivatives = null; finalized = false; this.forward = true; this.dirtyState = true; } /** Simple constructor. * @param y reference to the integrator array holding the state at * the end of the step * @param forward integration direction indicator */ protected AbstractStepInterpolator(final double[] y, final boolean forward) { globalPreviousTime = Double.NaN; globalCurrentTime = Double.NaN; softPreviousTime = Double.NaN; softCurrentTime = Double.NaN; h = Double.NaN; interpolatedTime = Double.NaN; currentState = y; interpolatedState = new double[y.length]; interpolatedDerivatives = new double[y.length]; finalized = false; this.forward = forward; this.dirtyState = true; } /** Copy constructor. *

                      The copied interpolator should have been finalized before the * copy, otherwise the copy will not be able to perform correctly * any derivative computation and will throw a {@link * NullPointerException} later. Since we don't want this constructor * to throw the exceptions finalization may involve and since we * don't want this method to modify the state of the copied * interpolator, finalization is not done * automatically, it remains under user control.

                      * *

                      The copy is a deep copy: its arrays are separated from the * original arrays of the instance.

                      * * @param interpolator interpolator to copy from. * */ protected AbstractStepInterpolator(final AbstractStepInterpolator interpolator) { globalPreviousTime = interpolator.globalPreviousTime; globalCurrentTime = interpolator.globalCurrentTime; softPreviousTime = interpolator.softPreviousTime; softCurrentTime = interpolator.softCurrentTime; h = interpolator.h; interpolatedTime = interpolator.interpolatedTime; if (interpolator.currentState != null) { currentState = interpolator.currentState.clone(); interpolatedState = interpolator.interpolatedState.clone(); interpolatedDerivatives = interpolator.interpolatedDerivatives.clone(); } else { currentState = null; interpolatedState = null; interpolatedDerivatives = null; } finalized = interpolator.finalized; forward = interpolator.forward; dirtyState = interpolator.dirtyState; } /** Reinitialize the instance * @param y reference to the integrator array holding the state at * the end of the step * @param isForward integration direction indicator */ protected void reinitialize(final double[] y, final boolean isForward) { globalPreviousTime = Double.NaN; globalCurrentTime = Double.NaN; softPreviousTime = Double.NaN; softCurrentTime = Double.NaN; h = Double.NaN; interpolatedTime = Double.NaN; currentState = y; interpolatedState = new double[y.length]; interpolatedDerivatives = new double[y.length]; finalized = false; this.forward = isForward; this.dirtyState = true; } /** {@inheritDoc} */ public StepInterpolator copy() throws DerivativeException { // finalize the step before performing copy finalizeStep(); // create the new independent instance return doCopy(); } /** Really copy the finalized instance. *

                      This method is called by {@link #copy()} after the * step has been finalized. It must perform a deep copy * to have an new instance completely independent for the * original instance. * @return a copy of the finalized instance */ protected abstract StepInterpolator doCopy(); /** Shift one step forward. * Copy the current time into the previous time, hence preparing the * interpolator for future calls to {@link #storeTime storeTime} */ public void shift() { globalPreviousTime = globalCurrentTime; softPreviousTime = globalPreviousTime; softCurrentTime = globalCurrentTime; } /** Store the current step time. * @param t current time */ public void storeTime(final double t) { globalCurrentTime = t; softCurrentTime = globalCurrentTime; h = globalCurrentTime - globalPreviousTime; setInterpolatedTime(t); // the step is not finalized anymore finalized = false; } /** Restrict step range to a limited part of the global step. *

                      * This method can be used to restrict a step and make it appear * as if the original step was smaller. Calling this method * only changes the value returned by {@link #getPreviousTime()}, * it does not change any other property *

                      * @param softPreviousTime start of the restricted step * @since 2.2 */ public void setSoftPreviousTime(final double softPreviousTime) { this.softPreviousTime = softPreviousTime; } /** Restrict step range to a limited part of the global step. *

                      * This method can be used to restrict a step and make it appear * as if the original step was smaller. Calling this method * only changes the value returned by {@link #getCurrentTime()}, * it does not change any other property *

                      * @param softCurrentTime end of the restricted step * @since 2.2 */ public void setSoftCurrentTime(final double softCurrentTime) { this.softCurrentTime = softCurrentTime; } /** * Get the previous global grid point time. * @return previous global grid point time * @since 2.2 */ public double getGlobalPreviousTime() { return globalPreviousTime; } /** * Get the current global grid point time. * @return current global grid point time * @since 2.2 */ public double getGlobalCurrentTime() { return globalCurrentTime; } /** * Get the previous soft grid point time. * @return previous soft grid point time * @see #setSoftPreviousTime(double) */ public double getPreviousTime() { return softPreviousTime; } /** * Get the current soft grid point time. * @return current soft grid point time * @see #setSoftCurrentTime(double) */ public double getCurrentTime() { return softCurrentTime; } /** {@inheritDoc} */ public double getInterpolatedTime() { return interpolatedTime; } /** {@inheritDoc} */ public void setInterpolatedTime(final double time) { interpolatedTime = time; dirtyState = true; } /** {@inheritDoc} */ public boolean isForward() { return forward; } /** Compute the state and derivatives at the interpolated time. * This is the main processing method that should be implemented by * the derived classes to perform the interpolation. * @param theta normalized interpolation abscissa within the step * (theta is zero at the previous time step and one at the current time step) * @param oneMinusThetaH time gap between the interpolated time and * the current time * @throws DerivativeException this exception is propagated to the caller if the * underlying user function triggers one */ protected abstract void computeInterpolatedStateAndDerivatives(double theta, double oneMinusThetaH) throws DerivativeException; /** {@inheritDoc} */ public double[] getInterpolatedState() throws DerivativeException { // lazy evaluation of the state if (dirtyState) { final double oneMinusThetaH = globalCurrentTime - interpolatedTime; final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); dirtyState = false; } return interpolatedState; } /** {@inheritDoc} */ public double[] getInterpolatedDerivatives() throws DerivativeException { // lazy evaluation of the state if (dirtyState) { final double oneMinusThetaH = globalCurrentTime - interpolatedTime; final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); dirtyState = false; } return interpolatedDerivatives; } /** * Finalize the step. * *

                      Some embedded Runge-Kutta integrators need fewer functions * evaluations than their counterpart step interpolators. These * interpolators should perform the last evaluations they need by * themselves only if they need them. This method triggers these * extra evaluations. It can be called directly by the user step * handler and it is called automatically if {@link * #setInterpolatedTime} is called.

                      * *

                      Once this method has been called, no other * evaluation will be performed on this step. If there is a need to * have some side effects between the step handler and the * differential equations (for example update some data in the * equations once the step has been done), it is advised to call * this method explicitly from the step handler before these side * effects are set up. If the step handler induces no side effect, * then this method can safely be ignored, it will be called * transparently as needed.

                      * *

                      Warning: since the step interpolator provided * to the step handler as a parameter of the {@link * StepHandler#handleStep handleStep} is valid only for the duration * of the {@link StepHandler#handleStep handleStep} call, one cannot * simply store a reference and reuse it later. One should first * finalize the instance, then copy this finalized instance into a * new object that can be kept.

                      * *

                      This method calls the protected doFinalize method * if it has never been called during this step and set a flag * indicating that it has been called once. It is the * doFinalize method which should perform the evaluations. * This wrapping prevents from calling doFinalize several * times and hence evaluating the differential equations too often. * Therefore, subclasses are not allowed not reimplement it, they * should rather reimplement doFinalize.

                      * * @throws DerivativeException this exception is propagated to the * caller if the underlying user function triggers one */ public final void finalizeStep() throws DerivativeException { if (! finalized) { doFinalize(); finalized = true; } } /** * Really finalize the step. * The default implementation of this method does nothing. * @throws DerivativeException this exception is propagated to the * caller if the underlying user function triggers one */ protected void doFinalize() throws DerivativeException { } /** {@inheritDoc} */ public abstract void writeExternal(ObjectOutput out) throws IOException; /** {@inheritDoc} */ public abstract void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; /** Save the base state of the instance. * This method performs step finalization if it has not been done * before. * @param out stream where to save the state * @exception IOException in case of write error */ protected void writeBaseExternal(final ObjectOutput out) throws IOException { if (currentState == null) { out.writeInt(-1); } else { out.writeInt(currentState.length); } out.writeDouble(globalPreviousTime); out.writeDouble(globalCurrentTime); out.writeDouble(softPreviousTime); out.writeDouble(softCurrentTime); out.writeDouble(h); out.writeBoolean(forward); if (currentState != null) { for (int i = 0; i < currentState.length; ++i) { out.writeDouble(currentState[i]); } } out.writeDouble(interpolatedTime); // we do not store the interpolated state, // it will be recomputed as needed after reading // finalize the step (and don't bother saving the now true flag) try { finalizeStep(); } catch (DerivativeException e) { IOException ioe = new IOException(e.getLocalizedMessage()); ioe.initCause(e); throw ioe; } } /** Read the base state of the instance. * This method does neither set the interpolated * time nor state. It is up to the derived class to reset it * properly calling the {@link #setInterpolatedTime} method later, * once all rest of the object state has been set up properly. * @param in stream where to read the state from * @return interpolated time be set later by the caller * @exception IOException in case of read error */ protected double readBaseExternal(final ObjectInput in) throws IOException { final int dimension = in.readInt(); globalPreviousTime = in.readDouble(); globalCurrentTime = in.readDouble(); softPreviousTime = in.readDouble(); softCurrentTime = in.readDouble(); h = in.readDouble(); forward = in.readBoolean(); dirtyState = true; if (dimension < 0) { currentState = null; } else { currentState = new double[dimension]; for (int i = 0; i < currentState.length; ++i) { currentState[i] = in.readDouble(); } } // we do NOT handle the interpolated time and state here interpolatedTime = Double.NaN; interpolatedState = (dimension < 0) ? null : new double[dimension]; interpolatedDerivatives = (dimension < 0) ? null : new double[dimension]; finalized = true; return in.readDouble(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/DummyStepInterpolator.java100644 1750 1750 12262 11532241246 32146 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; /** This class is a step interpolator that does nothing. * *

                      This class is used when the {@link StepHandler "step handler"} * set up by the user does not need step interpolation. It does not * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime * setInterpolatedTime} is called. This implies the interpolated state * is always the state at the end of the current step.

                      * * @see StepHandler * * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ * @since 1.2 */ public class DummyStepInterpolator extends AbstractStepInterpolator { /** Serializable version identifier. */ private static final long serialVersionUID = 1708010296707839488L; /** Current derivative. */ private double[] currentDerivative; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * AbstractStepInterpolator.reinitialize protected method * should be called before using the instance in order to initialize * the internal arrays. This constructor is used only in order to delay * the initialization in some cases. As an example, the {@link * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses * the prototyping design pattern to create the step interpolators by * cloning an uninitialized model and latter initializing the copy. */ public DummyStepInterpolator() { super(); currentDerivative = null; } /** Simple constructor. * @param y reference to the integrator array holding the state at * the end of the step * @param yDot reference to the integrator array holding the state * derivative at some arbitrary point within the step * @param forward integration direction indicator */ public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) { super(y, forward); currentDerivative = yDot; } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public DummyStepInterpolator(final DummyStepInterpolator interpolator) { super(interpolator); currentDerivative = interpolator.currentDerivative.clone(); } /** Really copy the finalized instance. * @return a copy of the finalized instance */ @Override protected StepInterpolator doCopy() { return new DummyStepInterpolator(this); } /** Compute the state at the interpolated time. * In this class, this method does nothing: the interpolated state * is always the state at the end of the current step. * @param theta normalized interpolation abscissa within the step * (theta is zero at the previous time step and one at the current time step) * @param oneMinusThetaH time gap between the interpolated time and * the current time */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) { System.arraycopy(currentState, 0, interpolatedState, 0, currentState.length); System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length); } /** Write the instance to an output channel. * @param out output channel * @exception IOException if the instance cannot be written */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // save the state of the base class writeBaseExternal(out); if (currentDerivative != null) { for (int i = 0; i < currentDerivative.length; ++i) { out.writeDouble(currentDerivative[i]); } } } /** Read the instance from an input channel. * @param in input channel * @exception IOException if the instance cannot be read */ @Override public void readExternal(final ObjectInput in) throws IOException { // read the base class final double t = readBaseExternal(in); if (currentState == null) { currentDerivative = null; } else { currentDerivative = new double[currentState.length]; for (int i = 0; i < currentDerivative.length; ++i) { currentDerivative[i] = in.readDouble(); } } // we can now set the interpolated time and state setInterpolatedTime(t); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/StepInterpolator.java100644 1750 1750 12331 11532241246 31127 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import java.io.Externalizable; import org.apache.commons.math.ode.DerivativeException; /** This interface represents an interpolator over the last step * during an ODE integration. * *

                      The various ODE integrators provide objects implementing this * interface to the step handlers. These objects are often custom * objects tightly bound to the integrator internal algorithms. The * handlers can use these objects to retrieve the state vector at * intermediate times between the previous and the current grid points * (this feature is often called dense output).

                      *

                      One important thing to note is that the step handlers may be so * tightly bound to the integrators that they often share some internal * state arrays. This imply that one should never use a direct * reference to a step interpolator outside of the step handler, either * for future use or for use in another thread. If such a need arise, the * step interpolator must be copied using the dedicated * {@link #copy()} method. *

                      * * @see org.apache.commons.math.ode.FirstOrderIntegrator * @see org.apache.commons.math.ode.SecondOrderIntegrator * @see StepHandler * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public interface StepInterpolator extends Externalizable { /** * Get the previous grid point time. * @return previous grid point time */ double getPreviousTime(); /** * Get the current grid point time. * @return current grid point time */ double getCurrentTime(); /** * Get the time of the interpolated point. * If {@link #setInterpolatedTime} has not been called, it returns * the current grid point time. * @return interpolation point time */ double getInterpolatedTime(); /** * Set the time of the interpolated point. *

                      Setting the time outside of the current step is now allowed, but * should be used with care since the accuracy of the interpolator will * probably be very poor far from this step. This allowance has been * added to simplify implementation of search algorithms near the * step endpoints.

                      *

                      Setting the time changes the instance internal state. If a * specific state must be preserved, a copy of the instance must be * created using {@link #copy()}.

                      * @param time time of the interpolated point */ void setInterpolatedTime(double time); /** * Get the state vector of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return state vector at time {@link #getInterpolatedTime} * @see #getInterpolatedDerivatives() * @exception DerivativeException if user code called from step interpolator * finalization triggers one */ double[] getInterpolatedState() throws DerivativeException; /** * Get the derivatives of the state vector of the interpolated point. *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return derivatives of the state vector at time {@link #getInterpolatedTime} * @see #getInterpolatedState() * @exception DerivativeException if user code called from step interpolator * finalization triggers one * @since 2.0 */ double[] getInterpolatedDerivatives() throws DerivativeException; /** Check if the natural integration direction is forward. *

                      This method provides the integration direction as specified by * the integrator itself, it avoid some nasty problems in * degenerated cases like null steps due to cancellation at step * initialization, step control or discrete events * triggering.

                      * @return true if the integration variable (time) increases during * integration */ boolean isForward(); /** Copy the instance. *

                      The copied instance is guaranteed to be independent from the * original one. Both can be used with different settings for * interpolated time without any side effect.

                      * @return a deep copy of the instance, which can be used independently. * @exception DerivativeException if user code called from step interpolator * finalization triggers one * @see #setInterpolatedTime(double) */ StepInterpolator copy() throws DerivativeException; } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.ja100644 1750 1750 24262 11532241246 32450 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Arrays; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.linear.Array2DRowRealMatrix; import org.apache.commons.math.util.FastMath; /** * This class implements an interpolator for integrators using Nordsieck representation. * *

                      This interpolator computes dense output around the current point. * The interpolation equation is based on Taylor series formulas. * * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public class NordsieckStepInterpolator extends AbstractStepInterpolator { /** Serializable version identifier */ private static final long serialVersionUID = -7179861704951334960L; /** State variation. */ protected double[] stateVariation; /** Step size used in the first scaled derivative and Nordsieck vector. */ private double scalingH; /** Reference time for all arrays. *

                      Sometimes, the reference time is the same as previousTime, * sometimes it is the same as currentTime, so we use a separate * field to avoid any confusion. *

                      */ private double referenceTime; /** First scaled derivative. */ private double[] scaled; /** Nordsieck vector. */ private Array2DRowRealMatrix nordsieck; /** Simple constructor. * This constructor builds an instance that is not usable yet, the * {@link AbstractStepInterpolator#reinitialize} method should be called * before using the instance in order to initialize the internal arrays. This * constructor is used only in order to delay the initialization in * some cases. */ public NordsieckStepInterpolator() { } /** Copy constructor. * @param interpolator interpolator to copy from. The copy is a deep * copy: its arrays are separated from the original arrays of the * instance */ public NordsieckStepInterpolator(final NordsieckStepInterpolator interpolator) { super(interpolator); scalingH = interpolator.scalingH; referenceTime = interpolator.referenceTime; if (interpolator.scaled != null) { scaled = interpolator.scaled.clone(); } if (interpolator.nordsieck != null) { nordsieck = new Array2DRowRealMatrix(interpolator.nordsieck.getDataRef(), true); } if (interpolator.stateVariation != null) { stateVariation = interpolator.stateVariation.clone(); } } /** {@inheritDoc} */ @Override protected StepInterpolator doCopy() { return new NordsieckStepInterpolator(this); } /** Reinitialize the instance. *

                      Beware that all arrays must be references to integrator * arrays, in order to ensure proper update without copy.

                      * @param y reference to the integrator array holding the state at * the end of the step * @param forward integration direction indicator */ @Override public void reinitialize(final double[] y, final boolean forward) { super.reinitialize(y, forward); stateVariation = new double[y.length]; } /** Reinitialize the instance. *

                      Beware that all arrays must be references to integrator * arrays, in order to ensure proper update without copy.

                      * @param time time at which all arrays are defined * @param stepSize step size used in the scaled and nordsieck arrays * @param scaledDerivative reference to the integrator array holding the first * scaled derivative * @param nordsieckVector reference to the integrator matrix holding the * nordsieck vector */ public void reinitialize(final double time, final double stepSize, final double[] scaledDerivative, final Array2DRowRealMatrix nordsieckVector) { this.referenceTime = time; this.scalingH = stepSize; this.scaled = scaledDerivative; this.nordsieck = nordsieckVector; // make sure the state and derivatives will depend on the new arrays setInterpolatedTime(getInterpolatedTime()); } /** Rescale the instance. *

                      Since the scaled and Nordiseck arrays are shared with the caller, * this method has the side effect of rescaling this arrays in the caller too.

                      * @param stepSize new step size to use in the scaled and nordsieck arrays */ public void rescale(final double stepSize) { final double ratio = stepSize / scalingH; for (int i = 0; i < scaled.length; ++i) { scaled[i] *= ratio; } final double[][] nData = nordsieck.getDataRef(); double power = ratio; for (int i = 0; i < nData.length; ++i) { power *= ratio; final double[] nDataI = nData[i]; for (int j = 0; j < nDataI.length; ++j) { nDataI[j] *= power; } } scalingH = stepSize; } /** * Get the state vector variation from current to interpolated state. *

                      This method is aimed at computing y(tinterpolation) * -y(tcurrent) accurately by avoiding the cancellation errors * that would occur if the subtraction were performed explicitly.

                      *

                      The returned vector is a reference to a reused array, so * it should not be modified and it should be copied if it needs * to be preserved across several calls.

                      * @return state vector at time {@link #getInterpolatedTime} * @see #getInterpolatedDerivatives() * @throws DerivativeException if this call induces an automatic * step finalization that throws one */ public double[] getInterpolatedStateVariation() throws DerivativeException { // compute and ignore interpolated state // to make sure state variation is computed as a side effect getInterpolatedState(); return stateVariation; } /** {@inheritDoc} */ @Override protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) { final double x = interpolatedTime - referenceTime; final double normalizedAbscissa = x / scalingH; Arrays.fill(stateVariation, 0.0); Arrays.fill(interpolatedDerivatives, 0.0); // apply Taylor formula from high order to low order, // for the sake of numerical accuracy final double[][] nData = nordsieck.getDataRef(); for (int i = nData.length - 1; i >= 0; --i) { final int order = i + 2; final double[] nDataI = nData[i]; final double power = FastMath.pow(normalizedAbscissa, order); for (int j = 0; j < nDataI.length; ++j) { final double d = nDataI[j] * power; stateVariation[j] += d; interpolatedDerivatives[j] += order * d; } } for (int j = 0; j < currentState.length; ++j) { stateVariation[j] += scaled[j] * normalizedAbscissa; interpolatedState[j] = currentState[j] + stateVariation[j]; interpolatedDerivatives[j] = (interpolatedDerivatives[j] + scaled[j] * normalizedAbscissa) / x; } } /** {@inheritDoc} */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // save the state of the base class writeBaseExternal(out); // save the local attributes out.writeDouble(scalingH); out.writeDouble(referenceTime); final int n = (currentState == null) ? -1 : currentState.length; if (scaled == null) { out.writeBoolean(false); } else { out.writeBoolean(true); for (int j = 0; j < n; ++j) { out.writeDouble(scaled[j]); } } if (nordsieck == null) { out.writeBoolean(false); } else { out.writeBoolean(true); out.writeObject(nordsieck); } // we don't save state variation, it will be recomputed } /** {@inheritDoc} */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { // read the base class final double t = readBaseExternal(in); // read the local attributes scalingH = in.readDouble(); referenceTime = in.readDouble(); final int n = (currentState == null) ? -1 : currentState.length; final boolean hasScaled = in.readBoolean(); if (hasScaled) { scaled = new double[n]; for (int j = 0; j < n; ++j) { scaled[j] = in.readDouble(); } } else { scaled = null; } final boolean hasNordsieck = in.readBoolean(); if (hasNordsieck) { nordsieck = (Array2DRowRealMatrix) in.readObject(); } else { nordsieck = null; } if (hasScaled && hasNordsieck) { // we can now set the interpolated time and state stateVariation = new double[n]; setInterpolatedTime(t); } else { stateVariation = null; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/package.html100644 1750 1750 5534 11532241246 27216 0ustarlucluc 0 0

                      This package provides classes to handle sampling steps during Ordinary Differential Equations integration.

                      In addition to computing the evolution of the state vector at some grid points, all ODE integrators also build up interpolation models of this evolution inside the last computed step. If users are interested in these interpolators, they can register a {@link org.apache.commons.math.ode.sampling.StepHandler StepHandler} instance using the {@link org.apache.commons.math.ode.FirstOrderIntegrator#addStepHandler addStepHandler} method which is supported by all integrators. The integrator will call this instance at the end of each accepted step and provide it the interpolator. The user can do whatever he wants with this interpolator, which computes both the state and its time-derivative. A typical use of step handler is to provide some output to monitor the integration process.

                      In a sense, this is a kind of Inversion Of Control: rather than having the master application driving the slave integrator by providing the target end value for the free variable, we get a master integrator scheduling the free variable evolution and calling the slave application callbacks that were registered at configuration time.

                      Since some integrators may use variable step size, the generic {@link org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface can be called either at regular or irregular rate. This interface allows to navigate to any location within the last computed step, thanks to the provided {@link org.apache.commons.math.ode.sampling.StepInterpolator StepInterpolator} object. If regular output is desired (for example in order to write an ephemeris file), then the simpler {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} interface can be used. Objects implementing this interface should be wrapped within a {@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} instance in order to be registered to the integrator.

                      commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/DummyStepHandler.java100644 1750 1750 7017 11532241246 31023 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; /** * This class is a step handler that does nothing. *

                      This class is provided as a convenience for users who are only * interested in the final state of an integration and not in the * intermediate steps. Its handleStep method does nothing.

                      * *

                      Since this class has no internal state, it is implemented using * the Singleton design pattern. This means that only one instance is * ever created, which can be retrieved using the getInstance * method. This explains why there is no public constructor.

                      * * @see StepHandler * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 1.2 */ public class DummyStepHandler implements StepHandler { /** Private constructor. * The constructor is private to prevent users from creating * instances (Singleton design-pattern). */ private DummyStepHandler() { } /** Get the only instance. * @return the only instance */ public static DummyStepHandler getInstance() { return LazyHolder.INSTANCE; } /** Determines whether this handler needs dense output. * Since this handler does nothing, it does not require dense output. * @return always false */ public boolean requiresDenseOutput() { return false; } /** Reset the step handler. * Initialize the internal data as required before the first step is * handled. */ public void reset() { } /** * Handle the last accepted step. * This method does nothing in this class. * @param interpolator interpolator for the last accepted step. For * efficiency purposes, the various integrators reuse the same * object on each call, so if the instance wants to keep it across * all calls (for example to provide at the end of the integration a * continuous model valid throughout the integration range), it * should build a local copy using the clone method and store this * copy. * @param isLast true if the step is the last one */ public void handleStep(final StepInterpolator interpolator, final boolean isLast) { } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the instance. *

                      We use here the Initialization On Demand Holder Idiom.

                      */ private static class LazyHolder { /** Cached field instance. */ private static final DummyStepHandler INSTANCE = new DummyStepHandler(); } // CHECKSTYLE: resume HideUtilityClassConstructor /** Handle deserialization of the singleton. * @return the singleton instance */ private Object readResolve() { // return the singleton instance return LazyHolder.INSTANCE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java100644 1750 1750 13324 11532241246 30572 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode.sampling; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.util.FastMath; /** * This class wraps an object implementing {@link FixedStepHandler} * into a {@link StepHandler}. *

                      This wrapper allows to use fixed step handlers with general * integrators which cannot guaranty their integration steps will * remain constant and therefore only accept general step * handlers.

                      * *

                      The stepsize used is selected at construction time. The {@link * FixedStepHandler#handleStep handleStep} method of the underlying * {@link FixedStepHandler} object is called at the beginning time of * the integration t0 and also at times t0+h, t0+2h, ... If the * integration range is an integer multiple of the stepsize, then the * last point handled will be the endpoint of the integration tend, if * not, the last point will belong to the interval [tend - h ; * tend].

                      * *

                      There is no constraint on the integrator, it can use any * timestep it needs (time steps longer or shorter than the fixed time * step and non-integer ratios are all allowed).

                      * * @see StepHandler * @see FixedStepHandler * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public class StepNormalizer implements StepHandler { /** Fixed time step. */ private double h; /** Underlying step handler. */ private final FixedStepHandler handler; /** Last step time. */ private double lastTime; /** Last State vector. */ private double[] lastState; /** Last Derivatives vector. */ private double[] lastDerivatives; /** Integration direction indicator. */ private boolean forward; /** Simple constructor. * @param h fixed time step (sign is not used) * @param handler fixed time step handler to wrap */ public StepNormalizer(final double h, final FixedStepHandler handler) { this.h = FastMath.abs(h); this.handler = handler; reset(); } /** Determines whether this handler needs dense output. * This handler needs dense output in order to provide data at * regularly spaced steps regardless of the steps the integrator * uses, so this method always returns true. * @return always true */ public boolean requiresDenseOutput() { return true; } /** Reset the step handler. * Initialize the internal data as required before the first step is * handled. */ public void reset() { lastTime = Double.NaN; lastState = null; lastDerivatives = null; forward = true; } /** * Handle the last accepted step * @param interpolator interpolator for the last accepted step. For * efficiency purposes, the various integrators reuse the same * object on each call, so if the instance wants to keep it across * all calls (for example to provide at the end of the integration a * continuous model valid throughout the integration range), it * should build a local copy using the clone method and store this * copy. * @param isLast true if the step is the last one * @throws DerivativeException this exception is propagated to the * caller if the underlying user function triggers one */ public void handleStep(final StepInterpolator interpolator, final boolean isLast) throws DerivativeException { if (lastState == null) { lastTime = interpolator.getPreviousTime(); interpolator.setInterpolatedTime(lastTime); lastState = interpolator.getInterpolatedState().clone(); lastDerivatives = interpolator.getInterpolatedDerivatives().clone(); // take the integration direction into account forward = interpolator.getCurrentTime() >= lastTime; if (! forward) { h = -h; } } double nextTime = lastTime + h; boolean nextInStep = forward ^ (nextTime > interpolator.getCurrentTime()); while (nextInStep) { // output the stored previous step handler.handleStep(lastTime, lastState, lastDerivatives, false); // store the next step lastTime = nextTime; interpolator.setInterpolatedTime(lastTime); System.arraycopy(interpolator.getInterpolatedState(), 0, lastState, 0, lastState.length); System.arraycopy(interpolator.getInterpolatedDerivatives(), 0, lastDerivatives, 0, lastDerivatives.length); nextTime += h; nextInStep = forward ^ (nextTime > interpolator.getCurrentTime()); } if (isLast) { // there will be no more steps, // the stored one should be flagged as being the last handler.handleStep(lastTime, lastState, lastDerivatives, true); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/AbstractIntegrator.java100644 1750 1750 40011 11532241246 27575 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.events.CombinedEventsManager; import org.apache.commons.math.ode.events.EventException; import org.apache.commons.math.ode.events.EventHandler; import org.apache.commons.math.ode.events.EventState; import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Base class managing common boilerplate for all integrators. * @version $Revision: 1073267 $ $Date: 2011-02-22 10:06:20 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public abstract class AbstractIntegrator implements FirstOrderIntegrator { /** Step handler. */ protected Collection stepHandlers; /** Current step start time. */ protected double stepStart; /** Current stepsize. */ protected double stepSize; /** Indicator for last step. */ protected boolean isLastStep; /** Indicator that a state or derivative reset was triggered by some event. */ protected boolean resetOccurred; /** Events states. */ private Collection eventsStates; /** Initialization indicator of events states. */ private boolean statesInitialized; /** Name of the method. */ private final String name; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Differential equations to integrate. */ private transient FirstOrderDifferentialEquations equations; /** Build an instance. * @param name name of the method */ public AbstractIntegrator(final String name) { this.name = name; stepHandlers = new ArrayList(); stepStart = Double.NaN; stepSize = Double.NaN; eventsStates = new ArrayList(); statesInitialized = false; setMaxEvaluations(-1); resetEvaluations(); } /** Build an instance with a null name. */ protected AbstractIntegrator() { this(null); } /** {@inheritDoc} */ public String getName() { return name; } /** {@inheritDoc} */ public void addStepHandler(final StepHandler handler) { stepHandlers.add(handler); } /** {@inheritDoc} */ public Collection getStepHandlers() { return Collections.unmodifiableCollection(stepHandlers); } /** {@inheritDoc} */ public void clearStepHandlers() { stepHandlers.clear(); } /** {@inheritDoc} */ public void addEventHandler(final EventHandler handler, final double maxCheckInterval, final double convergence, final int maxIterationCount) { eventsStates.add(new EventState(handler, maxCheckInterval, convergence, maxIterationCount)); } /** {@inheritDoc} */ public Collection getEventHandlers() { final List list = new ArrayList(); for (EventState state : eventsStates) { list.add(state.getEventHandler()); } return Collections.unmodifiableCollection(list); } /** {@inheritDoc} */ public void clearEventHandlers() { eventsStates.clear(); } /** Check if dense output is needed. * @return true if there is at least one event handler or if * one of the step handlers requires dense output */ protected boolean requiresDenseOutput() { if (!eventsStates.isEmpty()) { return true; } for (StepHandler handler : stepHandlers) { if (handler.requiresDenseOutput()) { return true; } } return false; } /** {@inheritDoc} */ public double getCurrentStepStart() { return stepStart; } /** {@inheritDoc} */ public double getCurrentSignedStepsize() { return stepSize; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return evaluations; } /** Reset the number of evaluations to zero. */ protected void resetEvaluations() { evaluations = 0; } /** Set the differential equations. * @param equations differential equations to integrate * @see #computeDerivatives(double, double[], double[]) */ protected void setEquations(final FirstOrderDifferentialEquations equations) { this.equations = equations; } /** Compute the derivatives and check the number of evaluations. * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param yDot placeholder array where to put the time derivative of the state vector * @throws DerivativeException this user-defined exception should be used if an error is * is triggered by user code */ public void computeDerivatives(final double t, final double[] y, final double[] yDot) throws DerivativeException { if (++evaluations > maxEvaluations) { throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); } equations.computeDerivatives(t, y, yDot); } /** Set the stateInitialized flag. *

                      This method must be called by integrators with the value * {@code false} before they start integration, so a proper lazy * initialization is done automatically on the first step.

                      * @param stateInitialized new value for the flag * @since 2.2 */ protected void setStateInitialized(final boolean stateInitialized) { this.statesInitialized = stateInitialized; } /** Accept a step, triggering events and step handlers. * @param interpolator step interpolator * @param y state vector at step end time, must be reset if an event * asks for resetting or if an events stops integration during the step * @param yDot placeholder array where to put the time derivative of the state vector * @param tEnd final integration time * @return time at end of step * @throws DerivativeException this exception is propagated to the caller if * the underlying user function triggers one * @exception IntegratorException if the value of one event state cannot be evaluated * @since 2.2 */ protected double acceptStep(final AbstractStepInterpolator interpolator, final double[] y, final double[] yDot, final double tEnd) throws DerivativeException, IntegratorException { try { double previousT = interpolator.getGlobalPreviousTime(); final double currentT = interpolator.getGlobalCurrentTime(); resetOccurred = false; // initialize the events states if needed if (! statesInitialized) { for (EventState state : eventsStates) { state.reinitializeBegin(interpolator); } statesInitialized = true; } // search for next events that may occur during the step final int orderingSign = interpolator.isForward() ? +1 : -1; SortedSet occuringEvents = new TreeSet(new Comparator() { /** {@inheritDoc} */ public int compare(EventState es0, EventState es1) { return orderingSign * Double.compare(es0.getEventTime(), es1.getEventTime()); } }); for (final EventState state : eventsStates) { if (state.evaluateStep(interpolator)) { // the event occurs during the current step occuringEvents.add(state); } } while (!occuringEvents.isEmpty()) { // handle the chronologically first event final Iterator iterator = occuringEvents.iterator(); final EventState currentEvent = iterator.next(); iterator.remove(); // restrict the interpolator to the first part of the step, up to the event final double eventT = currentEvent.getEventTime(); interpolator.setSoftPreviousTime(previousT); interpolator.setSoftCurrentTime(eventT); // trigger the event interpolator.setInterpolatedTime(eventT); final double[] eventY = interpolator.getInterpolatedState(); currentEvent.stepAccepted(eventT, eventY); isLastStep = currentEvent.stop(); // handle the first part of the step, up to the event for (final StepHandler handler : stepHandlers) { handler.handleStep(interpolator, isLastStep); } if (isLastStep) { // the event asked to stop integration System.arraycopy(eventY, 0, y, 0, y.length); return eventT; } if (currentEvent.reset(eventT, eventY)) { // some event handler has triggered changes that // invalidate the derivatives, we need to recompute them System.arraycopy(eventY, 0, y, 0, y.length); computeDerivatives(eventT, y, yDot); resetOccurred = true; return eventT; } // prepare handling of the remaining part of the step previousT = eventT; interpolator.setSoftPreviousTime(eventT); interpolator.setSoftCurrentTime(currentT); // check if the same event occurs again in the remaining part of the step if (currentEvent.evaluateStep(interpolator)) { // the event occurs during the current step occuringEvents.add(currentEvent); } } interpolator.setInterpolatedTime(currentT); final double[] currentY = interpolator.getInterpolatedState(); for (final EventState state : eventsStates) { state.stepAccepted(currentT, currentY); isLastStep = isLastStep || state.stop(); } isLastStep = isLastStep || MathUtils.equals(currentT, tEnd, 1); // handle the remaining part of the step, after all events if any for (StepHandler handler : stepHandlers) { handler.handleStep(interpolator, isLastStep); } return currentT; } catch (EventException se) { final Throwable cause = se.getCause(); if ((cause != null) && (cause instanceof DerivativeException)) { throw (DerivativeException) cause; } throw new IntegratorException(se); } catch (ConvergenceException ce) { throw new IntegratorException(ce); } } /** Perform some sanity checks on the integration parameters. * @param ode differential equations set * @param t0 start time * @param y0 state vector at t0 * @param t target time for the integration * @param y placeholder where to put the state vector * @exception IntegratorException if some inconsistency is detected */ protected void sanityChecks(final FirstOrderDifferentialEquations ode, final double t0, final double[] y0, final double t, final double[] y) throws IntegratorException { if (ode.getDimension() != y0.length) { throw new IntegratorException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, ode.getDimension(), y0.length); } if (ode.getDimension() != y.length) { throw new IntegratorException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, ode.getDimension(), y.length); } if (FastMath.abs(t - t0) <= 1.0e-12 * FastMath.max(FastMath.abs(t0), FastMath.abs(t))) { throw new IntegratorException( LocalizedFormats.TOO_SMALL_INTEGRATION_INTERVAL, FastMath.abs(t - t0)); } } /** Add an event handler for end time checking. *

                      This method can be used to simplify handling of integration end time. * It leverages the nominal stop condition with the exceptional stop * conditions.

                      * @param startTime integration start time * @param endTime desired end time * @param manager manager containing the user-defined handlers * @return a new manager containing all the user-defined handlers plus a * dedicated manager triggering a stop event at entTime * @deprecated as of 2.2, this method is not used any more */ @Deprecated protected CombinedEventsManager addEndTimeChecker(final double startTime, final double endTime, final CombinedEventsManager manager) { CombinedEventsManager newManager = new CombinedEventsManager(); for (final EventState state : manager.getEventsStates()) { newManager.addEventHandler(state.getEventHandler(), state.getMaxCheckInterval(), state.getConvergence(), state.getMaxIterationCount()); } newManager.addEventHandler(new EndTimeChecker(endTime), Double.POSITIVE_INFINITY, FastMath.ulp(FastMath.max(FastMath.abs(startTime), FastMath.abs(endTime))), 100); return newManager; } /** Specialized event handler to stop integration. * @deprecated as of 2.2, this class is not used anymore */ @Deprecated private static class EndTimeChecker implements EventHandler { /** Desired end time. */ private final double endTime; /** Build an instance. * @param endTime desired time */ public EndTimeChecker(final double endTime) { this.endTime = endTime; } /** {@inheritDoc} */ public int eventOccurred(double t, double[] y, boolean increasing) { return STOP; } /** {@inheritDoc} */ public double g(double t, double[] y) { return t - endTime; } /** {@inheritDoc} */ public void resetState(double t, double[] y) { } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/ContinuousOutputModel.java100644 1750 1750 33051 11532241246 30351 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import java.util.ArrayList; import java.util.List; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.ode.DerivativeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ode.sampling.StepHandler; import org.apache.commons.math.ode.sampling.StepInterpolator; import org.apache.commons.math.util.FastMath; /** * This class stores all information provided by an ODE integrator * during the integration process and build a continuous model of the * solution from this. * *

                      This class act as a step handler from the integrator point of * view. It is called iteratively during the integration process and * stores a copy of all steps information in a sorted collection for * later use. Once the integration process is over, the user can use * the {@link #setInterpolatedTime setInterpolatedTime} and {@link * #getInterpolatedState getInterpolatedState} to retrieve this * information at any time. It is important to wait for the * integration to be over before attempting to call {@link * #setInterpolatedTime setInterpolatedTime} because some internal * variables are set only once the last step has been handled.

                      * *

                      This is useful for example if the main loop of the user * application should remain independent from the integration process * or if one needs to mimic the behaviour of an analytical model * despite a numerical model is used (i.e. one needs the ability to * get the model value at any time or to navigate through the * data).

                      * *

                      If problem modeling is done with several separate * integration phases for contiguous intervals, the same * ContinuousOutputModel can be used as step handler for all * integration phases as long as they are performed in order and in * the same direction. As an example, one can extrapolate the * trajectory of a satellite with one model (i.e. one set of * differential equations) up to the beginning of a maneuver, use * another more complex model including thrusters modeling and * accurate attitude control during the maneuver, and revert to the * first model after the end of the maneuver. If the same continuous * output model handles the steps of all integration phases, the user * do not need to bother when the maneuver begins or ends, he has all * the data available in a transparent manner.

                      * *

                      An important feature of this class is that it implements the * Serializable interface. This means that the result of * an integration can be serialized and reused later (if stored into a * persistent medium like a filesystem or a database) or elsewhere (if * sent to another application). Only the result of the integration is * stored, there is no reference to the integrated problem by * itself.

                      * *

                      One should be aware that the amount of data stored in a * ContinuousOutputModel instance can be important if the state vector * is large, if the integration interval is long or if the steps are * small (which can result from small tolerance settings in {@link * org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator adaptive * step size integrators}).

                      * * @see StepHandler * @see StepInterpolator * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public class ContinuousOutputModel implements StepHandler, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1417964919405031606L; /** Initial integration time. */ private double initialTime; /** Final integration time. */ private double finalTime; /** Integration direction indicator. */ private boolean forward; /** Current interpolator index. */ private int index; /** Steps table. */ private List steps; /** Simple constructor. * Build an empty continuous output model. */ public ContinuousOutputModel() { steps = new ArrayList(); reset(); } /** Append another model at the end of the instance. * @param model model to add at the end of the instance * @exception DerivativeException if user code called from step interpolator * finalization triggers one * @exception IllegalArgumentException if the model to append is not * compatible with the instance (dimension of the state vector, * propagation direction, hole between the dates) */ public void append(final ContinuousOutputModel model) throws DerivativeException { if (model.steps.size() == 0) { return; } if (steps.size() == 0) { initialTime = model.initialTime; forward = model.forward; } else { if (getInterpolatedState().length != model.getInterpolatedState().length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, getInterpolatedState().length, model.getInterpolatedState().length); } if (forward ^ model.forward) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.PROPAGATION_DIRECTION_MISMATCH); } final StepInterpolator lastInterpolator = steps.get(index); final double current = lastInterpolator.getCurrentTime(); final double previous = lastInterpolator.getPreviousTime(); final double step = current - previous; final double gap = model.getInitialTime() - current; if (FastMath.abs(gap) > 1.0e-3 * FastMath.abs(step)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.HOLE_BETWEEN_MODELS_TIME_RANGES, FastMath.abs(gap)); } } for (StepInterpolator interpolator : model.steps) { steps.add(interpolator.copy()); } index = steps.size() - 1; finalTime = (steps.get(index)).getCurrentTime(); } /** Determines whether this handler needs dense output. *

                      The essence of this class is to provide dense output over all * steps, hence it requires the internal steps to provide themselves * dense output. The method therefore returns always true.

                      * @return always true */ public boolean requiresDenseOutput() { return true; } /** Reset the step handler. * Initialize the internal data as required before the first step is * handled. */ public void reset() { initialTime = Double.NaN; finalTime = Double.NaN; forward = true; index = 0; steps.clear(); } /** Handle the last accepted step. * A copy of the information provided by the last step is stored in * the instance for later use. * @param interpolator interpolator for the last accepted step. * @param isLast true if the step is the last one * @exception DerivativeException if user code called from step interpolator * finalization triggers one */ public void handleStep(final StepInterpolator interpolator, final boolean isLast) throws DerivativeException { if (steps.size() == 0) { initialTime = interpolator.getPreviousTime(); forward = interpolator.isForward(); } steps.add(interpolator.copy()); if (isLast) { finalTime = interpolator.getCurrentTime(); index = steps.size() - 1; } } /** * Get the initial integration time. * @return initial integration time */ public double getInitialTime() { return initialTime; } /** * Get the final integration time. * @return final integration time */ public double getFinalTime() { return finalTime; } /** * Get the time of the interpolated point. * If {@link #setInterpolatedTime} has not been called, it returns * the final integration time. * @return interpolation point time */ public double getInterpolatedTime() { return steps.get(index).getInterpolatedTime(); } /** Set the time of the interpolated point. *

                      This method should not be called before the * integration is over because some internal variables are set only * once the last step has been handled.

                      *

                      Setting the time outside of the integration interval is now * allowed (it was not allowed up to version 5.9 of Mantissa), but * should be used with care since the accuracy of the interpolator * will probably be very poor far from this interval. This allowance * has been added to simplify implementation of search algorithms * near the interval endpoints.

                      * @param time time of the interpolated point */ public void setInterpolatedTime(final double time) { // initialize the search with the complete steps table int iMin = 0; final StepInterpolator sMin = steps.get(iMin); double tMin = 0.5 * (sMin.getPreviousTime() + sMin.getCurrentTime()); int iMax = steps.size() - 1; final StepInterpolator sMax = steps.get(iMax); double tMax = 0.5 * (sMax.getPreviousTime() + sMax.getCurrentTime()); // handle points outside of the integration interval // or in the first and last step if (locatePoint(time, sMin) <= 0) { index = iMin; sMin.setInterpolatedTime(time); return; } if (locatePoint(time, sMax) >= 0) { index = iMax; sMax.setInterpolatedTime(time); return; } // reduction of the table slice size while (iMax - iMin > 5) { // use the last estimated index as the splitting index final StepInterpolator si = steps.get(index); final int location = locatePoint(time, si); if (location < 0) { iMax = index; tMax = 0.5 * (si.getPreviousTime() + si.getCurrentTime()); } else if (location > 0) { iMin = index; tMin = 0.5 * (si.getPreviousTime() + si.getCurrentTime()); } else { // we have found the target step, no need to continue searching si.setInterpolatedTime(time); return; } // compute a new estimate of the index in the reduced table slice final int iMed = (iMin + iMax) / 2; final StepInterpolator sMed = steps.get(iMed); final double tMed = 0.5 * (sMed.getPreviousTime() + sMed.getCurrentTime()); if ((FastMath.abs(tMed - tMin) < 1e-6) || (FastMath.abs(tMax - tMed) < 1e-6)) { // too close to the bounds, we estimate using a simple dichotomy index = iMed; } else { // estimate the index using a reverse quadratic polynom // (reverse means we have i = P(t), thus allowing to simply // compute index = P(time) rather than solving a quadratic equation) final double d12 = tMax - tMed; final double d23 = tMed - tMin; final double d13 = tMax - tMin; final double dt1 = time - tMax; final double dt2 = time - tMed; final double dt3 = time - tMin; final double iLagrange = ((dt2 * dt3 * d23) * iMax - (dt1 * dt3 * d13) * iMed + (dt1 * dt2 * d12) * iMin) / (d12 * d23 * d13); index = (int) FastMath.rint(iLagrange); } // force the next size reduction to be at least one tenth final int low = FastMath.max(iMin + 1, (9 * iMin + iMax) / 10); final int high = FastMath.min(iMax - 1, (iMin + 9 * iMax) / 10); if (index < low) { index = low; } else if (index > high) { index = high; } } // now the table slice is very small, we perform an iterative search index = iMin; while ((index <= iMax) && (locatePoint(time, steps.get(index)) > 0)) { ++index; } steps.get(index).setInterpolatedTime(time); } /** * Get the state vector of the interpolated point. * @return state vector at time {@link #getInterpolatedTime} * @exception DerivativeException if user code called from step interpolator * finalization triggers one */ public double[] getInterpolatedState() throws DerivativeException { return steps.get(index).getInterpolatedState(); } /** Compare a step interval and a double. * @param time point to locate * @param interval step interval * @return -1 if the double is before the interval, 0 if it is in * the interval, and +1 if it is after the interval, according to * the interval direction */ private int locatePoint(final double time, final StepInterpolator interval) { if (forward) { if (time < interval.getPreviousTime()) { return -1; } else if (time > interval.getCurrentTime()) { return +1; } else { return 0; } } if (time > interval.getPreviousTime()) { return -1; } else if (time < interval.getCurrentTime()) { return +1; } else { return 0; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ode/FirstOrderConverter.java100644 1750 1750 11322 11532241246 27751 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.ode; import org.apache.commons.math.ode.DerivativeException; /** This class converts second order differential equations to first * order ones. * *

                      This class is a wrapper around a {@link * SecondOrderDifferentialEquations} which allow to use a {@link * FirstOrderIntegrator} to integrate it.

                      * *

                      The transformation is done by changing the n dimension state * vector to a 2n dimension vector, where the first n components are * the initial state variables and the n last components are their * first time derivative. The first time derivative of this state * vector then really contains both the first and second time * derivative of the initial state vector, which can be handled by the * underlying second order equations set.

                      * *

                      One should be aware that the data is duplicated during the * transformation process and that for each call to {@link * #computeDerivatives computeDerivatives}, this wrapper does copy 4n * scalars : 2n before the call to {@link * SecondOrderDifferentialEquations#computeSecondDerivatives * computeSecondDerivatives} in order to dispatch the y state vector * into z and zDot, and 2n after the call to gather zDot and zDDot * into yDot. Since the underlying problem by itself perhaps also * needs to copy data and dispatch the arrays into domain objects, * this has an impact on both memory and CPU usage. The only way to * avoid this duplication is to perform the transformation at the * problem level, i.e. to implement the problem as a first order one * and then avoid using this class.

                      * * @see FirstOrderIntegrator * @see FirstOrderDifferentialEquations * @see SecondOrderDifferentialEquations * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 1.2 */ public class FirstOrderConverter implements FirstOrderDifferentialEquations { /** Underlying second order equations set. */ private final SecondOrderDifferentialEquations equations; /** second order problem dimension. */ private final int dimension; /** state vector. */ private final double[] z; /** first time derivative of the state vector. */ private final double[] zDot; /** second time derivative of the state vector. */ private final double[] zDDot; /** Simple constructor. * Build a converter around a second order equations set. * @param equations second order equations set to convert */ public FirstOrderConverter (final SecondOrderDifferentialEquations equations) { this.equations = equations; dimension = equations.getDimension(); z = new double[dimension]; zDot = new double[dimension]; zDDot = new double[dimension]; } /** Get the dimension of the problem. *

                      The dimension of the first order problem is twice the * dimension of the underlying second order problem.

                      * @return dimension of the problem */ public int getDimension() { return 2 * dimension; } /** Get the current time derivative of the state vector. * @param t current value of the independent time variable * @param y array containing the current value of the state vector * @param yDot placeholder array where to put the time derivative of the state vector * @throws DerivativeException this exception is propagated to the caller if the * underlying user function triggers one */ public void computeDerivatives(final double t, final double[] y, final double[] yDot) throws DerivativeException { // split the state vector in two System.arraycopy(y, 0, z, 0, dimension); System.arraycopy(y, dimension, zDot, 0, dimension); // apply the underlying equations set equations.computeSecondDerivatives(t, z, zDot, zDDot); // build the result state derivative System.arraycopy(zDot, 0, yDot, 0, dimension); System.arraycopy(zDDot, 0, yDot, dimension, dimension); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/FieldElement.java100644 1750 1750 3740 11532241247 25552 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; /** * Interface representing field elements. * @param the type of the field elements * @see Field * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface FieldElement { /** Compute this + a. * @param a element to add * @return a new element representing this + a */ T add(T a); /** Compute this - a. * @param a element to subtract * @return a new element representing this - a */ T subtract(T a); /** Compute this × a. * @param a element to multiply * @return a new element representing this × a */ T multiply(T a); /** Compute this ÷ a. * @param a element to add * @return a new element representing this ÷ a * @exception ArithmeticException if a is the zero of the * additive operation (i.e. additive identity) */ T divide(T a) throws ArithmeticException; /** Get the {@link Field} to which the instance belongs. * @return {@link Field} to which the instance belongs */ Field getField(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NullArgumentException.java100644 1750 1750 3615 11532241244 31505 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * All conditions checks that fail due to a {@code null} argument must throw * this exception. * This class is meant to signal a precondition violation ("null is an illegal * argument") and so does not extend the standard {@code NullPointerException}. * Proagation of {@code NullPointerException} from within Commons-Math is * construed to be a bug. * * @since 2.2 * @version $Revision$ $Date$ */ public class NullArgumentException extends MathIllegalArgumentException { /** Serializable version Id. */ private static final long serialVersionUID = -6024911025449780478L; /** * Default constructor. */ public NullArgumentException() { super(LocalizedFormats.NULL_NOT_ALLOWED); } /** * @param specific Message pattern providing the specific context of * the error. */ public NullArgumentException(Localizable specific) { super(specific, LocalizedFormats.NULL_NOT_ALLOWED); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java100644 1750 1750 5627 11532241244 32274 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when a number is too small. * * @since 2.2 * @version $Revision$ $Date$ */ public class NumberIsTooSmallException extends MathIllegalNumberException { /** Serializable version Id. */ private static final long serialVersionUID = -6100997100383932834L; /** * Higher bound. */ private final Number min; /** * Whether the maximum is included in the allowed range. */ private final boolean boundIsAllowed; /** * Construct the exception. * * @param wrong Value that is smaller than the minimum. * @param min minimum. * @param boundIsAllowed Whether {@code min} is included in the allowed range. */ public NumberIsTooSmallException(Number wrong, Number min, boolean boundIsAllowed) { this(null, wrong, min, boundIsAllowed); } /** * Construct the exception with a specific context. * * @param specific Specific contexte pattern . * @param wrong Value that is smaller than the minimum. * @param min minimum. * @param boundIsAllowed Whether {@code min} is included in the allowed range. */ public NumberIsTooSmallException(Localizable specific, Number wrong, Number min, boolean boundIsAllowed) { super(specific, boundIsAllowed ? LocalizedFormats.NUMBER_TOO_SMALL : LocalizedFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED, wrong, min); this.min = min; this.boundIsAllowed = boundIsAllowed; } /** * @return {@code true} if the minimum is included in the allowed range. **/ public boolean getBoundIsAllowed() { return boundIsAllowed; } /** * @return the minimum. **/ public Number getMin() { return min; } } ././@LongLink100644 0 0 151 11532242443 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NonMonotonousSequenceException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NonMonotonousSequenceException.100644 1750 1750 10223 11532241244 32563 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when the a sequence of values is not monotonously * increasing or decreasing. * * @since 2.2 * @version $Revision$ $Date$ */ public class NonMonotonousSequenceException extends MathIllegalNumberException { /** Serializable version Id. */ private static final long serialVersionUID = 3596849179428944575L; /** * Direction (positive for increasing, negative for decreasing). */ private final MathUtils.OrderDirection direction; /** * Whether the sequence must be strictly increasing or decreasing. */ private final boolean strict; /** * Index of the wrong value. */ private final int index; /** * Previous value. */ private final Number previous; /** * Construct the exception. * This constructor uses default values assuming that the sequence should * have been strictly increasing. * * @param wrong Value that did not match the requirements. * @param previous Previous value in the sequence. * @param index Index of the value that did not match the requirements. */ public NonMonotonousSequenceException(Number wrong, Number previous, int index) { this(wrong, previous, index, MathUtils.OrderDirection.INCREASING, true); } /** * Construct the exception. * * @param wrong Value that did not match the requirements. * @param previous Previous value in the sequence. * @param index Index of the value that did not match the requirements. * @param direction Strictly positive for a sequence required to be * increasing, negative (or zero) for a decreasing sequence. * @param strict Whether the sequence must be strictly increasing or * decreasing. */ public NonMonotonousSequenceException(Number wrong, Number previous, int index, MathUtils.OrderDirection direction, boolean strict) { super(direction == MathUtils.OrderDirection.INCREASING ? (strict ? LocalizedFormats.NOT_STRICTLY_INCREASING_SEQUENCE : LocalizedFormats.NOT_INCREASING_SEQUENCE) : (strict ? LocalizedFormats.NOT_STRICTLY_DECREASING_SEQUENCE : LocalizedFormats.NOT_DECREASING_SEQUENCE), wrong, previous, index, index - 1); this.direction = direction; this.strict = strict; this.index = index; this.previous = previous; } /** * @return the order direction. **/ public MathUtils.OrderDirection getDirection() { return direction; } /** * @return {@code true} is the sequence should be strictly monotonous. **/ public boolean getStrict() { return strict; } /** * Get the index of the wrong value. * * @return the current index. */ public int getIndex() { return index; } /** * @return the previous value. */ public Number getPrevious() { return previous; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NotPositiveException.java100644 1750 1750 3237 11532241244 31353 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; /** * Exception to be thrown when the argument is negative. * * @since 2.2 * @version $Revision$ $Date$ */ public class NotPositiveException extends NumberIsTooSmallException { /** Serializable version Id. */ private static final long serialVersionUID = -2250556892093726375L; /** * Construct the exception. * * @param value Argument. */ public NotPositiveException(Number value) { super(value, 0, true); } /** * Construct the exception with a specific context. * * @param specific Specific context where the error occurred. * @param value Argument. */ public NotPositiveException(Localizable specific, Number value) { super(specific, value, 0, true); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/ZeroException.java100644 1750 1750 3234 11532241244 30004 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when zero is provided where it is not allowed. * * @since 2.2 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class ZeroException extends MathIllegalNumberException { /** Serializable version identifier */ private static final long serialVersionUID = -1960874856936000015L; /** * Construct the exception. */ public ZeroException() { this(null); } /** * Construct the exception with a specific context. * * @param specific Specific contexte pattern . */ public ZeroException(Localizable specific) { super(specific, LocalizedFormats.ZERO_NOT_ALLOWED, 0); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.ja100644 1750 1750 7110 11532241244 32421 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import java.util.Locale; import org.apache.commons.math.exception.util.ArgUtils; import org.apache.commons.math.exception.util.MessageFactory; import org.apache.commons.math.exception.util.Localizable; /** * Base class for all preconditions violation exceptions. * This class is not intended to be instantiated directly: it should serve * as a base class to create all the exceptions that share the semantics of * the standard {@link IllegalArgumentException}, but must also provide a * localized message. * * @since 2.2 * @version $Revision$ $Date$ */ public class MathIllegalArgumentException extends IllegalArgumentException implements MathThrowable { /** Serializable version Id. */ private static final long serialVersionUID = -6024911025449780478L; /** * Pattern used to build the message (specific context). */ private final Localizable specific; /** * Pattern used to build the message (general problem description). */ private final Localizable general; /** * Arguments used to build the message. */ private final Object[] arguments; /** * @param specific Message pattern providing the specific context of * the error. * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ protected MathIllegalArgumentException(Localizable specific, Localizable general, Object ... args) { this.specific = specific; this.general = general; arguments = ArgUtils.flatten(args); } /** * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ protected MathIllegalArgumentException(Localizable general, Object ... args) { this(null, general, args); } /** {@inheritDoc} */ public Localizable getSpecificPattern() { return specific; } /** {@inheritDoc} */ public Localizable getGeneralPattern() { return general; } /** {@inheritDoc} */ public Object[] getArguments() { return arguments.clone(); } /** * Get the message in a specified locale. * * @param locale Locale in which the message should be translated. * * @return the localized message. */ public String getMessage(final Locale locale) { return MessageFactory.buildMessage(locale, specific, general, arguments); } /** {@inheritDoc} */ @Override public String getMessage() { return getMessage(Locale.US); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } } ././@LongLink100644 0 0 147 11532242443 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.ja100644 1750 1750 3301 11532241244 32552 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; /** * Exception to be thrown when the argument is negative. * * @since 2.2 * @version $Revision$ $Date$ */ public class NotStrictlyPositiveException extends NumberIsTooSmallException { /** Serializable version Id. */ private static final long serialVersionUID = -7824848630829852237L; /** * Construct the exception. * * @param value Argument. */ public NotStrictlyPositiveException(Number value) { super(value, 0, false); } /** * Construct the exception with a specific context. * * @param specific Specific context where the error occurred. * @param value Argument. */ public NotStrictlyPositiveException(Localizable specific, Number value) { super(specific, value, 0, false); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathIllegalStateException.java100644 1750 1750 10606 11532241244 32272 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import java.util.Locale; import org.apache.commons.math.exception.util.ArgUtils; import org.apache.commons.math.exception.util.MessageFactory; import org.apache.commons.math.exception.util.Localizable; /** * Base class for all exceptions that signal a mismatch between the * current state and the user's expectations. * * @since 2.2 * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $ */ public class MathIllegalStateException extends IllegalStateException implements MathThrowable { /** Serializable version Id. */ private static final long serialVersionUID = -6024911025449780478L; /** * Pattern used to build the message (specific context). */ private final Localizable specific; /** * Pattern used to build the message (general problem description). */ private final Localizable general; /** * Arguments used to build the message. */ private final Object[] arguments; /** * Simple constructor. * @param specific Message pattern providing the specific context of * the error. * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ public MathIllegalStateException(Localizable specific, Localizable general, Object ... args) { this(null, specific, general, args); } /** * Simple constructor. * @param cause root cause * @param specific Message pattern providing the specific context of * the error. * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ public MathIllegalStateException(Throwable cause, Localizable specific, Localizable general, Object ... args) { super(cause); this.specific = specific; this.general = general; arguments = ArgUtils.flatten(args); } /** * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ public MathIllegalStateException(Localizable general, Object ... args) { this(null, null, general, args); } /** * Simple constructor. * @param cause root cause * @param general Message pattern explaining the cause of the error. * @param args Arguments. */ public MathIllegalStateException(Throwable cause, Localizable general, Object ... args) { this(cause, null, general, args); } /** {@inheritDoc} */ public Localizable getSpecificPattern() { return specific; } /** {@inheritDoc} */ public Localizable getGeneralPattern() { return general; } /** {@inheritDoc} */ public Object[] getArguments() { return arguments.clone(); } /** * Get the message in a specified locale. * * @param locale Locale in which the message should be translated. * * @return the localized message. */ public String getMessage(final Locale locale) { return MessageFactory.buildMessage(locale, specific, general, arguments); } /** {@inheritDoc} */ @Override public String getMessage() { return getMessage(Locale.US); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathIllegalNumberException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathIllegalNumberException.java100644 1750 1750 4762 11532241244 32430 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; /** * Base class for exceptions raised by a wrong number. * This class is not intended to be instantiated directly: it should serve * as a base class to create all the exceptions that are raised because some * precondition is violated by a number argument. * * @since 2.2 * @version $Revision$ $Date$ */ public class MathIllegalNumberException extends MathIllegalArgumentException { /** Serializable version Id. */ private static final long serialVersionUID = -7447085893598031110L; /** Requested. */ private final Number argument; /** * Construct an exception. * * @param specific Localizable pattern. * @param general Localizable pattern. * @param wrong wrong number * @param arguments Arguments. */ protected MathIllegalNumberException(Localizable specific, Localizable general, Number wrong, Object ... arguments) { super(specific, general, wrong, arguments); argument = wrong; } /** * Construct an exception. * * @param general Localizable pattern. * @param wrong wrong number * @param arguments Arguments. */ protected MathIllegalNumberException(Localizable general, Number wrong, Object ... arguments) { super(general, wrong, arguments); argument = wrong; } /** * @return the requested value. */ public Number getArgument() { return argument; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java100644 1750 1750 5623 11532241244 32252 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when a number is too large. * * @since 2.2 * @version $Revision$ $Date$ */ public class NumberIsTooLargeException extends MathIllegalNumberException { /** Serializable version Id. */ private static final long serialVersionUID = 4330003017885151975L; /** * Higher bound. */ private final Number max; /** * Whether the maximum is included in the allowed range. */ private final boolean boundIsAllowed; /** * Construct the exception. * * @param wrong Value that is larger than the maximum. * @param max maximum. * @param boundIsAllowed if true the maximum is included in the allowed range. */ public NumberIsTooLargeException(Number wrong, Number max, boolean boundIsAllowed) { this(null, wrong, max, boundIsAllowed); } /** * Construct the exception with a specific context. * * @param specific Specific contexte pattern . * @param wrong Value that is larger than the maximum. * @param max maximum. * @param boundIsAllowed if true the maximum is included in the allowed range. */ public NumberIsTooLargeException(Localizable specific, Number wrong, Number max, boolean boundIsAllowed) { super(specific, boundIsAllowed ? LocalizedFormats.NUMBER_TOO_LARGE : LocalizedFormats.NUMBER_TOO_LARGE_BOUND_EXCLUDED, wrong, max); this.max = max; this.boundIsAllowed = boundIsAllowed; } /** * @return {@code true} if the maximum is included in the allowed range. **/ public boolean getBoundIsAllowed() { return boundIsAllowed; } /** * @return the maximum. **/ public Number getMax() { return max; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/NoDataException.java100644 1750 1750 3161 11532241244 30232 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when the required data is missing. * * @since 2.2 * @version $Revision$ $Date$ */ public class NoDataException extends MathIllegalStateException { /** Serializable version Id. */ private static final long serialVersionUID = -3629324471511904459L; /** * Construct the exception. */ public NoDataException() { this(null); } /** * Construct the exception with a specific context. * * @param specific Contextual information on what caused the exception. */ public NoDataException(Localizable specific) { super(specific, LocalizedFormats.NO_DATA, (Object[]) null); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/ConvergenceException.java100644 1750 1750 4176 11532241244 31331 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a numerical computation can not be performed because the * numerical result failed to converge to a finite value. * * @since 2.2 * @version $Revision: 1026666 $ $Date: 2010-10-23 21:30:48 +0200 (sam. 23 oct. 2010) $ */ public class ConvergenceException extends MathIllegalStateException { /** Serializable version Id. */ private static final long serialVersionUID = 4330003017885151975L; /** * Construct the exception. */ public ConvergenceException() { this(null); } /** * Construct the exception with a specific context. * * @param specific Specific contexte pattern. */ public ConvergenceException(Localizable specific) { this(specific, LocalizedFormats.CONVERGENCE_FAILED, null); } /** * Construct the exception with a specific context and arguments. * * @param specific Specific contexte pattern. * @param args Arguments. */ public ConvergenceException(Localizable specific, Object ... args) { super(specific, LocalizedFormats.CONVERGENCE_FAILED, args); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathThrowable.java100644 1750 1750 4317 11532241244 27752 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import java.util.Locale; import org.apache.commons.math.exception.util.Localizable; /** * Interface for commons-math throwables. * * @version $Revision: 1035475 $ $Date: 2010-11-15 23:39:25 +0100 (lun. 15 nov. 2010) $ * @since 2.2 */ public interface MathThrowable { /** Gets the localizable pattern used to build the specific part of the message of this throwable. * @return localizable pattern used to build the specific part of the message of this throwable */ Localizable getSpecificPattern(); /** Gets the localizable pattern used to build the general part of the message of this throwable. * @return localizable pattern used to build the general part of the message of this throwable */ Localizable getGeneralPattern(); /** Gets the arguments used to build the message of this throwable. * @return the arguments used to build the message of this throwable */ Object[] getArguments(); /** Gets the message in a specified locale. * @param locale Locale in which the message should be translated * @return localized message */ String getMessage(final Locale locale); /** Gets the message in a conventional US locale. * @return localized message */ String getMessage(); /** Gets the message in the system default locale. * @return localized message */ String getLocalizedMessage(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/package.html100644 1750 1750 2022 11532241244 26616 0ustarlucluc 0 0 Specialized exceptions for algorithms errors. The exceptions can be localized using simple java properties. ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationExcepti100644 1750 1750 6476 11532241244 32646 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import java.util.Locale; import org.apache.commons.math.exception.util.ArgUtils; import org.apache.commons.math.exception.util.MessageFactory; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Base class for all unsupported features. * It is used for all the exceptions that share the semantics of the standard * {@link UnsupportedOperationException}, but must also provide a localized * message. * * @since 2.2 * @version $Revision$ $Date$ */ public class MathUnsupportedOperationException extends UnsupportedOperationException implements MathThrowable { /** Serializable version Id. */ private static final long serialVersionUID = -6024911025449780478L; /** * Pattern used to build the message (specific context). */ private final Localizable specific; /** * Arguments used to build the message. */ private final Object[] arguments; /** * @param args Arguments. */ public MathUnsupportedOperationException(Object ... args) { this(null, args); } /** * @param specific Message pattern providing the specific context of * the error. * @param args Arguments. */ public MathUnsupportedOperationException(Localizable specific, Object ... args) { this.specific = specific; arguments = ArgUtils.flatten(args); } /** {@inheritDoc} */ public Localizable getSpecificPattern() { return specific; } /** {@inheritDoc} */ public Localizable getGeneralPattern() { return LocalizedFormats.UNSUPPORTED_OPERATION; } /** {@inheritDoc} */ public Object[] getArguments() { return arguments.clone(); } /** * Get the message in a specified locale. * * @param locale Locale in which the message should be translated. * * @return the localized message. */ public String getMessage(final Locale locale) { return MessageFactory.buildMessage(locale, specific, LocalizedFormats.UNSUPPORTED_OPERATION, arguments); } /** {@inheritDoc} */ @Override public String getMessage() { return getMessage(Locale.US); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/OutOfRangeException.java100644 1750 1750 3640 11532241244 31077 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when some argument is out of range. * * @since 2.2 * @version $Revision$ $Date$ */ public class OutOfRangeException extends MathIllegalNumberException { /** Serializable version Id. */ private static final long serialVersionUID = 111601815794403609L; /** Lower bound. */ private final Number lo; /** Higher bound. */ private final Number hi; /** * Construct an exception from the mismatched dimensions. * * @param wrong Requested value. * @param lo Lower bound. * @param hi Higher bound. */ public OutOfRangeException(Number wrong, Number lo, Number hi) { super(LocalizedFormats.OUT_OF_RANGE_SIMPLE, wrong, lo, hi); this.lo = lo; this.hi = hi; } /** * @return the lower bound. */ public Number getLo() { return lo; } /** * @return the higher bound. */ public Number getHi() { return hi; } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/DimensionMismatchException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/exception/DimensionMismatchException.java100644 1750 1750 3357 11532241244 32506 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception to be thrown when two dimensions differ. * * @since 2.2 * @version $Revision$ $Date$ */ public class DimensionMismatchException extends MathIllegalNumberException { /** Serializable version Id. */ private static final long serialVersionUID = -8415396756375798143L; /** Correct dimension. */ private final int dimension; /** * Construct an exception from the mismatched dimensions. * * @param wrong Wrong dimension. * @param expected Expected dimension. */ public DimensionMismatchException(int wrong, int expected) { super(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, wrong, expected); dimension = expected; } /** * @return the expected dimension. */ public int getDimension() { return dimension; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/MathInternalError.java100644 1750 1750 3323 11532241244 30605 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Exception triggered when something that shouldn't happen does happen. * * @since 2.2 * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $ */ public class MathInternalError extends MathIllegalStateException { /** Serializable version Id. */ private static final long serialVersionUID = -6276776513966934846L; /** URL for reporting problems. */ private static final String REPORT_URL = "https://issues.apache.org/jira/browse/MATH"; /** * Simple constructor. */ public MathInternalError() { super(LocalizedFormats.INTERNAL_ERROR, REPORT_URL); } /** * Simple constructor. * @param cause root cause */ public MathInternalError(final Throwable cause) { super(LocalizedFormats.INTERNAL_ERROR, REPORT_URL); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/DummyLocalizable.java100644 1750 1750 3350 11532241244 31417 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.util.Locale; /** * Dummy implementation of the {@link Localizable} interface, without localization. * * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class DummyLocalizable implements Localizable { /** Serializable version identifier. */ private static final long serialVersionUID = 8843275624471387299L; /** Source string. */ private final String source; /** Simple constructor. * @param source source text */ public DummyLocalizable(final String source) { this.source = source; } /** {@inheritDoc} */ public String getSourceString() { return source; } /** {@inheritDoc} */ public String getLocalizedString(Locale locale) { return source; } /** {@inheritDoc} */ @Override public String toString() { return source; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java100644 1750 1750 3531 11532241244 27715 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.util.List; import java.util.ArrayList; /** * Utility class for transforming the list of arguments passed to * constructors of exceptions. * * @version $Revision$ $Date$ * @since 2.2 */ public class ArgUtils { /** * Private constructor */ private ArgUtils() { } /** * Transform a multidimensional array into a one-dimensional list. * * @param array Array (possibly multidimensional). * @return a list of all the {@code Object} instances contained in * {@code array}. */ public static Object[] flatten(Object[] array) { final List list = new ArrayList(); if (array != null) { for (Object o : array) { if (o instanceof Object[]) { for (Object oR : flatten((Object[]) o)) { list.add(oR); } } else { list.add(o); } } } return list.toArray(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/package.html100644 1750 1750 1716 11532241244 27604 0ustarlucluc 0 0 Classes supporting exception localization. commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java100644 1750 1750 5610 11532241244 31077 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.text.MessageFormat; import java.util.Locale; /** * Class for constructing localized messages. * * @since 2.2 * @version $Revision$ $Date$ */ public class MessageFactory { /** * Class contains only static methods. */ private MessageFactory() {} /** * Builds a message string by from a pattern and its arguments. * * @param locale Locale in which the message should be translated. * @param pattern Format specifier. * @param arguments Format arguments. * @return a localized message string. */ public static String buildMessage(Locale locale, Localizable pattern, Object ... arguments) { return buildMessage(locale, null, pattern, arguments); } /** * Builds a message string by from two patterns (specific and general) and * an argument list. * * @param locale Locale in which the message should be translated. * @param specific Format specifier (may be null). * @param general Format specifier (may be null). * @param arguments Format arguments. They will be substituted in * both the {@code general} and {@code specific} format specifiers. * @return a localized message string. */ public static String buildMessage(Locale locale, Localizable specific, Localizable general, Object ... arguments) { final StringBuilder sb = new StringBuilder(); if (general != null) { final MessageFormat fmt = new MessageFormat(general.getLocalizedString(locale), locale); sb.append(fmt.format(arguments)); } if (specific != null) { if (general != null) { sb.append(": "); } final MessageFormat fmt = new MessageFormat(specific.getLocalizedString(locale), locale); sb.append(fmt.format(arguments)); } return sb.toString(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/Localizable.java100644 1750 1750 2706 11532241244 30407 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.io.Serializable; import java.util.Locale; /** * Interface for localizable strings. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.2 */ public interface Localizable extends Serializable { /** * Get the source (non-localized) string. * @return source string */ String getSourceString(); /** * Get the localized string. * @param locale locale into which to get the string * @return localized string or the source string if no localized version is available */ String getLocalizedString(Locale locale); } commons-math-2.2-src/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java100644 1750 1750 61175 11532241244 31455 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.exception.util; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * Enumeration for localized messages formats used in exceptions messages. *

                      * The constants in this enumeration represent the available * formats as localized strings. These formats are intended to be * localized using simple properties files, using the constant * name as the key and the property value as the message format. * The source English format is provided in the constants themselves * to serve both as a reminder for developers to understand the parameters * needed by each format, as a basis for translators to create * localized properties files, and as a default format if some * translation is missing. *

                      * @since 2.2 * @version $Revision: 1073165 $ $Date: 2011-02-21 23:04:14 +0100 (lun. 21 févr. 2011) $ */ public enum LocalizedFormats implements Localizable { // CHECKSTYLE: stop MultipleVariableDeclarations // CHECKSTYLE: stop JavadocVariable ARGUMENT_OUTSIDE_DOMAIN("Argument {0} outside domain [{1} ; {2}]"), ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1("array sizes should have difference 1 ({0} != {1} + 1)"), ARRAY_SUMS_TO_ZERO("array sums to zero"), ASSYMETRIC_EIGEN_NOT_SUPPORTED("eigen decomposition of assymetric matrices not supported yet"), AT_LEAST_ONE_COLUMN("matrix must have at least one column"), AT_LEAST_ONE_ROW("matrix must have at least one row"), BANDWIDTH_OUT_OF_INTERVAL("bandwidth must be in the interval [0,1], but got {0}"), BINOMIAL_INVALID_PARAMETERS_ORDER("must have n >= k for binomial coefficient (n,k), got n = {0}, k = {1}"), BINOMIAL_NEGATIVE_PARAMETER("must have n >= 0 for binomial coefficient (n,k), got n = {0}"), CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be cleared"), CANNOT_COMPUTE_0TH_ROOT_OF_UNITY("cannot compute 0-th root of unity, indefinite result"), CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA("cannot compute beta density at 0 when alpha = {0,number}"), CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA("cannot compute beta density at 1 when beta = %.3g"), CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N("cannot compute nth root for null or negative n: {0}"), CANNOT_CONVERT_OBJECT_TO_FRACTION("cannot convert given object to a fraction number: {0}"), CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS("cannot discard a negative number of elements ({0})"), CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR("cannot format a {0} instance as a 3D vector"), CANNOT_FORMAT_INSTANCE_AS_COMPLEX("cannot format a {0} instance as a complex number"), CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR("cannot format a {0} instance as a real vector"), CANNOT_FORMAT_OBJECT_TO_FRACTION("cannot format given object as a fraction number"), CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be incremented"), CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR("cannot normalize a zero norm vector"), CANNOT_RETRIEVE_AT_NEGATIVE_INDEX("elements cannot be retrieved from a negative array index {0}"), CANNOT_SET_AT_NEGATIVE_INDEX("cannot set an element at a negative index {0}"), CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY("cannot substitute an element from an empty array"), CANNOT_TRANSFORM_TO_DOUBLE("Conversion Exception in Transformation: {0}"), CARDAN_ANGLES_SINGULARITY("Cardan angles singularity"), CLASS_DOESNT_IMPLEMENT_COMPARABLE("class ({0}) does not implement Comparable"), CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT("the closest orthogonal matrix has a negative determinant {0}"), COLUMN_INDEX_OUT_OF_RANGE("column index {0} out of allowed range [{1}, {2}]"), CONTINUED_FRACTION_INFINITY_DIVERGENCE("Continued fraction convergents diverged to +/- infinity for value {0}"), CONTINUED_FRACTION_NAN_DIVERGENCE("Continued fraction diverged to NaN for value {0}"), CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR("contraction criteria ({0}) smaller than the expansion factor ({1}). This would lead to a never ending loop of expansion and contraction as a newly expanded internal storage array would immediately satisfy the criteria for contraction."), CONTRACTION_CRITERIA_SMALLER_THAN_ONE("contraction criteria smaller than one ({0}). This would lead to a never ending loop of expansion and contraction as an internal storage array length equal to the number of elements would satisfy the contraction criteria."), CONVERGENCE_FAILED("convergence failed"), CUMULATIVE_PROBABILITY_RETURNED_NAN("Cumulative probability function returned NaN for argument {0} p = {1}"), DIFFERENT_ROWS_LENGTHS("some rows have length {0} while others have length {1}"), DIGEST_NOT_INITIALIZED("digest not initialized"), DIMENSIONS_MISMATCH_2x2("dimensions mismatch: got {0}x{1} but expected {2}x{3}"), DIMENSIONS_MISMATCH_SIMPLE("dimensions mismatch {0} != {1}"), /* keep */ DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN("Discrete cumulative probability function returned NaN for argument {0}"), DISTRIBUTION_NOT_LOADED("distribution not loaded"), DUPLICATED_ABSCISSA("Abscissa {0} is duplicated at both indices {1} and {2}"), EMPTY_CLUSTER_IN_K_MEANS("empty cluster in k-means"), EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY("empty polynomials coefficients array"), /* keep */ EMPTY_SELECTED_COLUMN_INDEX_ARRAY("empty selected column index array"), EMPTY_SELECTED_ROW_INDEX_ARRAY("empty selected row index array"), EMPTY_STRING_FOR_IMAGINARY_CHARACTER("empty string for imaginary character"), ENDPOINTS_NOT_AN_INTERVAL("endpoints do not specify an interval: [{0}, {1}]"), EQUAL_VERTICES_IN_SIMPLEX("equal vertices {0} and {1} in simplex configuration"), EULER_ANGLES_SINGULARITY("Euler angles singularity"), EVALUATION_FAILED("evaluation failed for argument = {0}"), EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"), FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"), FAILED_BRACKETING("number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}, final a value={5}, final b value={6}, f(a)={7}, f(b)={8}"), FAILED_FRACTION_CONVERSION("Unable to convert {0} to fraction after {1} iterations"), FIRST_COLUMNS_NOT_INITIALIZED_YET("first {0} columns are not initialized yet"), FIRST_ELEMENT_NOT_ZERO("first element is not 0: {0}"), FIRST_ROWS_NOT_INITIALIZED_YET("first {0} rows are not initialized yet"), FRACTION_CONVERSION_OVERFLOW("Overflow trying to convert {0} to fraction ({1}/{2})"), FUNCTION_NOT_DIFFERENTIABLE("function is not differentiable"), FUNCTION_NOT_POLYNOMIAL("function is not polynomial"), GCD_OVERFLOW_32_BITS("overflow: gcd({0}, {1}) is 2^31"), GCD_OVERFLOW_64_BITS("overflow: gcd({0}, {1}) is 2^63"), HOLE_BETWEEN_MODELS_TIME_RANGES("{0} wide hole between models time ranges"), IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO("identical abscissas x[{0}] == x[{1}] == {2} cause division by zero"), INDEX_LARGER_THAN_MAX("the index specified: {0} is larger than the current maximal index {1}"), INDEX_NOT_POSITIVE("index ({0}) is not positive"), INDEX_OUT_OF_RANGE("index {0} out of allowed range [{1}, {2}]"), INFINITE_ARRAY_ELEMENT("Array contains an infinite element, {0} at index {1}"), INFINITE_VALUE_CONVERSION("cannot convert infinite value"), INITIAL_CAPACITY_NOT_POSITIVE("initial capacity ({0}) is not positive"), INITIAL_COLUMN_AFTER_FINAL_COLUMN("initial column {0} after final column {1}"), INITIAL_ROW_AFTER_FINAL_ROW("initial row {0} after final row {1}"), INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE("input data comes from unsupported datasource: {0}, supported sources: {1}, {2}"), INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES("instance of class {0} not comparable to existing values"), INSUFFICIENT_DATA_FOR_T_STATISTIC("insufficient data for t statistic, needs at least 2, got {0}"), INSUFFICIENT_DIMENSION("insufficient dimension {0}, must be at least {1}"), INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE("sample contains {0} observed points, at least {1} are required"), INSUFFICIENT_ROWS_AND_COLUMNS("insufficient data: only {0} rows and {1} columns."), INTEGRATION_METHOD_NEEDS_AT_LEAST_ONE_PREVIOUS_POINT("{0} method needs at least one previous point"), INTERNAL_ERROR("internal error, please fill a bug report at {0}"), INVALID_BRACKETING_PARAMETERS("invalid bracketing parameters: lower bound={0}, initial={1}, upper bound={2}"), INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS("invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}"), INVALID_ITERATIONS_LIMITS("invalid iteration limits: min={0}, max={1}"), INVALID_MAX_ITERATIONS("bad value for maximum iterations number: {0}"), INVALID_REGRESSION_ARRAY("input data array length = {0} does not match the number of observations = {1} and the number of regressors = {2}"), INVALID_ROUNDING_METHOD("invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})"), ITERATOR_EXHAUSTED("iterator exhausted"), LCM_OVERFLOW_32_BITS("overflow: lcm({0}, {1}) is 2^31"), LCM_OVERFLOW_64_BITS("overflow: lcm({0}, {1}) is 2^63"), LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE("list of chromosomes bigger than maxPopulationSize"), LOESS_EXPECTS_AT_LEAST_ONE_POINT("Loess expects at least 1 point"), LOWER_BOUND_NOT_BELOW_UPPER_BOUND("lower bound ({0}) must be strictly less than upper bound ({1})"), /* keep */ LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT("lower endpoint ({0}) must be less than or equal to upper endpoint ({1})"), MAP_MODIFIED_WHILE_ITERATING("map has been modified while iterating"), MAX_EVALUATIONS_EXCEEDED("maximal number of evaluations ({0}) exceeded"), MAX_ITERATIONS_EXCEEDED("maximal number of iterations ({0}) exceeded"), MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION("minimal step size ({0,number,0.00E00}) reached, integration needs {1,number,0.00E00}"), MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS("Loess expects the abscissa and ordinate arrays to be of the same size, but got {0} abscissae and {1} ordinatae"), NAN_ELEMENT_AT_INDEX("element {0} is NaN"), NAN_VALUE_CONVERSION("cannot convert NaN value"), NEGATIVE_BRIGHTNESS_EXPONENT("brightness exponent should be positive or null, but got {0}"), NEGATIVE_COMPLEX_MODULE("negative complex module {0}"), NEGATIVE_ELEMENT_AT_2D_INDEX("element ({0}, {1}) is negative: {2}"), NEGATIVE_ELEMENT_AT_INDEX("element {0} is negative: {1}"), NEGATIVE_NUMBER_OF_SUCCESSES("number of successes must be non-negative ({0})"), NEGATIVE_NUMBER_OF_TRIALS("number of trials must be non-negative ({0})"), NEGATIVE_ROBUSTNESS_ITERATIONS("the number of robustness iterations must be non-negative, but got {0}"), START_POSITION("start position ({0})"), /* keep */ NON_CONVERGENT_CONTINUED_FRACTION("Continued fraction convergents failed to converge for value {0}"), NON_POSITIVE_MICROSPHERE_ELEMENTS("number of microsphere elements must be positive, but got {0}"), NON_POSITIVE_POLYNOMIAL_DEGREE("polynomial degree must be positive: degree={0}"), NON_REAL_FINITE_ABSCISSA("all abscissae must be finite real numbers, but {0}-th is {1}"), NON_REAL_FINITE_ORDINATE("all ordinatae must be finite real numbers, but {0}-th is {1}"), NON_REAL_FINITE_WEIGHT("all weights must be finite real numbers, but {0}-th is {1}"), NON_SQUARE_MATRIX("a {0}x{1} matrix was provided instead of a square matrix"), NORMALIZE_INFINITE("Cannot normalize to an infinite value"), NORMALIZE_NAN("Cannot normalize to NaN"), NOT_ADDITION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not addition compatible"), NOT_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not decreasing ({2} < {3})"), NOT_DECREASING_SEQUENCE("points {3} and {2} are not decreasing ({1} < {0})"), /* keep */ NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS("not enough data ({0} rows) for this many predictors ({1} predictors)"), NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION("spline partition must have at least {0} points, got {1}"), NOT_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not increasing ({2} > {3})"), NOT_INCREASING_SEQUENCE("points {3} and {2} are not increasing ({1} > {0})"), /* keep */ NOT_MULTIPLICATION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not multiplication compatible"), NOT_OVERRIDEN("method not overriden"), NOT_POSITIVE_ALPHA("alpha must be positive ({0})"), NOT_POSITIVE_BETA("beta must be positive ({0})"), NOT_POSITIVE_COLUMNDIMENSION("invalid column dimension: {0} (must be positive)"), NOT_POSITIVE_DEFINITE_MATRIX("not positive definite matrix"), NOT_POSITIVE_DEGREES_OF_FREEDOM("degrees of freedom must be positive ({0})"), NOT_POSITIVE_ELEMENT_AT_INDEX("element {0} is not positive: {1}"), NOT_POSITIVE_EXPONENT("invalid exponent {0} (must be positive)"), NOT_POSITIVE_LENGTH("length must be positive ({0})"), LENGTH("length ({0})"), /* keep */ NOT_POSITIVE_MEAN("mean must be positive ({0})"), MEAN("mean ({0})"), /* keep */ NOT_POSITIVE_NUMBER_OF_SAMPLES("number of sample is not positive: {0}"), NUMBER_OF_SAMPLES("number of samples ({0})"), /* keep */ NOT_POSITIVE_PERMUTATION("permutation k ({0}) must be positive"), PERMUTATION_SIZE("permutation size ({0}"), /* keep */ NOT_POSITIVE_POISSON_MEAN("the Poisson mean must be positive ({0})"), NOT_POSITIVE_POPULATION_SIZE("population size must be positive ({0})"), NOT_POSITIVE_ROW_DIMENSION("invalid row dimension: {0} (must be positive)"), NOT_POSITIVE_SAMPLE_SIZE("sample size must be positive ({0})"), NOT_POSITIVE_SCALE("scale must be positive ({0})"), NOT_POSITIVE_SHAPE("shape must be positive ({0})"), NOT_POSITIVE_STANDARD_DEVIATION("standard deviation must be positive ({0})"), STANDARD_DEVIATION("standard deviation ({0})"), /* keep */ NOT_POSITIVE_UPPER_BOUND("upper bound must be positive ({0})"), NOT_POSITIVE_WINDOW_SIZE("window size must be positive ({0})"), NOT_POWER_OF_TWO("{0} is not a power of 2"), NOT_POWER_OF_TWO_CONSIDER_PADDING("{0} is not a power of 2, consider padding for fix"), NOT_POWER_OF_TWO_PLUS_ONE("{0} is not a power of 2 plus one"), NOT_STRICTLY_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly decreasing ({2} <= {3})"), NOT_STRICTLY_DECREASING_SEQUENCE("points {3} and {2} are not strictly decreasing ({1} <= {0})"), /* keep */ NOT_STRICTLY_INCREASING_KNOT_VALUES("knot values must be strictly increasing"), NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly increasing ({2} >= {3})"), NOT_STRICTLY_INCREASING_SEQUENCE("points {3} and {2} are not strictly increasing ({1} >= {0})"), /* keep */ NOT_SUBTRACTION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not subtraction compatible"), NOT_SYMMETRIC_MATRIX("not symmetric matrix"), NO_BIN_SELECTED("no bin selected"), NO_CONVERGENCE_WITH_ANY_START_POINT("none of the {0} start points lead to convergence"), NO_DATA("no data"), /* keep */ NO_DEGREES_OF_FREEDOM("no degrees of freedom ({0} measurements, {1} parameters)"), NO_DENSITY_FOR_THIS_DISTRIBUTION("This distribution does not have a density function implemented"), NO_FEASIBLE_SOLUTION("no feasible solution"), NO_OPTIMUM_COMPUTED_YET("no optimum computed yet"), NO_RESULT_AVAILABLE("no result available"), NO_SUCH_MATRIX_ENTRY("no entry at indices ({0}, {1}) in a {2}x{3} matrix"), NULL_NOT_ALLOWED("null is not allowed"), /* keep */ COVARIANCE_MATRIX("covariance matrix"), /* keep */ DENOMINATOR("denominator"), /* keep */ DENOMINATOR_FORMAT("denominator format"), /* keep */ FRACTION("fraction"), /* keep */ FUNCTION("function"), /* keep */ IMAGINARY_FORMAT("imaginary format"), /* keep */ INPUT_ARRAY("input array"), /* keep */ NUMERATOR("numerator"), /* keep */ NUMERATOR_FORMAT("numerator format"), /* keep */ OBJECT_TRANSFORMATION("conversion exception in transformation"), /* keep */ REAL_FORMAT("real format"), /* keep */ WHOLE_FORMAT("whole format"), /* keep */ NUMBER_TOO_LARGE("{0} is larger than the maximum ({1})"), /* keep */ NUMBER_TOO_SMALL("{0} is smaller than the minimum ({1})"), /* keep */ NUMBER_TOO_LARGE_BOUND_EXCLUDED("{0} is larger than, or equal to, the maximum ({1})"), /* keep */ NUMBER_TOO_SMALL_BOUND_EXCLUDED("{0} is smaller than, or equal to, the minimum ({1})"), /* keep */ NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE("number of successes ({0}) must be less than or equal to population size ({1})"), NUMERATOR_OVERFLOW_AFTER_MULTIPLY("overflow, numerator too large after multiply: {0}"), N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED("{0} points Legendre-Gauss integrator not supported, number of points must be in the {1}-{2} range"), OBSERVED_COUNTS_ALL_ZERO("observed counts are all 0 in observed array {0}"), OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY("observed counts are both zero for entry {0}"), OUT_OF_BOUNDS_QUANTILE_VALUE("out of bounds quantile value: {0}, must be in (0, 100]"), OUT_OF_BOUND_SIGNIFICANCE_LEVEL("out of bounds significance level {0}, must be between {1} and {2}"), OUT_OF_ORDER_ABSCISSA_ARRAY("the abscissae array must be sorted in a strictly increasing order, but the {0}-th element is {1} whereas {2}-th is {3}"), OUT_OF_RANGE_ROOT_OF_UNITY_INDEX("out of range root of unity index {0} (must be in [{1};{2}])"), OUT_OF_RANGE_SIMPLE("{0} out of [{1}, {2}] range"), /* keep */ OVERFLOW_IN_FRACTION("overflow in fraction {0}/{1}, cannot negate"), OVERFLOW_IN_ADDITION("overflow in addition: {0} + {1}"), OVERFLOW_IN_SUBTRACTION("overflow in subtraction: {0} - {1}"), PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"), PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"), PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */ POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS("number of polynomial interpolants must match the number of segments ({0} != {1} - 1)"), POPULATION_LIMIT_NOT_POSITIVE("population limit has to be positive"), POSITION_SIZE_MISMATCH_INPUT_ARRAY("position {0} and size {1} don't fit to the size of the input array {2}"), POWER_NEGATIVE_PARAMETERS("cannot raise an integral value to a negative power ({0}^{1})"), PROPAGATION_DIRECTION_MISMATCH("propagation direction mismatch"), RANDOMKEY_MUTATION_WRONG_CLASS("RandomKeyMutation works only with RandomKeys, not {0}"), ROOTS_OF_UNITY_NOT_COMPUTED_YET("roots of unity have not been computed yet"), ROTATION_MATRIX_DIMENSIONS("a {0}x{1} matrix cannot be a rotation matrix"), ROW_INDEX_OUT_OF_RANGE("row index {0} out of allowed range [{1}, {2}]"), SAME_SIGN_AT_ENDPOINTS("function values at endpoints do not have different signs, endpoints: [{0}, {1}], values: [{2}, {3}]"), SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE("sample size ({0}) exceeds collection size ({1})"), /* keep */ SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE("sample size ({0}) must be less than or equal to population size ({1})"), SIMPLEX_NEED_ONE_POINT("simplex must contain at least one point"), SIMPLE_MESSAGE("{0}"), SINGULAR_MATRIX("matrix is singular"), SUBARRAY_ENDS_AFTER_ARRAY_END("subarray ends after array end"), TOO_LARGE_CUTOFF_SINGULAR_VALUE("cutoff singular value is {0}, should be at most {1}"), TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY("cannot discard {0} elements from a {1} elements array"), TOO_SMALL_BANDWIDTH("the bandwidth must be large enough to accomodate at least 2 points. There are {0} data points, and bandwidth must be at least {1} but it is only {2}"), TOO_SMALL_COST_RELATIVE_TOLERANCE("cost relative tolerance is too small ({0}), no further reduction in the sum of squares is possible"), TOO_SMALL_INTEGRATION_INTERVAL("too small integration interval: length = {0}"), TOO_SMALL_ORTHOGONALITY_TOLERANCE("orthogonality tolerance is too small ({0}), solution is orthogonal to the jacobian"), TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE("parameters relative tolerance is too small ({0}), no further improvement in the approximate solution is possible"), TWO_OR_MORE_CATEGORIES_REQUIRED("two or more categories required, got {0}"), TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED("two or more values required in each category, one has {0}"), UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH("unable to bracket optimum in line search"), UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM("unable to compute covariances: singular problem"), UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS("unable to first guess the harmonic coefficients"), UNABLE_TO_ORTHOGONOLIZE_MATRIX("unable to orthogonalize matrix in {0} iterations"), UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN("unable to perform Q.R decomposition on the {0}x{1} jacobian matrix"), UNABLE_TO_SOLVE_SINGULAR_PROBLEM("unable to solve: singular problem"), UNBOUNDED_SOLUTION("unbounded solution"), UNKNOWN_MODE("unknown mode {0}, known modes: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) and {11} ({12})"), UNPARSEABLE_3D_VECTOR("unparseable 3D vector: \"{0}\""), UNPARSEABLE_COMPLEX_NUMBER("unparseable complex number: \"{0}\""), UNPARSEABLE_FRACTION_NUMBER("unparseable fraction number: \"{0}\""), UNPARSEABLE_REAL_VECTOR("unparseable real vector: \"{0}\""), UNSUPPORTED_EXPANSION_MODE("unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})"), UNSUPPORTED_OPERATION("unsupported operation"), /* keep */ USER_EXCEPTION("exception generated in user code"), /* keep */ URL_CONTAINS_NO_DATA("URL {0} contains no data"), VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC("{0} values have been added before statistic is configured"), VECTOR_LENGTH_MISMATCH("vector length mismatch: got {0} but expected {1}"), VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT("vector must have at least one element"), WEIGHT_AT_LEAST_ONE_NON_ZERO("weigth array must contain at least one non-zero value"), WRONG_BLOCK_LENGTH("wrong array shape (block length = {0}, expected {1})"), WRONG_NUMBER_OF_POINTS("{0} points are required, got only {1}"), NUMBER_OF_POINTS("number of points ({0})"), /* keep */ ZERO_DENOMINATOR("denominator must be different from 0"), ZERO_DENOMINATOR_IN_FRACTION("zero denominator in fraction {0}/{1}"), ZERO_FRACTION_TO_DIVIDE_BY("the fraction to divide by must not be zero: {0}/{1}"), ZERO_NORM("zero norm"), ZERO_NORM_FOR_ROTATION_AXIS("zero norm for rotation axis"), ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR("zero norm for rotation defining vector"), ZERO_NOT_ALLOWED("zero not allowed here"); // CHECKSTYLE: resume JavadocVariable // CHECKSTYLE: resume MultipleVariableDeclarations /** Source English format. */ private final String sourceFormat; /** Simple constructor. * @param sourceFormat source English format to use when no * localized version is available */ private LocalizedFormats(final String sourceFormat) { this.sourceFormat = sourceFormat; } /** {@inheritDoc} */ public String getSourceString() { return sourceFormat; } /** {@inheritDoc} */ public String getLocalizedString(final Locale locale) { try { ResourceBundle bundle = ResourceBundle.getBundle("META-INF/localization/LocalizedFormats", locale); if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) { // the value of the resource is the translated format return bundle.getString(toString()); } } catch (MissingResourceException mre) { // do nothing here } // either the locale is not supported or the resource is unknown // don't translate and fall back to using the source format return sourceFormat; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/MaxIterationsExceededException.java100644 1750 1750 6426 11532241247 31316 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a numerical computation exceeds its allowed * number of iterations. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class MaxIterationsExceededException extends ConvergenceException { /** Serializable version identifier. */ private static final long serialVersionUID = -7821226672760574694L; /** Maximal number of iterations allowed. */ private final int maxIterations; /** * Constructs an exception with a default detail message. * @param maxIterations maximal number of iterations allowed */ public MaxIterationsExceededException(final int maxIterations) { super(LocalizedFormats.MAX_ITERATIONS_EXCEEDED, maxIterations); this.maxIterations = maxIterations; } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param maxIterations the exceeded maximal number of iterations * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MaxIterationsExceededException(int, Localizable, Object...)} */ @Deprecated public MaxIterationsExceededException(final int maxIterations, final String pattern, final Object ... arguments) { this(maxIterations, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param maxIterations the exceeded maximal number of iterations * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MaxIterationsExceededException(final int maxIterations, final Localizable pattern, final Object ... arguments) { super(pattern, arguments); this.maxIterations = maxIterations; } /** Get the maximal number of iterations allowed. * @return maximal number of iterations allowed */ public int getMaxIterations() { return maxIterations; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ConvergenceException.java100644 1750 1750 7377 11532241247 27344 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a numerical computation can not be performed because the * numerical result failed to converge to a finite value. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class ConvergenceException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -1111352570797662604L; /** * Default constructor. */ public ConvergenceException() { super(LocalizedFormats.CONVERGENCE_FAILED); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 1.2 * @deprecated as of 2.2 replaced by {@link #ConvergenceException(Localizable, Object...)} */ @Deprecated public ConvergenceException(String pattern, Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public ConvergenceException(Localizable pattern, Object ... arguments) { super(pattern, arguments); } /** * Create an exception with a given root cause. * @param cause the exception or error that caused this exception to be thrown */ public ConvergenceException(Throwable cause) { super(cause); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param pattern format specifier * @param arguments format arguments * @since 1.2 * @deprecated as of 2.2 replaced by {@link #ConvergenceException(Throwable, Localizable, Object...)} */ @Deprecated public ConvergenceException(Throwable cause, String pattern, Object ... arguments) { this(cause, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public ConvergenceException(Throwable cause, Localizable pattern, Object ... arguments) { super(cause, pattern, arguments); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ConvergingAlgorithm.java100644 1750 1750 11674 11532241247 27212 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; /** * Interface for algorithms handling convergence settings. *

                      * This interface only deals with convergence parameters setting, not * execution of the algorithms per se. *

                      * @see ConvergenceException * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ * @since 2.0 * @deprecated in 2.2 (to be removed in 3.0). The concept of "iteration" will * be moved to a new {@code IterativeAlgorithm}. The concept of "accuracy" is * currently is also contained in {@link org.apache.commons.math.optimization.SimpleRealPointChecker} * and similar classes. */ @Deprecated public interface ConvergingAlgorithm { /** * Set the upper limit for the number of iterations. *

                      * Usually a high iteration count indicates convergence problems. However, * the "reasonable value" varies widely for different algorithms. Users are * advised to use the default value supplied by the algorithm.

                      *

                      * A {@link ConvergenceException} will be thrown if this number * is exceeded.

                      * * @param count maximum number of iterations */ void setMaximalIterationCount(int count); /** * Get the upper limit for the number of iterations. * * @return the actual upper limit */ int getMaximalIterationCount(); /** * Reset the upper limit for the number of iterations to the default. *

                      * The default value is supplied by the algorithm implementation.

                      * * @see #setMaximalIterationCount(int) */ void resetMaximalIterationCount(); /** * Set the absolute accuracy. *

                      * The default is usually chosen so that results in the interval * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the * expected absolute value of your results is of much smaller magnitude, set * this to a smaller value.

                      *

                      * Algorithms are advised to do a plausibility check with the relative * accuracy, but clients should not rely on this.

                      * * @param accuracy the accuracy. * @throws IllegalArgumentException if the accuracy can't be achieved by * the solver or is otherwise deemed unreasonable. */ void setAbsoluteAccuracy(double accuracy); /** * Get the actual absolute accuracy. * * @return the accuracy */ double getAbsoluteAccuracy(); /** * Reset the absolute accuracy to the default. *

                      * The default value is provided by the algorithm implementation.

                      */ void resetAbsoluteAccuracy(); /** * Set the relative accuracy. *

                      * This is used to stop iterations if the absolute accuracy can't be * achieved due to large values or short mantissa length.

                      *

                      * If this should be the primary criterion for convergence rather then a * safety measure, set the absolute accuracy to a ridiculously small value, * like {@link org.apache.commons.math.util.MathUtils#SAFE_MIN MathUtils.SAFE_MIN}.

                      * * @param accuracy the relative accuracy. * @throws IllegalArgumentException if the accuracy can't be achieved by * the algorithm or is otherwise deemed unreasonable. */ void setRelativeAccuracy(double accuracy); /** * Get the actual relative accuracy. * @return the accuracy */ double getRelativeAccuracy(); /** * Reset the relative accuracy to the default. * The default value is provided by the algorithm implementation. */ void resetRelativeAccuracy(); /** * Get the number of iterations in the last run of the algorithm. *

                      * This is mainly meant for testing purposes. It may occasionally * help track down performance problems: if the iteration count * is notoriously high, check whether the problem is evaluated * properly, and whether another algorithm is more amenable to the * problem.

                      * * @return the last iteration count. * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed. */ int getIterationCount(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/package.html100644 1750 1750 1716 11532241247 24634 0ustarlucluc 0 0 Common classes used throughout the commons-math library. commons-math-2.2-src/src/main/java/org/apache/commons/math/FunctionEvaluationException.java100644 1750 1750 20427 11532241247 30732 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.linear.ArrayRealVector; /** * Exception thrown when an error occurs evaluating a function. *

                      * Maintains an argument property holding the input value that * caused the function evaluation to fail. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class FunctionEvaluationException extends MathException { /** Serializable version identifier. */ private static final long serialVersionUID = 1384427981840836868L; /** Argument causing function evaluation failure */ private double[] argument; /** * Construct an exception indicating the argument value * that caused the function evaluation to fail. * * @param argument the failing function argument */ public FunctionEvaluationException(double argument) { super(LocalizedFormats.EVALUATION_FAILED, argument); this.argument = new double[] { argument }; } /** * Construct an exception indicating the argument value * that caused the function evaluation to fail. * * @param argument the failing function argument * @since 2.0 */ public FunctionEvaluationException(double[] argument) { super(LocalizedFormats.EVALUATION_FAILED, new ArrayRealVector(argument)); this.argument = argument.clone(); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 1.2 */ public FunctionEvaluationException(double argument, String pattern, Object ... arguments) { this(argument, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public FunctionEvaluationException(double argument, Localizable pattern, Object ... arguments) { super(pattern, arguments); this.argument = new double[] { argument }; } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.0 */ public FunctionEvaluationException(double[] argument, String pattern, Object ... arguments) { this(argument, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public FunctionEvaluationException(double[] argument, Localizable pattern, Object ... arguments) { super(pattern, arguments); this.argument = argument.clone(); } /** * Constructs an exception with specified root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @since 1.2 */ public FunctionEvaluationException(Throwable cause, double argument) { super(cause); this.argument = new double[] { argument }; } /** * Constructs an exception with specified root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @since 2.0 */ public FunctionEvaluationException(Throwable cause, double[] argument) { super(cause); this.argument = argument.clone(); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 1.2 */ public FunctionEvaluationException(Throwable cause, double argument, String pattern, Object ... arguments) { this(cause, argument, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public FunctionEvaluationException(Throwable cause, double argument, Localizable pattern, Object ... arguments) { super(cause, pattern, arguments); this.argument = new double[] { argument }; } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.0 */ public FunctionEvaluationException(Throwable cause, double[] argument, String pattern, Object ... arguments) { this(cause, argument, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param argument the failing function argument * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public FunctionEvaluationException(Throwable cause, double[] argument, Localizable pattern, Object ... arguments) { super(cause, pattern, arguments); this.argument = argument.clone(); } /** * Returns the function argument that caused this exception. * * @return argument that caused function evaluation to fail */ public double[] getArgument() { return argument.clone(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/package.html100644 1750 1750 7627 11532241246 25413 0ustarlucluc 0 0 Decimal floating point library for Java

                      Another floating point class. This one is built using radix 10000 which is 104, so its almost decimal.

                      The design goals here are:

                      1. Decimal math, or close to it
                      2. Settable precision (but no mix between numbers using different settings)
                      3. Portability. Code should be keep as portable as possible.
                      4. Performance
                      5. Accuracy - Results should always be +/- 1 ULP for basic algebraic operation
                      6. Comply with IEEE 854-1987 as much as possible. (See IEEE 854-1987 notes below)

                      Trade offs:

                      1. Memory foot print. I'm using more memory than necessary to represent numbers to get better performance.
                      2. Digits are bigger, so rounding is a greater loss. So, if you really need 12 decimal digits, better use 4 base 10000 digits there can be one partially filled.

                      Numbers are represented in the following form:

                      n  =  sign × mant × (radix)exp;

                      where sign is ±1, mantissa represents a fractional number between zero and one. mant[0] is the least significant digit. exp is in the range of -32767 to 32768

                      IEEE 854-1987 Notes and differences

                      IEEE 854 requires the radix to be either 2 or 10. The radix here is 10000, so that requirement is not met, but it is possible that a subclassed can be made to make it behave as a radix 10 number. It is my opinion that if it looks and behaves as a radix 10 number then it is one and that requirement would be met.

                      The radix of 10000 was chosen because it should be faster to operate on 4 decimal digits at once instead of one at a time. Radix 10 behavior can be realized by add an additional rounding step to ensure that the number of decimal digits represented is constant.

                      The IEEE standard specifically leaves out internal data encoding, so it is reasonable to conclude that such a subclass of this radix 10000 system is merely an encoding of a radix 10 system.

                      IEEE 854 also specifies the existence of "sub-normal" numbers. This class does not contain any such entities. The most significant radix 10000 digit is always non-zero. Instead, we support "gradual underflow" by raising the underflow flag for numbers less with exponent less than expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits. Thus the smallest number we can represent would be: 1E(-(MIN_EXP-digits-1)*4), eg, for digits=5, MIN_EXP=-32767, that would be 1e-131092.

                      IEEE 854 defines that the implied radix point lies just to the right of the most significant digit and to the left of the remaining digits. This implementation puts the implied radix point to the left of all digits including the most significant one. The most significant digit here is the one just to the right of the radix point. This is a fine detail and is really only a matter of definition. Any side effects of this can be rendered invisible by a subclass.

                      commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/DfpDec.java100644 1750 1750 25567 11532241246 25145 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; /** Subclass of {@link Dfp} which hides the radix-10000 artifacts of the superclass. * This should give outward appearances of being a decimal number with DIGITS*4-3 * decimal digits. This class can be subclassed to appear to be an arbitrary number * of decimal digits less than DIGITS*4-3. * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class DfpDec extends Dfp { /** Makes an instance with a value of zero. * @param factory factory linked to this instance */ protected DfpDec(final DfpField factory) { super(factory); } /** Create an instance from a byte value. * @param factory factory linked to this instance * @param x value to convert to an instance */ protected DfpDec(final DfpField factory, byte x) { super(factory, x); } /** Create an instance from an int value. * @param factory factory linked to this instance * @param x value to convert to an instance */ protected DfpDec(final DfpField factory, int x) { super(factory, x); } /** Create an instance from a long value. * @param factory factory linked to this instance * @param x value to convert to an instance */ protected DfpDec(final DfpField factory, long x) { super(factory, x); } /** Create an instance from a double value. * @param factory factory linked to this instance * @param x value to convert to an instance */ protected DfpDec(final DfpField factory, double x) { super(factory, x); round(0); } /** Copy constructor. * @param d instance to copy */ public DfpDec(final Dfp d) { super(d); round(0); } /** Create an instance from a String representation. * @param factory factory linked to this instance * @param s string representation of the instance */ protected DfpDec(final DfpField factory, final String s) { super(factory, s); round(0); } /** Creates an instance with a non-finite value. * @param factory factory linked to this instance * @param sign sign of the Dfp to create * @param nans code of the value, must be one of {@link #INFINITE}, * {@link #SNAN}, {@link #QNAN} */ protected DfpDec(final DfpField factory, final byte sign, final byte nans) { super(factory, sign, nans); } /** {@inheritDoc} */ @Override public Dfp newInstance() { return new DfpDec(getField()); } /** {@inheritDoc} */ @Override public Dfp newInstance(final byte x) { return new DfpDec(getField(), x); } /** {@inheritDoc} */ @Override public Dfp newInstance(final int x) { return new DfpDec(getField(), x); } /** {@inheritDoc} */ @Override public Dfp newInstance(final long x) { return new DfpDec(getField(), x); } /** {@inheritDoc} */ @Override public Dfp newInstance(final double x) { return new DfpDec(getField(), x); } /** {@inheritDoc} */ @Override public Dfp newInstance(final Dfp d) { // make sure we don't mix number with different precision if (getField().getRadixDigits() != d.getField().getRadixDigits()) { getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, "newInstance", d, result); } return new DfpDec(d); } /** {@inheritDoc} */ @Override public Dfp newInstance(final String s) { return new DfpDec(getField(), s); } /** {@inheritDoc} */ @Override public Dfp newInstance(final byte sign, final byte nans) { return new DfpDec(getField(), sign, nans); } /** Get the number of decimal digits this class is going to represent. * Default implementation returns {@link #getRadixDigits()}*4-3. Subclasses can * override this to return something less. * @return number of decimal digits this class is going to represent */ protected int getDecimalDigits() { return getRadixDigits() * 4 - 3; } /** {@inheritDoc} */ @Override protected int round(int in) { int msb = mant[mant.length-1]; if (msb == 0) { // special case -- this == zero return 0; } int cmaxdigits = mant.length * 4; int lsbthreshold = 1000; while (lsbthreshold > msb) { lsbthreshold /= 10; cmaxdigits --; } final int digits = getDecimalDigits(); final int lsbshift = cmaxdigits - digits; final int lsd = lsbshift / 4; lsbthreshold = 1; for (int i = 0; i < lsbshift % 4; i++) { lsbthreshold *= 10; } final int lsb = mant[lsd]; if (lsbthreshold <= 1 && digits == 4 * mant.length - 3) { return super.round(in); } int discarded = in; // not looking at this after this point final int n; if (lsbthreshold == 1) { // look to the next digit for rounding n = (mant[lsd-1] / 1000) % 10; mant[lsd-1] %= 1000; discarded |= mant[lsd-1]; } else { n = (lsb * 10 / lsbthreshold) % 10; discarded |= lsb % (lsbthreshold/10); } for (int i = 0; i < lsd; i++) { discarded |= mant[i]; // need to know if there are any discarded bits mant[i] = 0; } mant[lsd] = lsb / lsbthreshold * lsbthreshold; final boolean inc; switch (getField().getRoundingMode()) { case ROUND_DOWN: inc = false; break; case ROUND_UP: inc = (n != 0) || (discarded != 0); // round up if n!=0 break; case ROUND_HALF_UP: inc = n >= 5; // round half up break; case ROUND_HALF_DOWN: inc = n > 5; // round half down break; case ROUND_HALF_EVEN: inc = (n > 5) || (n == 5 && discarded != 0) || (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 1); // round half-even break; case ROUND_HALF_ODD: inc = (n > 5) || (n == 5 && discarded != 0) || (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 0); // round half-odd break; case ROUND_CEIL: inc = (sign == 1) && (n != 0 || discarded != 0); // round ceil break; case ROUND_FLOOR: default: inc = (sign == -1) && (n != 0 || discarded != 0); // round floor break; } if (inc) { // increment if necessary int rh = lsbthreshold; for (int i = lsd; i < mant.length; i++) { final int r = mant[i] + rh; rh = r / RADIX; mant[i] = r % RADIX; } if (rh != 0) { shiftRight(); mant[mant.length-1]=rh; } } // Check for exceptional cases and raise signals if necessary if (exp < MIN_EXP) { // Gradual Underflow getField().setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW); return DfpField.FLAG_UNDERFLOW; } if (exp > MAX_EXP) { // Overflow getField().setIEEEFlagsBits(DfpField.FLAG_OVERFLOW); return DfpField.FLAG_OVERFLOW; } if (n != 0 || discarded != 0) { // Inexact getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT); return DfpField.FLAG_INEXACT; } return 0; } /** {@inheritDoc} */ @Override public Dfp nextAfter(Dfp x) { final String trapName = "nextAfter"; // make sure we don't mix number with different precision if (getField().getRadixDigits() != x.getField().getRadixDigits()) { getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, trapName, x, result); } boolean up = false; Dfp result; Dfp inc; // if this is greater than x if (this.lessThan(x)) { up = true; } if (equals(x)) { return newInstance(x); } if (lessThan(getZero())) { up = !up; } if (up) { inc = power10(log10() - getDecimalDigits() + 1); inc = copysign(inc, this); if (this.equals(getZero())) { inc = power10K(MIN_EXP-mant.length-1); } if (inc.equals(getZero())) { result = copysign(newInstance(getZero()), this); } else { result = add(inc); } } else { inc = power10(log10()); inc = copysign(inc, this); if (this.equals(inc)) { inc = inc.divide(power10(getDecimalDigits())); } else { inc = inc.divide(power10(getDecimalDigits() - 1)); } if (this.equals(getZero())) { inc = power10K(MIN_EXP-mant.length-1); } if (inc.equals(getZero())) { result = copysign(newInstance(getZero()), this); } else { result = subtract(inc); } } if (result.classify() == INFINITE && this.classify() != INFINITE) { getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT); result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result); } if (result.equals(getZero()) && this.equals(getZero()) == false) { getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT); result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result); } return result; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/DfpMath.java100644 1750 1750 71560 11532241246 25335 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; /** Mathematical routines for use with {@link Dfp}. * The constants are defined in {@link DfpField} * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ * @since 2.2 */ public class DfpMath { /** Name for traps triggered by pow. */ private static final String POW_TRAP = "pow"; /** * Private Constructor. */ private DfpMath() { } /** Breaks a string representation up into two dfp's. *

                      The two dfp are such that the sum of them is equivalent * to the input string, but has higher precision than using a * single dfp. This is useful for improving accuracy of * exponentiation and critical multiplies. * @param field field to which the Dfp must belong * @param a string representation to split * @return an array of two {@link Dfp} which sum is a */ protected static Dfp[] split(final DfpField field, final String a) { Dfp result[] = new Dfp[2]; char[] buf; boolean leading = true; int sp = 0; int sig = 0; buf = new char[a.length()]; for (int i = 0; i < buf.length; i++) { buf[i] = a.charAt(i); if (buf[i] >= '1' && buf[i] <= '9') { leading = false; } if (buf[i] == '.') { sig += (400 - sig) % 4; leading = false; } if (sig == (field.getRadixDigits() / 2) * 4) { sp = i; break; } if (buf[i] >= '0' && buf[i] <= '9' && !leading) { sig ++; } } result[0] = field.newDfp(new String(buf, 0, sp)); for (int i = 0; i < buf.length; i++) { buf[i] = a.charAt(i); if (buf[i] >= '0' && buf[i] <= '9' && i < sp) { buf[i] = '0'; } } result[1] = field.newDfp(new String(buf)); return result; } /** Splits a {@link Dfp} into 2 {@link Dfp}'s such that their sum is equal to the input {@link Dfp}. * @param a number to split * @return two elements array containing the split number */ protected static Dfp[] split(final Dfp a) { final Dfp[] result = new Dfp[2]; final Dfp shift = a.multiply(a.power10K(a.getRadixDigits() / 2)); result[0] = a.add(shift).subtract(shift); result[1] = a.subtract(result[0]); return result; } /** Multiply two numbers that are split in to two pieces that are * meant to be added together. * Use binomial multiplication so ab = a0 b0 + a0 b1 + a1 b0 + a1 b1 * Store the first term in result0, the rest in result1 * @param a first factor of the multiplication, in split form * @param b second factor of the multiplication, in split form * @return a × b, in split form */ protected static Dfp[] splitMult(final Dfp[] a, final Dfp[] b) { final Dfp[] result = new Dfp[2]; result[1] = a[0].getZero(); result[0] = a[0].multiply(b[0]); /* If result[0] is infinite or zero, don't compute result[1]. * Attempting to do so may produce NaNs. */ if (result[0].classify() == Dfp.INFINITE || result[0].equals(result[1])) { return result; } result[1] = a[0].multiply(b[1]).add(a[1].multiply(b[0])).add(a[1].multiply(b[1])); return result; } /** Divide two numbers that are split in to two pieces that are meant to be added together. * Inverse of split multiply above: * (a+b) / (c+d) = (a/c) + ( (bc-ad)/(c**2+cd) ) * @param a dividend, in split form * @param b divisor, in split form * @return a / b, in split form */ protected static Dfp[] splitDiv(final Dfp[] a, final Dfp[] b) { final Dfp[] result; result = new Dfp[2]; result[0] = a[0].divide(b[0]); result[1] = a[1].multiply(b[0]).subtract(a[0].multiply(b[1])); result[1] = result[1].divide(b[0].multiply(b[0]).add(b[0].multiply(b[1]))); return result; } /** Raise a split base to the a power. * @param base number to raise * @param a power * @return basea */ protected static Dfp splitPow(final Dfp[] base, int a) { boolean invert = false; Dfp[] r = new Dfp[2]; Dfp[] result = new Dfp[2]; result[0] = base[0].getOne(); result[1] = base[0].getZero(); if (a == 0) { // Special case a = 0 return result[0].add(result[1]); } if (a < 0) { // If a is less than zero invert = true; a = -a; } // Exponentiate by successive squaring do { r[0] = new Dfp(base[0]); r[1] = new Dfp(base[1]); int trial = 1; int prevtrial; while (true) { prevtrial = trial; trial = trial * 2; if (trial > a) { break; } r = splitMult(r, r); } trial = prevtrial; a -= trial; result = splitMult(result, r); } while (a >= 1); result[0] = result[0].add(result[1]); if (invert) { result[0] = base[0].getOne().divide(result[0]); } return result[0]; } /** Raises base to the power a by successive squaring. * @param base number to raise * @param a power * @return basea */ public static Dfp pow(Dfp base, int a) { boolean invert = false; Dfp result = base.getOne(); if (a == 0) { // Special case return result; } if (a < 0) { invert = true; a = -a; } // Exponentiate by successive squaring do { Dfp r = new Dfp(base); Dfp prevr; int trial = 1; int prevtrial; do { prevr = new Dfp(r); prevtrial = trial; r = r.multiply(r); trial = trial * 2; } while (a>trial); r = prevr; trial = prevtrial; a = a - trial; result = result.multiply(r); } while (a >= 1); if (invert) { result = base.getOne().divide(result); } return base.newInstance(result); } /** Computes e to the given power. * a is broken into two parts, such that a = n+m where n is an integer. * We use pow() to compute en and a Taylor series to compute * em. We return e*n × em * @param a power at which e should be raised * @return ea */ public static Dfp exp(final Dfp a) { final Dfp inta = a.rint(); final Dfp fraca = a.subtract(inta); final int ia = inta.intValue(); if (ia > 2147483646) { // return +Infinity return a.newInstance((byte)1, Dfp.INFINITE); } if (ia < -2147483646) { // return 0; return a.newInstance(); } final Dfp einta = splitPow(a.getField().getESplit(), ia); final Dfp efraca = expInternal(fraca); return einta.multiply(efraca); } /** Computes e to the given power. * Where -1 < a < 1. Use the classic Taylor series. 1 + x**2/2! + x**3/3! + x**4/4! ... * @param a power at which e should be raised * @return ea */ protected static Dfp expInternal(final Dfp a) { Dfp y = a.getOne(); Dfp x = a.getOne(); Dfp fact = a.getOne(); Dfp py = new Dfp(y); for (int i = 1; i < 90; i++) { x = x.multiply(a); fact = fact.divide(i); y = y.add(x.multiply(fact)); if (y.equals(py)) { break; } py = new Dfp(y); } return y; } /** Returns the natural logarithm of a. * a is first split into three parts such that a = (10000^h)(2^j)k. * ln(a) is computed by ln(a) = ln(5)*h + ln(2)*(h+j) + ln(k) * k is in the range 2/3 < k <4/3 and is passed on to a series expansion. * @param a number from which logarithm is requested * @return log(a) */ public static Dfp log(Dfp a) { int lr; Dfp x; int ix; int p2 = 0; // Check the arguments somewhat here if (a.equals(a.getZero()) || a.lessThan(a.getZero()) || a.isNaN()) { // negative, zero or NaN a.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); return a.dotrap(DfpField.FLAG_INVALID, "ln", a, a.newInstance((byte)1, Dfp.QNAN)); } if (a.classify() == Dfp.INFINITE) { return a; } x = new Dfp(a); lr = x.log10K(); x = x.divide(pow(a.newInstance(10000), lr)); /* This puts x in the range 0-10000 */ ix = x.floor().intValue(); while (ix > 2) { ix >>= 1; p2++; } Dfp[] spx = split(x); Dfp[] spy = new Dfp[2]; spy[0] = pow(a.getTwo(), p2); // use spy[0] temporarily as a divisor spx[0] = spx[0].divide(spy[0]); spx[1] = spx[1].divide(spy[0]); spy[0] = a.newInstance("1.33333"); // Use spy[0] for comparison while (spx[0].add(spx[1]).greaterThan(spy[0])) { spx[0] = spx[0].divide(2); spx[1] = spx[1].divide(2); p2++; } // X is now in the range of 2/3 < x < 4/3 Dfp[] spz = logInternal(spx); spx[0] = a.newInstance(new StringBuilder().append(p2+4*lr).toString()); spx[1] = a.getZero(); spy = splitMult(a.getField().getLn2Split(), spx); spz[0] = spz[0].add(spy[0]); spz[1] = spz[1].add(spy[1]); spx[0] = a.newInstance(new StringBuilder().append(4*lr).toString()); spx[1] = a.getZero(); spy = splitMult(a.getField().getLn5Split(), spx); spz[0] = spz[0].add(spy[0]); spz[1] = spz[1].add(spy[1]); return a.newInstance(spz[0].add(spz[1])); } /** Computes the natural log of a number between 0 and 2. * Let f(x) = ln(x), * * We know that f'(x) = 1/x, thus from Taylor's theorum we have: * * ----- n+1 n * f(x) = \ (-1) (x - 1) * / ---------------- for 1 <= n <= infinity * ----- n * * or * 2 3 4 * (x-1) (x-1) (x-1) * ln(x) = (x-1) - ----- + ------ - ------ + ... * 2 3 4 * * alternatively, * * 2 3 4 * x x x * ln(x+1) = x - - + - - - + ... * 2 3 4 * * This series can be used to compute ln(x), but it converges too slowly. * * If we substitute -x for x above, we get * * 2 3 4 * x x x * ln(1-x) = -x - - - - - - + ... * 2 3 4 * * Note that all terms are now negative. Because the even powered ones * absorbed the sign. Now, subtract the series above from the previous * one to get ln(x+1) - ln(1-x). Note the even terms cancel out leaving * only the odd ones * * 3 5 7 * 2x 2x 2x * ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ... * 3 5 7 * * By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have: * * 3 5 7 * x+1 / x x x \ * ln ----- = 2 * | x + ---- + ---- + ---- + ... | * x-1 \ 3 5 7 / * * But now we want to find ln(a), so we need to find the value of x * such that a = (x+1)/(x-1). This is easily solved to find that * x = (a-1)/(a+1). * @param a number from which logarithm is requested, in split form * @return log(a) */ protected static Dfp[] logInternal(final Dfp a[]) { /* Now we want to compute x = (a-1)/(a+1) but this is prone to * loss of precision. So instead, compute x = (a/4 - 1/4) / (a/4 + 1/4) */ Dfp t = a[0].divide(4).add(a[1].divide(4)); Dfp x = t.add(a[0].newInstance("-0.25")).divide(t.add(a[0].newInstance("0.25"))); Dfp y = new Dfp(x); Dfp num = new Dfp(x); Dfp py = new Dfp(y); int den = 1; for (int i = 0; i < 10000; i++) { num = num.multiply(x); num = num.multiply(x); den = den + 2; t = num.divide(den); y = y.add(t); if (y.equals(py)) { break; } py = new Dfp(y); } y = y.multiply(a[0].getTwo()); return split(y); } /** Computes x to the y power.

                      * * Uses the following method:

                      * *

                        *
                      1. Set u = rint(y), v = y-u *
                      2. Compute a = v * ln(x) *
                      3. Compute b = rint( a/ln(2) ) *
                      4. Compute c = a - b*ln(2) *
                      5. xy = xu * 2b * ec *
                      * if |y| > 1e8, then we compute by exp(y*ln(x))

                      * * Special Cases

                      *

                        *
                      • if y is 0.0 or -0.0 then result is 1.0 *
                      • if y is 1.0 then result is x *
                      • if y is NaN then result is NaN *
                      • if x is NaN and y is not zero then result is NaN *
                      • if |x| > 1.0 and y is +Infinity then result is +Infinity *
                      • if |x| < 1.0 and y is -Infinity then result is +Infinity *
                      • if |x| > 1.0 and y is -Infinity then result is +0 *
                      • if |x| < 1.0 and y is +Infinity then result is +0 *
                      • if |x| = 1.0 and y is +/-Infinity then result is NaN *
                      • if x = +0 and y > 0 then result is +0 *
                      • if x = +Inf and y < 0 then result is +0 *
                      • if x = +0 and y < 0 then result is +Inf *
                      • if x = +Inf and y > 0 then result is +Inf *
                      • if x = -0 and y > 0, finite, not odd integer then result is +0 *
                      • if x = -0 and y < 0, finite, and odd integer then result is -Inf *
                      • if x = -Inf and y > 0, finite, and odd integer then result is -Inf *
                      • if x = -0 and y < 0, not finite odd integer then result is +Inf *
                      • if x = -Inf and y > 0, not finite odd integer then result is +Inf *
                      • if x < 0 and y > 0, finite, and odd integer then result is -(|x|y) *
                      • if x < 0 and y > 0, finite, and not integer then result is NaN *
                      * @param x base to be raised * @param y power to which base should be raised * @return xy */ public static Dfp pow(Dfp x, final Dfp y) { // make sure we don't mix number with different precision if (x.getField().getRadixDigits() != y.getField().getRadixDigits()) { x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = x.newInstance(x.getZero()); result.nans = Dfp.QNAN; return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, result); } final Dfp zero = x.getZero(); final Dfp one = x.getOne(); final Dfp two = x.getTwo(); boolean invert = false; int ui; /* Check for special cases */ if (y.equals(zero)) { return x.newInstance(one); } if (y.equals(one)) { if (x.isNaN()) { // Test for NaNs x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x); } return x; } if (x.isNaN() || y.isNaN()) { // Test for NaNs x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN)); } // X == 0 if (x.equals(zero)) { if (Dfp.copysign(one, x).greaterThan(zero)) { // X == +0 if (y.greaterThan(zero)) { return x.newInstance(zero); } else { return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE)); } } else { // X == -0 if (y.classify() == Dfp.FINITE && y.rint().equals(y) && !y.remainder(two).equals(zero)) { // If y is odd integer if (y.greaterThan(zero)) { return x.newInstance(zero.negate()); } else { return x.newInstance(x.newInstance((byte)-1, Dfp.INFINITE)); } } else { // Y is not odd integer if (y.greaterThan(zero)) { return x.newInstance(zero); } else { return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE)); } } } } if (x.lessThan(zero)) { // Make x positive, but keep track of it x = x.negate(); invert = true; } if (x.greaterThan(one) && y.classify() == Dfp.INFINITE) { if (y.greaterThan(zero)) { return y; } else { return x.newInstance(zero); } } if (x.lessThan(one) && y.classify() == Dfp.INFINITE) { if (y.greaterThan(zero)) { return x.newInstance(zero); } else { return x.newInstance(Dfp.copysign(y, one)); } } if (x.equals(one) && y.classify() == Dfp.INFINITE) { x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN)); } if (x.classify() == Dfp.INFINITE) { // x = +/- inf if (invert) { // negative infinity if (y.classify() == Dfp.FINITE && y.rint().equals(y) && !y.remainder(two).equals(zero)) { // If y is odd integer if (y.greaterThan(zero)) { return x.newInstance(x.newInstance((byte)-1, Dfp.INFINITE)); } else { return x.newInstance(zero.negate()); } } else { // Y is not odd integer if (y.greaterThan(zero)) { return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE)); } else { return x.newInstance(zero); } } } else { // positive infinity if (y.greaterThan(zero)) { return x; } else { return x.newInstance(zero); } } } if (invert && !y.rint().equals(y)) { x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID); return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN)); } // End special cases Dfp r; if (y.lessThan(x.newInstance(100000000)) && y.greaterThan(x.newInstance(-100000000))) { final Dfp u = y.rint(); ui = u.intValue(); final Dfp v = y.subtract(u); if (v.unequal(zero)) { final Dfp a = v.multiply(log(x)); final Dfp b = a.divide(x.getField().getLn2()).rint(); final Dfp c = a.subtract(b.multiply(x.getField().getLn2())); r = splitPow(split(x), ui); r = r.multiply(pow(two, b.intValue())); r = r.multiply(exp(c)); } else { r = splitPow(split(x), ui); } } else { // very large exponent. |y| > 1e8 r = exp(log(x).multiply(y)); } if (invert) { // if y is odd integer if (y.rint().equals(y) && !y.remainder(two).equals(zero)) { r = r.negate(); } } return x.newInstance(r); } /** Computes sin(a) Used when 0 < a < pi/4. * Uses the classic Taylor series. x - x**3/3! + x**5/5! ... * @param a number from which sine is desired, in split form * @return sin(a) */ protected static Dfp sinInternal(Dfp a[]) { Dfp c = a[0].add(a[1]); Dfp y = c; c = c.multiply(c); Dfp x = y; Dfp fact = a[0].getOne(); Dfp py = new Dfp(y); for (int i = 3; i < 90; i += 2) { x = x.multiply(c); x = x.negate(); fact = fact.divide((i-1)*i); // 1 over fact y = y.add(x.multiply(fact)); if (y.equals(py)) break; py = new Dfp(y); } return y; } /** Computes cos(a) Used when 0 < a < pi/4. * Uses the classic Taylor series for cosine. 1 - x**2/2! + x**4/4! ... * @param a number from which cosine is desired, in split form * @return cos(a) */ protected static Dfp cosInternal(Dfp a[]) { final Dfp one = a[0].getOne(); Dfp x = one; Dfp y = one; Dfp c = a[0].add(a[1]); c = c.multiply(c); Dfp fact = one; Dfp py = new Dfp(y); for (int i = 2; i < 90; i += 2) { x = x.multiply(c); x = x.negate(); fact = fact.divide((i - 1) * i); // 1 over fact y = y.add(x.multiply(fact)); if (y.equals(py)) { break; } py = new Dfp(y); } return y; } /** computes the sine of the argument. * @param a number from which sine is desired * @return sin(a) */ public static Dfp sin(final Dfp a) { final Dfp pi = a.getField().getPi(); final Dfp zero = a.getField().getZero(); boolean neg = false; /* First reduce the argument to the range of +/- PI */ Dfp x = a.remainder(pi.multiply(2)); /* if x < 0 then apply identity sin(-x) = -sin(x) */ /* This puts x in the range 0 < x < PI */ if (x.lessThan(zero)) { x = x.negate(); neg = true; } /* Since sine(x) = sine(pi - x) we can reduce the range to * 0 < x < pi/2 */ if (x.greaterThan(pi.divide(2))) { x = pi.subtract(x); } Dfp y; if (x.lessThan(pi.divide(4))) { Dfp c[] = new Dfp[2]; c[0] = x; c[1] = zero; //y = sinInternal(c); y = sinInternal(split(x)); } else { final Dfp c[] = new Dfp[2]; final Dfp[] piSplit = a.getField().getPiSplit(); c[0] = piSplit[0].divide(2).subtract(x); c[1] = piSplit[1].divide(2); y = cosInternal(c); } if (neg) { y = y.negate(); } return a.newInstance(y); } /** computes the cosine of the argument. * @param a number from which cosine is desired * @return cos(a) */ public static Dfp cos(Dfp a) { final Dfp pi = a.getField().getPi(); final Dfp zero = a.getField().getZero(); boolean neg = false; /* First reduce the argument to the range of +/- PI */ Dfp x = a.remainder(pi.multiply(2)); /* if x < 0 then apply identity cos(-x) = cos(x) */ /* This puts x in the range 0 < x < PI */ if (x.lessThan(zero)) { x = x.negate(); } /* Since cos(x) = -cos(pi - x) we can reduce the range to * 0 < x < pi/2 */ if (x.greaterThan(pi.divide(2))) { x = pi.subtract(x); neg = true; } Dfp y; if (x.lessThan(pi.divide(4))) { Dfp c[] = new Dfp[2]; c[0] = x; c[1] = zero; y = cosInternal(c); } else { final Dfp c[] = new Dfp[2]; final Dfp[] piSplit = a.getField().getPiSplit(); c[0] = piSplit[0].divide(2).subtract(x); c[1] = piSplit[1].divide(2); y = sinInternal(c); } if (neg) { y = y.negate(); } return a.newInstance(y); } /** computes the tangent of the argument. * @param a number from which tangent is desired * @return tan(a) */ public static Dfp tan(final Dfp a) { return sin(a).divide(cos(a)); } /** computes the arc-tangent of the argument. * @param a number from which arc-tangent is desired * @return atan(a) */ protected static Dfp atanInternal(final Dfp a) { Dfp y = new Dfp(a); Dfp x = new Dfp(y); Dfp py = new Dfp(y); for (int i = 3; i < 90; i += 2) { x = x.multiply(a); x = x.multiply(a); x = x.negate(); y = y.add(x.divide(i)); if (y.equals(py)) { break; } py = new Dfp(y); } return y; } /** computes the arc tangent of the argument * * Uses the typical taylor series * * but may reduce arguments using the following identity * tan(x+y) = (tan(x) + tan(y)) / (1 - tan(x)*tan(y)) * * since tan(PI/8) = sqrt(2)-1, * * atan(x) = atan( (x - sqrt(2) + 1) / (1+x*sqrt(2) - x) + PI/8.0 * @param a number from which arc-tangent is desired * @return atan(a) */ public static Dfp atan(final Dfp a) { final Dfp zero = a.getField().getZero(); final Dfp one = a.getField().getOne(); final Dfp[] sqr2Split = a.getField().getSqr2Split(); final Dfp[] piSplit = a.getField().getPiSplit(); boolean recp = false; boolean neg = false; boolean sub = false; final Dfp ty = sqr2Split[0].subtract(one).add(sqr2Split[1]); Dfp x = new Dfp(a); if (x.lessThan(zero)) { neg = true; x = x.negate(); } if (x.greaterThan(one)) { recp = true; x = one.divide(x); } if (x.greaterThan(ty)) { Dfp sty[] = new Dfp[2]; sub = true; sty[0] = sqr2Split[0].subtract(one); sty[1] = sqr2Split[1]; Dfp[] xs = split(x); Dfp[] ds = splitMult(xs, sty); ds[0] = ds[0].add(one); xs[0] = xs[0].subtract(sty[0]); xs[1] = xs[1].subtract(sty[1]); xs = splitDiv(xs, ds); x = xs[0].add(xs[1]); //x = x.subtract(ty).divide(dfp.one.add(x.multiply(ty))); } Dfp y = atanInternal(x); if (sub) { y = y.add(piSplit[0].divide(8)).add(piSplit[1].divide(8)); } if (recp) { y = piSplit[0].divide(2).subtract(y).add(piSplit[1].divide(2)); } if (neg) { y = y.negate(); } return a.newInstance(y); } /** computes the arc-sine of the argument. * @param a number from which arc-sine is desired * @return asin(a) */ public static Dfp asin(final Dfp a) { return atan(a.divide(a.getOne().subtract(a.multiply(a)).sqrt())); } /** computes the arc-cosine of the argument. * @param a number from which arc-cosine is desired * @return acos(a) */ public static Dfp acos(Dfp a) { Dfp result; boolean negative = false; if (a.lessThan(a.getZero())) { negative = true; } a = Dfp.copysign(a, a.getOne()); // absolute value result = atan(a.getOne().subtract(a.multiply(a)).sqrt().divide(a)); if (negative) { result = a.getField().getPi().subtract(result); } return a.newInstance(result); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/Dfp.java100644 1750 1750 217572 11532241246 24550 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; import java.util.Arrays; import org.apache.commons.math.FieldElement; /** * Decimal floating point library for Java * *

                      Another floating point class. This one is built using radix 10000 * which is 104, so its almost decimal.

                      * *

                      The design goals here are: *

                        *
                      1. Decimal math, or close to it
                      2. *
                      3. Settable precision (but no mix between numbers using different settings)
                      4. *
                      5. Portability. Code should be keep as portable as possible.
                      6. *
                      7. Performance
                      8. *
                      9. Accuracy - Results should always be +/- 1 ULP for basic * algebraic operation
                      10. *
                      11. Comply with IEEE 854-1987 as much as possible. * (See IEEE 854-1987 notes below)
                      12. *

                      * *

                      Trade offs: *

                        *
                      1. Memory foot print. I'm using more memory than necessary to * represent numbers to get better performance.
                      2. *
                      3. Digits are bigger, so rounding is a greater loss. So, if you * really need 12 decimal digits, better use 4 base 10000 digits * there can be one partially filled.
                      4. *

                      * *

                      Numbers are represented in the following form: *

                       *  n  =  sign × mant × (radix)exp;

                      *
                      * where sign is ±1, mantissa represents a fractional number between * zero and one. mant[0] is the least significant digit. * exp is in the range of -32767 to 32768

                      * *

                      IEEE 854-1987 Notes and differences

                      * *

                      IEEE 854 requires the radix to be either 2 or 10. The radix here is * 10000, so that requirement is not met, but it is possible that a * subclassed can be made to make it behave as a radix 10 * number. It is my opinion that if it looks and behaves as a radix * 10 number then it is one and that requirement would be met.

                      * *

                      The radix of 10000 was chosen because it should be faster to operate * on 4 decimal digits at once instead of one at a time. Radix 10 behavior * can be realized by add an additional rounding step to ensure that * the number of decimal digits represented is constant.

                      * *

                      The IEEE standard specifically leaves out internal data encoding, * so it is reasonable to conclude that such a subclass of this radix * 10000 system is merely an encoding of a radix 10 system.

                      * *

                      IEEE 854 also specifies the existence of "sub-normal" numbers. This * class does not contain any such entities. The most significant radix * 10000 digit is always non-zero. Instead, we support "gradual underflow" * by raising the underflow flag for numbers less with exponent less than * expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits. * Thus the smallest number we can represent would be: * 1E(-(MIN_EXP-digits-1)*4), eg, for digits=5, MIN_EXP=-32767, that would * be 1e-131092.

                      * *

                      IEEE 854 defines that the implied radix point lies just to the right * of the most significant digit and to the left of the remaining digits. * This implementation puts the implied radix point to the left of all * digits including the most significant one. The most significant digit * here is the one just to the right of the radix point. This is a fine * detail and is really only a matter of definition. Any side effects of * this can be rendered invisible by a subclass.

                      * @see DfpField * @version $Revision: 1003889 $ $Date: 2010-10-02 23:11:55 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class Dfp implements FieldElement { /** The radix, or base of this system. Set to 10000 */ public static final int RADIX = 10000; /** The minimum exponent before underflow is signaled. Flush to zero * occurs at minExp-DIGITS */ public static final int MIN_EXP = -32767; /** The maximum exponent before overflow is signaled and results flushed * to infinity */ public static final int MAX_EXP = 32768; /** The amount under/overflows are scaled by before going to trap handler */ public static final int ERR_SCALE = 32760; /** Indicator value for normal finite numbers. */ public static final byte FINITE = 0; /** Indicator value for Infinity. */ public static final byte INFINITE = 1; /** Indicator value for signaling NaN. */ public static final byte SNAN = 2; /** Indicator value for quiet NaN. */ public static final byte QNAN = 3; /** String for NaN representation. */ private static final String NAN_STRING = "NaN"; /** String for positive infinity representation. */ private static final String POS_INFINITY_STRING = "Infinity"; /** String for negative infinity representation. */ private static final String NEG_INFINITY_STRING = "-Infinity"; /** Name for traps triggered by addition. */ private static final String ADD_TRAP = "add"; /** Name for traps triggered by multiplication. */ private static final String MULTIPLY_TRAP = "multiply"; /** Name for traps triggered by division. */ private static final String DIVIDE_TRAP = "divide"; /** Name for traps triggered by square root. */ private static final String SQRT_TRAP = "sqrt"; /** Name for traps triggered by alignment. */ private static final String ALIGN_TRAP = "align"; /** Name for traps triggered by truncation. */ private static final String TRUNC_TRAP = "trunc"; /** Name for traps triggered by nextAfter. */ private static final String NEXT_AFTER_TRAP = "nextAfter"; /** Name for traps triggered by lessThan. */ private static final String LESS_THAN_TRAP = "lessThan"; /** Name for traps triggered by greaterThan. */ private static final String GREATER_THAN_TRAP = "greaterThan"; /** Name for traps triggered by newInstance. */ private static final String NEW_INSTANCE_TRAP = "newInstance"; /** Mantissa. */ protected int[] mant; /** Sign bit: & for positive, -1 for negative. */ protected byte sign; /** Exponent. */ protected int exp; /** Indicator for non-finite / non-number values. */ protected byte nans; /** Factory building similar Dfp's. */ private final DfpField field; /** Makes an instance with a value of zero. * @param field field to which this instance belongs */ protected Dfp(final DfpField field) { mant = new int[field.getRadixDigits()]; sign = 1; exp = 0; nans = FINITE; this.field = field; } /** Create an instance from a byte value. * @param field field to which this instance belongs * @param x value to convert to an instance */ protected Dfp(final DfpField field, byte x) { this(field, (long) x); } /** Create an instance from an int value. * @param field field to which this instance belongs * @param x value to convert to an instance */ protected Dfp(final DfpField field, int x) { this(field, (long) x); } /** Create an instance from a long value. * @param field field to which this instance belongs * @param x value to convert to an instance */ protected Dfp(final DfpField field, long x) { // initialize as if 0 mant = new int[field.getRadixDigits()]; nans = FINITE; this.field = field; boolean isLongMin = false; if (x == Long.MIN_VALUE) { // special case for Long.MIN_VALUE (-9223372036854775808) // we must shift it before taking its absolute value isLongMin = true; ++x; } // set the sign if (x < 0) { sign = -1; x = -x; } else { sign = 1; } exp = 0; while (x != 0) { System.arraycopy(mant, mant.length - exp, mant, mant.length - 1 - exp, exp); mant[mant.length - 1] = (int) (x % RADIX); x /= RADIX; exp++; } if (isLongMin) { // remove the shift added for Long.MIN_VALUE // we know in this case that fixing the last digit is sufficient for (int i = 0; i < mant.length - 1; i++) { if (mant[i] != 0) { mant[i]++; break; } } } } /** Create an instance from a double value. * @param field field to which this instance belongs * @param x value to convert to an instance */ protected Dfp(final DfpField field, double x) { // initialize as if 0 mant = new int[field.getRadixDigits()]; sign = 1; exp = 0; nans = FINITE; this.field = field; long bits = Double.doubleToLongBits(x); long mantissa = bits & 0x000fffffffffffffL; int exponent = (int) ((bits & 0x7ff0000000000000L) >> 52) - 1023; if (exponent == -1023) { // Zero or sub-normal if (x == 0) { return; } exponent++; // Normalize the subnormal number while ( (mantissa & 0x0010000000000000L) == 0) { exponent--; mantissa <<= 1; } mantissa &= 0x000fffffffffffffL; } if (exponent == 1024) { // infinity or NAN if (x != x) { sign = (byte) 1; nans = QNAN; } else if (x < 0) { sign = (byte) -1; nans = INFINITE; } else { sign = (byte) 1; nans = INFINITE; } return; } Dfp xdfp = new Dfp(field, mantissa); xdfp = xdfp.divide(new Dfp(field, 4503599627370496l)).add(field.getOne()); // Divide by 2^52, then add one xdfp = xdfp.multiply(DfpMath.pow(field.getTwo(), exponent)); if ((bits & 0x8000000000000000L) != 0) { xdfp = xdfp.negate(); } System.arraycopy(xdfp.mant, 0, mant, 0, mant.length); sign = xdfp.sign; exp = xdfp.exp; nans = xdfp.nans; } /** Copy constructor. * @param d instance to copy */ public Dfp(final Dfp d) { mant = d.mant.clone(); sign = d.sign; exp = d.exp; nans = d.nans; field = d.field; } /** Create an instance from a String representation. * @param field field to which this instance belongs * @param s string representation of the instance */ protected Dfp(final DfpField field, final String s) { // initialize as if 0 mant = new int[field.getRadixDigits()]; sign = 1; exp = 0; nans = FINITE; this.field = field; boolean decimalFound = false; final int rsize = 4; // size of radix in decimal digits final int offset = 4; // Starting offset into Striped final char[] striped = new char[getRadixDigits() * rsize + offset * 2]; // Check some special cases if (s.equals(POS_INFINITY_STRING)) { sign = (byte) 1; nans = INFINITE; return; } if (s.equals(NEG_INFINITY_STRING)) { sign = (byte) -1; nans = INFINITE; return; } if (s.equals(NAN_STRING)) { sign = (byte) 1; nans = QNAN; return; } // Check for scientific notation int p = s.indexOf("e"); if (p == -1) { // try upper case? p = s.indexOf("E"); } final String fpdecimal; int sciexp = 0; if (p != -1) { // scientific notation fpdecimal = s.substring(0, p); String fpexp = s.substring(p+1); boolean negative = false; for (int i=0; i= '0' && fpexp.charAt(i) <= '9') sciexp = sciexp * 10 + fpexp.charAt(i) - '0'; } if (negative) { sciexp = -sciexp; } } else { // normal case fpdecimal = s; } // If there is a minus sign in the number then it is negative if (fpdecimal.indexOf("-") != -1) { sign = -1; } // First off, find all of the leading zeros, trailing zeros, and significant digits p = 0; // Move p to first significant digit int decimalPos = 0; for (;;) { if (fpdecimal.charAt(p) >= '1' && fpdecimal.charAt(p) <= '9') { break; } if (decimalFound && fpdecimal.charAt(p) == '0') { decimalPos--; } if (fpdecimal.charAt(p) == '.') { decimalFound = true; } p++; if (p == fpdecimal.length()) { break; } } // Copy the string onto Stripped int q = offset; striped[0] = '0'; striped[1] = '0'; striped[2] = '0'; striped[3] = '0'; int significantDigits=0; for(;;) { if (p == (fpdecimal.length())) { break; } // Don't want to run pass the end of the array if (q == mant.length*rsize+offset+1) { break; } if (fpdecimal.charAt(p) == '.') { decimalFound = true; decimalPos = significantDigits; p++; continue; } if (fpdecimal.charAt(p) < '0' || fpdecimal.charAt(p) > '9') { p++; continue; } striped[q] = fpdecimal.charAt(p); q++; p++; significantDigits++; } // If the decimal point has been found then get rid of trailing zeros. if (decimalFound && q != offset) { for (;;) { q--; if (q == offset) { break; } if (striped[q] == '0') { significantDigits--; } else { break; } } } // special case of numbers like "0.00000" if (decimalFound && significantDigits == 0) { decimalPos = 0; } // Implicit decimal point at end of number if not present if (!decimalFound) { decimalPos = q-offset; } // Find the number of significant trailing zeros q = offset; // set q to point to first sig digit p = significantDigits-1+offset; int trailingZeros = 0; while (p > q) { if (striped[p] != '0') { break; } trailingZeros++; p--; } // Make sure the decimal is on a mod 10000 boundary int i = ((rsize * 100) - decimalPos - sciexp % rsize) % rsize; q -= i; decimalPos += i; // Make the mantissa length right by adding zeros at the end if necessary while ((p - q) < (mant.length * rsize)) { for (i = 0; i < rsize; i++) { striped[++p] = '0'; } } // Ok, now we know how many trailing zeros there are, // and where the least significant digit is for (i = mant.length - 1; i >= 0; i--) { mant[i] = (striped[q] - '0') * 1000 + (striped[q+1] - '0') * 100 + (striped[q+2] - '0') * 10 + (striped[q+3] - '0'); q += 4; } exp = (decimalPos+sciexp) / rsize; if (q < striped.length) { // Is there possible another digit? round((striped[q] - '0')*1000); } } /** Creates an instance with a non-finite value. * @param field field to which this instance belongs * @param sign sign of the Dfp to create * @param nans code of the value, must be one of {@link #INFINITE}, * {@link #SNAN}, {@link #QNAN} */ protected Dfp(final DfpField field, final byte sign, final byte nans) { this.field = field; this.mant = new int[field.getRadixDigits()]; this.sign = sign; this.exp = 0; this.nans = nans; } /** Create an instance with a value of 0. * Use this internally in preference to constructors to facilitate subclasses * @return a new instance with a value of 0 */ public Dfp newInstance() { return new Dfp(getField()); } /** Create an instance from a byte value. * @param x value to convert to an instance * @return a new instance with value x */ public Dfp newInstance(final byte x) { return new Dfp(getField(), x); } /** Create an instance from an int value. * @param x value to convert to an instance * @return a new instance with value x */ public Dfp newInstance(final int x) { return new Dfp(getField(), x); } /** Create an instance from a long value. * @param x value to convert to an instance * @return a new instance with value x */ public Dfp newInstance(final long x) { return new Dfp(getField(), x); } /** Create an instance from a double value. * @param x value to convert to an instance * @return a new instance with value x */ public Dfp newInstance(final double x) { return new Dfp(getField(), x); } /** Create an instance by copying an existing one. * Use this internally in preference to constructors to facilitate subclasses. * @param d instance to copy * @return a new instance with the same value as d */ public Dfp newInstance(final Dfp d) { // make sure we don't mix number with different precision if (field.getRadixDigits() != d.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, NEW_INSTANCE_TRAP, d, result); } return new Dfp(d); } /** Create an instance from a String representation. * Use this internally in preference to constructors to facilitate subclasses. * @param s string representation of the instance * @return a new instance parsed from specified string */ public Dfp newInstance(final String s) { return new Dfp(field, s); } /** Creates an instance with a non-finite value. * @param sig sign of the Dfp to create * @param code code of the value, must be one of {@link #INFINITE}, * {@link #SNAN}, {@link #QNAN} * @return a new instance with a non-finite value */ public Dfp newInstance(final byte sig, final byte code) { return field.newDfp(sig, code); } /** Get the {@link org.apache.commons.math.Field Field} (really a {@link DfpField}) to which the instance belongs. *

                      * The field is linked to the number of digits and acts as a factory * for {@link Dfp} instances. *

                      * @return {@link org.apache.commons.math.Field Field} (really a {@link DfpField}) to which the instance belongs */ public DfpField getField() { return field; } /** Get the number of radix digits of the instance. * @return number of radix digits */ public int getRadixDigits() { return field.getRadixDigits(); } /** Get the constant 0. * @return a Dfp with value zero */ public Dfp getZero() { return field.getZero(); } /** Get the constant 1. * @return a Dfp with value one */ public Dfp getOne() { return field.getOne(); } /** Get the constant 2. * @return a Dfp with value two */ public Dfp getTwo() { return field.getTwo(); } /** Shift the mantissa left, and adjust the exponent to compensate. */ protected void shiftLeft() { for (int i = mant.length - 1; i > 0; i--) { mant[i] = mant[i-1]; } mant[0] = 0; exp--; } /* Note that shiftRight() does not call round() as that round() itself uses shiftRight() */ /** Shift the mantissa right, and adjust the exponent to compensate. */ protected void shiftRight() { for (int i = 0; i < mant.length - 1; i++) { mant[i] = mant[i+1]; } mant[mant.length - 1] = 0; exp++; } /** Make our exp equal to the supplied one, this may cause rounding. * Also causes de-normalized numbers. These numbers are generally * dangerous because most routines assume normalized numbers. * Align doesn't round, so it will return the last digit destroyed * by shifting right. * @param e desired exponent * @return last digit destroyed by shifting right */ protected int align(int e) { int lostdigit = 0; boolean inexact = false; int diff = exp - e; int adiff = diff; if (adiff < 0) { adiff = -adiff; } if (diff == 0) { return 0; } if (adiff > (mant.length + 1)) { // Special case Arrays.fill(mant, 0); exp = e; field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this); return 0; } for (int i = 0; i < adiff; i++) { if (diff < 0) { /* Keep track of loss -- only signal inexact after losing 2 digits. * the first lost digit is returned to add() and may be incorporated * into the result. */ if (lostdigit != 0) { inexact = true; } lostdigit = mant[0]; shiftRight(); } else { shiftLeft(); } } if (inexact) { field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this); } return lostdigit; } /** Check if instance is less than x. * @param x number to check instance against * @return true if instance is less than x and neither are NaN, false otherwise */ public boolean lessThan(final Dfp x) { // make sure we don't mix number with different precision if (field.getRadixDigits() != x.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, result); return false; } /* if a nan is involved, signal invalid and return false */ if (isNaN() || x.isNaN()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, newInstance(getZero())); return false; } return compare(this, x) < 0; } /** Check if instance is greater than x. * @param x number to check instance against * @return true if instance is greater than x and neither are NaN, false otherwise */ public boolean greaterThan(final Dfp x) { // make sure we don't mix number with different precision if (field.getRadixDigits() != x.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, result); return false; } /* if a nan is involved, signal invalid and return false */ if (isNaN() || x.isNaN()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, newInstance(getZero())); return false; } return compare(this, x) > 0; } /** Check if instance is infinite. * @return true if instance is infinite */ public boolean isInfinite() { return nans == INFINITE; } /** Check if instance is not a number. * @return true if instance is not a number */ public boolean isNaN() { return (nans == QNAN) || (nans == SNAN); } /** Check if instance is equal to x. * @param other object to check instance against * @return true if instance is equal to x and neither are NaN, false otherwise */ @Override public boolean equals(final Object other) { if (other instanceof Dfp) { final Dfp x = (Dfp) other; if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) { return false; } return compare(this, x) == 0; } return false; } /** * Gets a hashCode for the instance. * @return a hash code value for this object */ @Override public int hashCode() { return 17 + (sign << 8) + (nans << 16) + exp + Arrays.hashCode(mant); } /** Check if instance is not equal to x. * @param x number to check instance against * @return true if instance is not equal to x and neither are NaN, false otherwise */ public boolean unequal(final Dfp x) { if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) { return false; } return greaterThan(x) || lessThan(x); } /** Compare two instances. * @param a first instance in comparison * @param b second instance in comparison * @return -1 if ab and 0 if a==b * Note this method does not properly handle NaNs or numbers with different precision. */ private static int compare(final Dfp a, final Dfp b) { // Ignore the sign of zero if (a.mant[a.mant.length - 1] == 0 && b.mant[b.mant.length - 1] == 0 && a.nans == FINITE && b.nans == FINITE) { return 0; } if (a.sign != b.sign) { if (a.sign == -1) { return -1; } else { return 1; } } // deal with the infinities if (a.nans == INFINITE && b.nans == FINITE) { return a.sign; } if (a.nans == FINITE && b.nans == INFINITE) { return -b.sign; } if (a.nans == INFINITE && b.nans == INFINITE) { return 0; } // Handle special case when a or b is zero, by ignoring the exponents if (b.mant[b.mant.length-1] != 0 && a.mant[b.mant.length-1] != 0) { if (a.exp < b.exp) { return -a.sign; } if (a.exp > b.exp) { return a.sign; } } // compare the mantissas for (int i = a.mant.length - 1; i >= 0; i--) { if (a.mant[i] > b.mant[i]) { return a.sign; } if (a.mant[i] < b.mant[i]) { return -a.sign; } } return 0; } /** Round to nearest integer using the round-half-even method. * That is round to nearest integer unless both are equidistant. * In which case round to the even one. * @return rounded value */ public Dfp rint() { return trunc(DfpField.RoundingMode.ROUND_HALF_EVEN); } /** Round to an integer using the round floor mode. * That is, round toward -Infinity * @return rounded value */ public Dfp floor() { return trunc(DfpField.RoundingMode.ROUND_FLOOR); } /** Round to an integer using the round ceil mode. * That is, round toward +Infinity * @return rounded value */ public Dfp ceil() { return trunc(DfpField.RoundingMode.ROUND_CEIL); } /** Returns the IEEE remainder. * @param d divisor * @return this less n × d, where n is the integer closest to this/d */ public Dfp remainder(final Dfp d) { final Dfp result = this.subtract(this.divide(d).rint().multiply(d)); // IEEE 854-1987 says that if the result is zero, then it carries the sign of this if (result.mant[mant.length-1] == 0) { result.sign = sign; } return result; } /** Does the integer conversions with the specified rounding. * @param rmode rounding mode to use * @return truncated value */ protected Dfp trunc(final DfpField.RoundingMode rmode) { boolean changed = false; if (isNaN()) { return newInstance(this); } if (nans == INFINITE) { return newInstance(this); } if (mant[mant.length-1] == 0) { // a is zero return newInstance(this); } /* If the exponent is less than zero then we can certainly * return zero */ if (exp < 0) { field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); Dfp result = newInstance(getZero()); result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result); return result; } /* If the exponent is greater than or equal to digits, then it * must already be an integer since there is no precision left * for any fractional part */ if (exp >= mant.length) { return newInstance(this); } /* General case: create another dfp, result, that contains the * a with the fractional part lopped off. */ Dfp result = newInstance(this); for (int i = 0; i < mant.length-result.exp; i++) { changed |= result.mant[i] != 0; result.mant[i] = 0; } if (changed) { switch (rmode) { case ROUND_FLOOR: if (result.sign == -1) { // then we must increment the mantissa by one result = result.add(newInstance(-1)); } break; case ROUND_CEIL: if (result.sign == 1) { // then we must increment the mantissa by one result = result.add(getOne()); } break; case ROUND_HALF_EVEN: default: final Dfp half = newInstance("0.5"); Dfp a = subtract(result); // difference between this and result a.sign = 1; // force positive (take abs) if (a.greaterThan(half)) { a = newInstance(getOne()); a.sign = sign; result = result.add(a); } /** If exactly equal to 1/2 and odd then increment */ if (a.equals(half) && result.exp > 0 && (result.mant[mant.length-result.exp]&1) != 0) { a = newInstance(getOne()); a.sign = sign; result = result.add(a); } break; } field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); // signal inexact result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result); return result; } return result; } /** Convert this to an integer. * If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648. * @return converted number */ public int intValue() { Dfp rounded; int result = 0; rounded = rint(); if (rounded.greaterThan(newInstance(2147483647))) { return 2147483647; } if (rounded.lessThan(newInstance(-2147483648))) { return -2147483648; } for (int i = mant.length - 1; i >= mant.length - rounded.exp; i--) { result = result * RADIX + rounded.mant[i]; } if (rounded.sign == -1) { result = -result; } return result; } /** Get the exponent of the greatest power of 10000 that is * less than or equal to the absolute value of this. I.E. if * this is 106 then log10K would return 1. * @return integer base 10000 logarithm */ public int log10K() { return exp - 1; } /** Get the specified power of 10000. * @param e desired power * @return 10000e */ public Dfp power10K(final int e) { Dfp d = newInstance(getOne()); d.exp = e + 1; return d; } /** Get the exponent of the greatest power of 10 that is less than or equal to abs(this). * @return integer base 10 logarithm */ public int log10() { if (mant[mant.length-1] > 1000) { return exp * 4 - 1; } if (mant[mant.length-1] > 100) { return exp * 4 - 2; } if (mant[mant.length-1] > 10) { return exp * 4 - 3; } return exp * 4 - 4; } /** Return the specified power of 10. * @param e desired power * @return 10e */ public Dfp power10(final int e) { Dfp d = newInstance(getOne()); if (e >= 0) { d.exp = e / 4 + 1; } else { d.exp = (e + 1) / 4; } switch ((e % 4 + 4) % 4) { case 0: break; case 1: d = d.multiply(10); break; case 2: d = d.multiply(100); break; default: d = d.multiply(1000); } return d; } /** Negate the mantissa of this by computing the complement. * Leaves the sign bit unchanged, used internally by add. * Denormalized numbers are handled properly here. * @param extra ??? * @return ??? */ protected int complement(int extra) { extra = RADIX-extra; for (int i = 0; i < mant.length; i++) { mant[i] = RADIX-mant[i]-1; } int rh = extra / RADIX; extra = extra - rh * RADIX; for (int i = 0; i < mant.length; i++) { final int r = mant[i] + rh; rh = r / RADIX; mant[i] = r - rh * RADIX; } return extra; } /** Add x to this. * @param x number to add * @return sum of this and x */ public Dfp add(final Dfp x) { // make sure we don't mix number with different precision if (field.getRadixDigits() != x.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result); } /* handle special cases */ if (nans != FINITE || x.nans != FINITE) { if (isNaN()) { return this; } if (x.isNaN()) { return x; } if (nans == INFINITE && x.nans == FINITE) { return this; } if (x.nans == INFINITE && nans == FINITE) { return x; } if (x.nans == INFINITE && nans == INFINITE && sign == x.sign) { return x; } if (x.nans == INFINITE && nans == INFINITE && sign != x.sign) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); Dfp result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result); return result; } } /* copy this and the arg */ Dfp a = newInstance(this); Dfp b = newInstance(x); /* initialize the result object */ Dfp result = newInstance(getZero()); /* Make all numbers positive, but remember their sign */ final byte asign = a.sign; final byte bsign = b.sign; a.sign = 1; b.sign = 1; /* The result will be signed like the arg with greatest magnitude */ byte rsign = bsign; if (compare(a, b) > 0) { rsign = asign; } /* Handle special case when a or b is zero, by setting the exponent of the zero number equal to the other one. This avoids an alignment which would cause catastropic loss of precision */ if (b.mant[mant.length-1] == 0) { b.exp = a.exp; } if (a.mant[mant.length-1] == 0) { a.exp = b.exp; } /* align number with the smaller exponent */ int aextradigit = 0; int bextradigit = 0; if (a.exp < b.exp) { aextradigit = a.align(b.exp); } else { bextradigit = b.align(a.exp); } /* complement the smaller of the two if the signs are different */ if (asign != bsign) { if (asign == rsign) { bextradigit = b.complement(bextradigit); } else { aextradigit = a.complement(aextradigit); } } /* add the mantissas */ int rh = 0; /* acts as a carry */ for (int i = 0; i < mant.length; i++) { final int r = a.mant[i]+b.mant[i]+rh; rh = r / RADIX; result.mant[i] = r - rh * RADIX; } result.exp = a.exp; result.sign = rsign; /* handle overflow -- note, when asign!=bsign an overflow is * normal and should be ignored. */ if (rh != 0 && (asign == bsign)) { final int lostdigit = result.mant[0]; result.shiftRight(); result.mant[mant.length-1] = rh; final int excp = result.round(lostdigit); if (excp != 0) { result = dotrap(excp, ADD_TRAP, x, result); } } /* normalize the result */ for (int i = 0; i < mant.length; i++) { if (result.mant[mant.length-1] != 0) { break; } result.shiftLeft(); if (i == 0) { result.mant[0] = aextradigit+bextradigit; aextradigit = 0; bextradigit = 0; } } /* result is zero if after normalization the most sig. digit is zero */ if (result.mant[mant.length-1] == 0) { result.exp = 0; if (asign != bsign) { // Unless adding 2 negative zeros, sign is positive result.sign = 1; // Per IEEE 854-1987 Section 6.3 } } /* Call round to test for over/under flows */ final int excp = result.round(aextradigit + bextradigit); if (excp != 0) { result = dotrap(excp, ADD_TRAP, x, result); } return result; } /** Returns a number that is this number with the sign bit reversed. * @return the opposite of this */ public Dfp negate() { Dfp result = newInstance(this); result.sign = (byte) - result.sign; return result; } /** Subtract x from this. * @param x number to subtract * @return difference of this and a */ public Dfp subtract(final Dfp x) { return add(x.negate()); } /** Round this given the next digit n using the current rounding mode. * @param n ??? * @return the IEEE flag if an exception occurred */ protected int round(int n) { boolean inc = false; switch (field.getRoundingMode()) { case ROUND_DOWN: inc = false; break; case ROUND_UP: inc = n != 0; // round up if n!=0 break; case ROUND_HALF_UP: inc = n >= 5000; // round half up break; case ROUND_HALF_DOWN: inc = n > 5000; // round half down break; case ROUND_HALF_EVEN: inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 1); // round half-even break; case ROUND_HALF_ODD: inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 0); // round half-odd break; case ROUND_CEIL: inc = sign == 1 && n != 0; // round ceil break; case ROUND_FLOOR: default: inc = sign == -1 && n != 0; // round floor break; } if (inc) { // increment if necessary int rh = 1; for (int i = 0; i < mant.length; i++) { final int r = mant[i] + rh; rh = r / RADIX; mant[i] = r - rh * RADIX; } if (rh != 0) { shiftRight(); mant[mant.length-1] = rh; } } // check for exceptional cases and raise signals if necessary if (exp < MIN_EXP) { // Gradual Underflow field.setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW); return DfpField.FLAG_UNDERFLOW; } if (exp > MAX_EXP) { // Overflow field.setIEEEFlagsBits(DfpField.FLAG_OVERFLOW); return DfpField.FLAG_OVERFLOW; } if (n != 0) { // Inexact field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); return DfpField.FLAG_INEXACT; } return 0; } /** Multiply this by x. * @param x multiplicand * @return product of this and x */ public Dfp multiply(final Dfp x) { // make sure we don't mix number with different precision if (field.getRadixDigits() != x.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result); } Dfp result = newInstance(getZero()); /* handle special cases */ if (nans != FINITE || x.nans != FINITE) { if (isNaN()) { return this; } if (x.isNaN()) { return x; } if (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] != 0) { result = newInstance(this); result.sign = (byte) (sign * x.sign); return result; } if (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] != 0) { result = newInstance(x); result.sign = (byte) (sign * x.sign); return result; } if (x.nans == INFINITE && nans == INFINITE) { result = newInstance(this); result.sign = (byte) (sign * x.sign); return result; } if ( (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] == 0) || (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] == 0) ) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result); return result; } } int[] product = new int[mant.length*2]; // Big enough to hold even the largest result for (int i = 0; i < mant.length; i++) { int rh = 0; // acts as a carry for (int j=0; j= 0; i--) { if (product[i] != 0) { md = i; break; } } // Copy the digits into the result for (int i = 0; i < mant.length; i++) { result.mant[mant.length - i - 1] = product[md - i]; } // Fixup the exponent. result.exp = exp + x.exp + md - 2 * mant.length + 1; result.sign = (byte)((sign == x.sign)?1:-1); if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero result.exp = 0; } final int excp; if (md > (mant.length-1)) { excp = result.round(product[md-mant.length]); } else { excp = result.round(0); // has no effect except to check status } if (excp != 0) { result = dotrap(excp, MULTIPLY_TRAP, x, result); } return result; } /** Multiply this by a single digit 0<=x<radix. * There are speed advantages in this special case * @param x multiplicand * @return product of this and x */ public Dfp multiply(final int x) { Dfp result = newInstance(this); /* handle special cases */ if (nans != FINITE) { if (isNaN()) { return this; } if (nans == INFINITE && x != 0) { result = newInstance(this); return result; } if (nans == INFINITE && x == 0) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, newInstance(getZero()), result); return result; } } /* range check x */ if (x < 0 || x >= RADIX) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, result, result); return result; } int rh = 0; for (int i = 0; i < mant.length; i++) { final int r = mant[i] * x + rh; rh = r / RADIX; result.mant[i] = r - rh * RADIX; } int lostdigit = 0; if (rh != 0) { lostdigit = result.mant[0]; result.shiftRight(); result.mant[mant.length-1] = rh; } if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero result.exp = 0; } final int excp = result.round(lostdigit); if (excp != 0) { result = dotrap(excp, MULTIPLY_TRAP, result, result); } return result; } /** Divide this by divisor. * @param divisor divisor * @return quotient of this by divisor */ public Dfp divide(Dfp divisor) { int dividend[]; // current status of the dividend int quotient[]; // quotient int remainder[];// remainder int qd; // current quotient digit we're working with int nsqd; // number of significant quotient digits we have int trial=0; // trial quotient digit int minadj; // minimum adjustment boolean trialgood; // Flag to indicate a good trail digit int md=0; // most sig digit in result int excp; // exceptions // make sure we don't mix number with different precision if (field.getRadixDigits() != divisor.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result); } Dfp result = newInstance(getZero()); /* handle special cases */ if (nans != FINITE || divisor.nans != FINITE) { if (isNaN()) { return this; } if (divisor.isNaN()) { return divisor; } if (nans == INFINITE && divisor.nans == FINITE) { result = newInstance(this); result.sign = (byte) (sign * divisor.sign); return result; } if (divisor.nans == INFINITE && nans == FINITE) { result = newInstance(getZero()); result.sign = (byte) (sign * divisor.sign); return result; } if (divisor.nans == INFINITE && nans == INFINITE) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result); return result; } } /* Test for divide by zero */ if (divisor.mant[mant.length-1] == 0) { field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO); result = newInstance(getZero()); result.sign = (byte) (sign * divisor.sign); result.nans = INFINITE; result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, divisor, result); return result; } dividend = new int[mant.length+1]; // one extra digit needed quotient = new int[mant.length+2]; // two extra digits needed 1 for overflow, 1 for rounding remainder = new int[mant.length+1]; // one extra digit needed /* Initialize our most significant digits to zero */ dividend[mant.length] = 0; quotient[mant.length] = 0; quotient[mant.length+1] = 0; remainder[mant.length] = 0; /* copy our mantissa into the dividend, initialize the quotient while we are at it */ for (int i = 0; i < mant.length; i++) { dividend[i] = mant[i]; quotient[i] = 0; remainder[i] = 0; } /* outer loop. Once per quotient digit */ nsqd = 0; for (qd = mant.length+1; qd >= 0; qd--) { /* Determine outer limits of our quotient digit */ // r = most sig 2 digits of dividend final int divMsb = dividend[mant.length]*RADIX+dividend[mant.length-1]; int min = divMsb / (divisor.mant[mant.length-1]+1); int max = (divMsb + 1) / divisor.mant[mant.length-1]; trialgood = false; while (!trialgood) { // try the mean trial = (min+max)/2; /* Multiply by divisor and store as remainder */ int rh = 0; for (int i = 0; i < mant.length + 1; i++) { int dm = (i= 2) { min = trial+minadj; // update the minimum continue; } /* May have a good one here, check more thoroughly. Basically its a good one if it is less than the divisor */ trialgood = false; // assume false for (int i = mant.length - 1; i >= 0; i--) { if (divisor.mant[i] > remainder[i]) { trialgood = true; } if (divisor.mant[i] < remainder[i]) { break; } } if (remainder[mant.length] != 0) { trialgood = false; } if (trialgood == false) { min = trial+1; } } /* Great we have a digit! */ quotient[qd] = trial; if (trial != 0 || nsqd != 0) { nsqd++; } if (field.getRoundingMode() == DfpField.RoundingMode.ROUND_DOWN && nsqd == mant.length) { // We have enough for this mode break; } if (nsqd > mant.length) { // We have enough digits break; } /* move the remainder into the dividend while left shifting */ dividend[0] = 0; for (int i = 0; i < mant.length; i++) { dividend[i + 1] = remainder[i]; } } /* Find the most sig digit */ md = mant.length; // default for (int i = mant.length + 1; i >= 0; i--) { if (quotient[i] != 0) { md = i; break; } } /* Copy the digits into the result */ for (int i=0; i (mant.length-1)) { excp = result.round(quotient[md-mant.length]); } else { excp = result.round(0); } if (excp != 0) { result = dotrap(excp, DIVIDE_TRAP, divisor, result); } return result; } /** Divide by a single digit less than radix. * Special case, so there are speed advantages. 0 <= divisor < radix * @param divisor divisor * @return quotient of this by divisor */ public Dfp divide(int divisor) { // Handle special cases if (nans != FINITE) { if (isNaN()) { return this; } if (nans == INFINITE) { return newInstance(this); } } // Test for divide by zero if (divisor == 0) { field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO); Dfp result = newInstance(getZero()); result.sign = sign; result.nans = INFINITE; result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, getZero(), result); return result; } // range check divisor if (divisor < 0 || divisor >= RADIX) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); Dfp result = newInstance(getZero()); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, result, result); return result; } Dfp result = newInstance(this); int rl = 0; for (int i = mant.length-1; i >= 0; i--) { final int r = rl*RADIX + result.mant[i]; final int rh = r / divisor; rl = r - rh * divisor; result.mant[i] = rh; } if (result.mant[mant.length-1] == 0) { // normalize result.shiftLeft(); final int r = rl * RADIX; // compute the next digit and put it in final int rh = r / divisor; rl = r - rh * divisor; result.mant[0] = rh; } final int excp = result.round(rl * RADIX / divisor); // do the rounding if (excp != 0) { result = dotrap(excp, DIVIDE_TRAP, result, result); } return result; } /** Compute the square root. * @return square root of the instance */ public Dfp sqrt() { // check for unusual cases if (nans == FINITE && mant[mant.length-1] == 0) { // if zero return newInstance(this); } if (nans != FINITE) { if (nans == INFINITE && sign == 1) { // if positive infinity return newInstance(this); } if (nans == QNAN) { return newInstance(this); } if (nans == SNAN) { Dfp result; field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(this); result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result); return result; } } if (sign == -1) { // if negative Dfp result; field.setIEEEFlagsBits(DfpField.FLAG_INVALID); result = newInstance(this); result.nans = QNAN; result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result); return result; } Dfp x = newInstance(this); /* Lets make a reasonable guess as to the size of the square root */ if (x.exp < -1 || x.exp > 1) { x.exp = this.exp / 2; } /* Coarsely estimate the mantissa */ switch (x.mant[mant.length-1] / 2000) { case 0: x.mant[mant.length-1] = x.mant[mant.length-1]/2+1; break; case 2: x.mant[mant.length-1] = 1500; break; case 3: x.mant[mant.length-1] = 2200; break; default: x.mant[mant.length-1] = 3000; } Dfp dx = newInstance(x); /* Now that we have the first pass estimate, compute the rest by the formula dx = (y - x*x) / (2x); */ Dfp px = getZero(); Dfp ppx = getZero(); while (x.unequal(px)) { dx = newInstance(x); dx.sign = -1; dx = dx.add(this.divide(x)); dx = dx.divide(2); ppx = px; px = x; x = x.add(dx); if (x.equals(ppx)) { // alternating between two values break; } // if dx is zero, break. Note testing the most sig digit // is a sufficient test since dx is normalized if (dx.mant[mant.length-1] == 0) { break; } } return x; } /** Get a string representation of the instance. * @return string representation of the instance */ @Override public String toString() { if (nans != FINITE) { // if non-finite exceptional cases if (nans == INFINITE) { return (sign < 0) ? NEG_INFINITY_STRING : POS_INFINITY_STRING; } else { return NAN_STRING; } } if (exp > mant.length || exp < -1) { return dfp2sci(); } return dfp2string(); } /** Convert an instance to a string using scientific notation. * @return string representation of the instance in scientific notation */ protected String dfp2sci() { char rawdigits[] = new char[mant.length * 4]; char outputbuffer[] = new char[mant.length * 4 + 20]; int p; int q; int e; int ae; int shf; // Get all the digits p = 0; for (int i = mant.length - 1; i >= 0; i--) { rawdigits[p++] = (char) ((mant[i] / 1000) + '0'); rawdigits[p++] = (char) (((mant[i] / 100) %10) + '0'); rawdigits[p++] = (char) (((mant[i] / 10) % 10) + '0'); rawdigits[p++] = (char) (((mant[i]) % 10) + '0'); } // Find the first non-zero one for (p = 0; p < rawdigits.length; p++) { if (rawdigits[p] != '0') { break; } } shf = p; // Now do the conversion q = 0; if (sign == -1) { outputbuffer[q++] = '-'; } if (p != rawdigits.length) { // there are non zero digits... outputbuffer[q++] = rawdigits[p++]; outputbuffer[q++] = '.'; while (p ae; p /= 10) { // nothing to do } if (e < 0) { outputbuffer[q++] = '-'; } while (p > 0) { outputbuffer[q++] = (char)(ae / p + '0'); ae = ae % p; p = p / 10; } return new String(outputbuffer, 0, q); } /** Convert an instance to a string using normal notation. * @return string representation of the instance in normal notation */ protected String dfp2string() { char buffer[] = new char[mant.length*4 + 20]; int p = 1; int q; int e = exp; boolean pointInserted = false; buffer[0] = ' '; if (e <= 0) { buffer[p++] = '0'; buffer[p++] = '.'; pointInserted = true; } while (e < 0) { buffer[p++] = '0'; buffer[p++] = '0'; buffer[p++] = '0'; buffer[p++] = '0'; e++; } for (int i = mant.length - 1; i >= 0; i--) { buffer[p++] = (char) ((mant[i] / 1000) + '0'); buffer[p++] = (char) (((mant[i] / 100) % 10) + '0'); buffer[p++] = (char) (((mant[i] / 10) % 10) + '0'); buffer[p++] = (char) (((mant[i]) % 10) + '0'); if (--e == 0) { buffer[p++] = '.'; pointInserted = true; } } while (e > 0) { buffer[p++] = '0'; buffer[p++] = '0'; buffer[p++] = '0'; buffer[p++] = '0'; e--; } if (!pointInserted) { // Ensure we have a radix point! buffer[p++] = '.'; } // Suppress leading zeros q = 1; while (buffer[q] == '0') { q++; } if (buffer[q] == '.') { q--; } // Suppress trailing zeros while (buffer[p-1] == '0') { p--; } // Insert sign if (sign < 0) { buffer[--q] = '-'; } return new String(buffer, q, p - q); } /** Raises a trap. This does not set the corresponding flag however. * @param type the trap type * @param what - name of routine trap occurred in * @param oper - input operator to function * @param result - the result computed prior to the trap * @return The suggested return value from the trap handler */ public Dfp dotrap(int type, String what, Dfp oper, Dfp result) { Dfp def = result; switch (type) { case DfpField.FLAG_INVALID: def = newInstance(getZero()); def.sign = result.sign; def.nans = QNAN; break; case DfpField.FLAG_DIV_ZERO: if (nans == FINITE && mant[mant.length-1] != 0) { // normal case, we are finite, non-zero def = newInstance(getZero()); def.sign = (byte)(sign*oper.sign); def.nans = INFINITE; } if (nans == FINITE && mant[mant.length-1] == 0) { // 0/0 def = newInstance(getZero()); def.nans = QNAN; } if (nans == INFINITE || nans == QNAN) { def = newInstance(getZero()); def.nans = QNAN; } if (nans == INFINITE || nans == SNAN) { def = newInstance(getZero()); def.nans = QNAN; } break; case DfpField.FLAG_UNDERFLOW: if ( (result.exp+mant.length) < MIN_EXP) { def = newInstance(getZero()); def.sign = result.sign; } else { def = newInstance(result); // gradual underflow } result.exp = result.exp + ERR_SCALE; break; case DfpField.FLAG_OVERFLOW: result.exp = result.exp - ERR_SCALE; def = newInstance(getZero()); def.sign = result.sign; def.nans = INFINITE; break; default: def = result; break; } return trap(type, what, oper, def, result); } /** Trap handler. Subclasses may override this to provide trap * functionality per IEEE 854-1987. * * @param type The exception type - e.g. FLAG_OVERFLOW * @param what The name of the routine we were in e.g. divide() * @param oper An operand to this function if any * @param def The default return value if trap not enabled * @param result The result that is specified to be delivered per * IEEE 854, if any * @return the value that should be return by the operation triggering the trap */ protected Dfp trap(int type, String what, Dfp oper, Dfp def, Dfp result) { return def; } /** Returns the type - one of FINITE, INFINITE, SNAN, QNAN. * @return type of the number */ public int classify() { return nans; } /** Creates an instance that is the same as x except that it has the sign of y. * abs(x) = dfp.copysign(x, dfp.one) * @param x number to get the value from * @param y number to get the sign from * @return a number with the value of x and the sign of y */ public static Dfp copysign(final Dfp x, final Dfp y) { Dfp result = x.newInstance(x); result.sign = y.sign; return result; } /** Returns the next number greater than this one in the direction of x. * If this==x then simply returns this. * @param x direction where to look at * @return closest number next to instance in the direction of x */ public Dfp nextAfter(final Dfp x) { // make sure we don't mix number with different precision if (field.getRadixDigits() != x.field.getRadixDigits()) { field.setIEEEFlagsBits(DfpField.FLAG_INVALID); final Dfp result = newInstance(getZero()); result.nans = QNAN; return dotrap(DfpField.FLAG_INVALID, NEXT_AFTER_TRAP, x, result); } // if this is greater than x boolean up = false; if (this.lessThan(x)) { up = true; } if (compare(this, x) == 0) { return newInstance(x); } if (lessThan(getZero())) { up = !up; } final Dfp inc; Dfp result; if (up) { inc = newInstance(getOne()); inc.exp = this.exp-mant.length+1; inc.sign = this.sign; if (this.equals(getZero())) { inc.exp = MIN_EXP-mant.length; } result = add(inc); } else { inc = newInstance(getOne()); inc.exp = this.exp; inc.sign = this.sign; if (this.equals(inc)) { inc.exp = this.exp-mant.length; } else { inc.exp = this.exp-mant.length+1; } if (this.equals(getZero())) { inc.exp = MIN_EXP-mant.length; } result = this.subtract(inc); } if (result.classify() == INFINITE && this.classify() != INFINITE) { field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result); } if (result.equals(getZero()) && this.equals(getZero()) == false) { field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result); } return result; } /** Convert the instance into a double. * @return a double approximating the instance * @see #toSplitDouble() */ public double toDouble() { if (isInfinite()) { if (lessThan(getZero())) { return Double.NEGATIVE_INFINITY; } else { return Double.POSITIVE_INFINITY; } } if (isNaN()) { return Double.NaN; } Dfp y = this; boolean negate = false; if (lessThan(getZero())) { y = negate(); negate = true; } /* Find the exponent, first estimate by integer log10, then adjust. Should be faster than doing a natural logarithm. */ int exponent = (int)(y.log10() * 3.32); if (exponent < 0) { exponent--; } Dfp tempDfp = DfpMath.pow(getTwo(), exponent); while (tempDfp.lessThan(y) || tempDfp.equals(y)) { tempDfp = tempDfp.multiply(2); exponent++; } exponent--; /* We have the exponent, now work on the mantissa */ y = y.divide(DfpMath.pow(getTwo(), exponent)); if (exponent > -1023) { y = y.subtract(getOne()); } if (exponent < -1074) { return 0; } if (exponent > 1023) { return negate ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; } y = y.multiply(newInstance(4503599627370496l)).rint(); String str = y.toString(); str = str.substring(0, str.length()-1); long mantissa = Long.parseLong(str); if (mantissa == 4503599627370496L) { // Handle special case where we round up to next power of two mantissa = 0; exponent++; } /* Its going to be subnormal, so make adjustments */ if (exponent <= -1023) { exponent--; } while (exponent < -1023) { exponent++; mantissa >>>= 1; } long bits = mantissa | ((exponent + 1023L) << 52); double x = Double.longBitsToDouble(bits); if (negate) { x = -x; } return x; } /** Convert the instance into a split double. * @return an array of two doubles which sum represent the instance * @see #toDouble() */ public double[] toSplitDouble() { double split[] = new double[2]; long mask = 0xffffffffc0000000L; split[0] = Double.longBitsToDouble(Double.doubleToLongBits(toDouble()) & mask); split[1] = subtract(newInstance(split[0])).toDouble(); return split; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/dfp/DfpField.java100644 1750 1750 57507 11532241246 25474 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.dfp; import org.apache.commons.math.Field; /** Field for Decimal floating point instances. * @version $Revision: 995987 $ $Date: 2010-09-10 23:24:15 +0200 (ven. 10 sept. 2010) $ * @since 2.2 */ public class DfpField implements Field { /** Enumerate for rounding modes. */ public enum RoundingMode { /** Rounds toward zero (truncation). */ ROUND_DOWN, /** Rounds away from zero if discarded digit is non-zero. */ ROUND_UP, /** Rounds towards nearest unless both are equidistant in which case it rounds away from zero. */ ROUND_HALF_UP, /** Rounds towards nearest unless both are equidistant in which case it rounds toward zero. */ ROUND_HALF_DOWN, /** Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor. * This is the default as specified by IEEE 854-1987 */ ROUND_HALF_EVEN, /** Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor. */ ROUND_HALF_ODD, /** Rounds towards positive infinity. */ ROUND_CEIL, /** Rounds towards negative infinity. */ ROUND_FLOOR; } /** IEEE 854-1987 flag for invalid operation. */ public static final int FLAG_INVALID = 1; /** IEEE 854-1987 flag for division by zero. */ public static final int FLAG_DIV_ZERO = 2; /** IEEE 854-1987 flag for overflow. */ public static final int FLAG_OVERFLOW = 4; /** IEEE 854-1987 flag for underflow. */ public static final int FLAG_UNDERFLOW = 8; /** IEEE 854-1987 flag for inexact result. */ public static final int FLAG_INEXACT = 16; /** High precision string representation of √2. */ private static String sqr2String; /** High precision string representation of √2 / 2. */ private static String sqr2ReciprocalString; /** High precision string representation of √3. */ private static String sqr3String; /** High precision string representation of √3 / 3. */ private static String sqr3ReciprocalString; /** High precision string representation of π. */ private static String piString; /** High precision string representation of e. */ private static String eString; /** High precision string representation of ln(2). */ private static String ln2String; /** High precision string representation of ln(5). */ private static String ln5String; /** High precision string representation of ln(10). */ private static String ln10String; /** The number of radix digits. * Note these depend on the radix which is 10000 digits, * so each one is equivalent to 4 decimal digits. */ private final int radixDigits; /** A {@link Dfp} with value 0. */ private final Dfp zero; /** A {@link Dfp} with value 1. */ private final Dfp one; /** A {@link Dfp} with value 2. */ private final Dfp two; /** A {@link Dfp} with value √2. */ private final Dfp sqr2; /** A two elements {@link Dfp} array with value √2 split in two pieces. */ private final Dfp[] sqr2Split; /** A {@link Dfp} with value √2 / 2. */ private final Dfp sqr2Reciprocal; /** A {@link Dfp} with value √3. */ private final Dfp sqr3; /** A {@link Dfp} with value √3 / 3. */ private final Dfp sqr3Reciprocal; /** A {@link Dfp} with value π. */ private final Dfp pi; /** A two elements {@link Dfp} array with value π split in two pieces. */ private final Dfp[] piSplit; /** A {@link Dfp} with value e. */ private final Dfp e; /** A two elements {@link Dfp} array with value e split in two pieces. */ private final Dfp[] eSplit; /** A {@link Dfp} with value ln(2). */ private final Dfp ln2; /** A two elements {@link Dfp} array with value ln(2) split in two pieces. */ private final Dfp[] ln2Split; /** A {@link Dfp} with value ln(5). */ private final Dfp ln5; /** A two elements {@link Dfp} array with value ln(5) split in two pieces. */ private final Dfp[] ln5Split; /** A {@link Dfp} with value ln(10). */ private final Dfp ln10; /** Current rounding mode. */ private RoundingMode rMode; /** IEEE 854-1987 signals. */ private int ieeeFlags; /** Create a factory for the specified number of radix digits. *

                      * Note that since the {@link Dfp} class uses 10000 as its radix, each radix * digit is equivalent to 4 decimal digits. This implies that asking for * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in * all cases. *

                      * @param decimalDigits minimal number of decimal digits. */ public DfpField(final int decimalDigits) { this(decimalDigits, true); } /** Create a factory for the specified number of radix digits. *

                      * Note that since the {@link Dfp} class uses 10000 as its radix, each radix * digit is equivalent to 4 decimal digits. This implies that asking for * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in * all cases. *

                      * @param decimalDigits minimal number of decimal digits * @param computeConstants if true, the transcendental constants for the given precision * must be computed (setting this flag to false is RESERVED for the internal recursive call) */ private DfpField(final int decimalDigits, final boolean computeConstants) { this.radixDigits = (decimalDigits < 13) ? 4 : (decimalDigits + 3) / 4; this.rMode = RoundingMode.ROUND_HALF_EVEN; this.ieeeFlags = 0; this.zero = new Dfp(this, 0); this.one = new Dfp(this, 1); this.two = new Dfp(this, 2); if (computeConstants) { // set up transcendental constants synchronized (DfpField.class) { // as a heuristic to circumvent Table-Maker's Dilemma, we set the string // representation of the constants to be at least 3 times larger than the // number of decimal digits, also as an attempt to really compute these // constants only once, we set a minimum number of digits computeStringConstants((decimalDigits < 67) ? 200 : (3 * decimalDigits)); // set up the constants at current field accuracy sqr2 = new Dfp(this, sqr2String); sqr2Split = split(sqr2String); sqr2Reciprocal = new Dfp(this, sqr2ReciprocalString); sqr3 = new Dfp(this, sqr3String); sqr3Reciprocal = new Dfp(this, sqr3ReciprocalString); pi = new Dfp(this, piString); piSplit = split(piString); e = new Dfp(this, eString); eSplit = split(eString); ln2 = new Dfp(this, ln2String); ln2Split = split(ln2String); ln5 = new Dfp(this, ln5String); ln5Split = split(ln5String); ln10 = new Dfp(this, ln10String); } } else { // dummy settings for unused constants sqr2 = null; sqr2Split = null; sqr2Reciprocal = null; sqr3 = null; sqr3Reciprocal = null; pi = null; piSplit = null; e = null; eSplit = null; ln2 = null; ln2Split = null; ln5 = null; ln5Split = null; ln10 = null; } } /** Get the number of radix digits of the {@link Dfp} instances built by this factory. * @return number of radix digits */ public int getRadixDigits() { return radixDigits; } /** Set the rounding mode. * If not set, the default value is {@link RoundingMode#ROUND_HALF_EVEN}. * @param mode desired rounding mode * Note that the rounding mode is common to all {@link Dfp} instances * belonging to the current {@link DfpField} in the system and will * affect all future calculations. */ public void setRoundingMode(final RoundingMode mode) { rMode = mode; } /** Get the current rounding mode. * @return current rounding mode */ public RoundingMode getRoundingMode() { return rMode; } /** Get the IEEE 854 status flags. * @return IEEE 854 status flags * @see #clearIEEEFlags() * @see #setIEEEFlags(int) * @see #setIEEEFlagsBits(int) * @see #FLAG_INVALID * @see #FLAG_DIV_ZERO * @see #FLAG_OVERFLOW * @see #FLAG_UNDERFLOW * @see #FLAG_INEXACT */ public int getIEEEFlags() { return ieeeFlags; } /** Clears the IEEE 854 status flags. * @see #getIEEEFlags() * @see #setIEEEFlags(int) * @see #setIEEEFlagsBits(int) * @see #FLAG_INVALID * @see #FLAG_DIV_ZERO * @see #FLAG_OVERFLOW * @see #FLAG_UNDERFLOW * @see #FLAG_INEXACT */ public void clearIEEEFlags() { ieeeFlags = 0; } /** Sets the IEEE 854 status flags. * @param flags desired value for the flags * @see #getIEEEFlags() * @see #clearIEEEFlags() * @see #setIEEEFlagsBits(int) * @see #FLAG_INVALID * @see #FLAG_DIV_ZERO * @see #FLAG_OVERFLOW * @see #FLAG_UNDERFLOW * @see #FLAG_INEXACT */ public void setIEEEFlags(final int flags) { ieeeFlags = flags & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT); } /** Sets some bits in the IEEE 854 status flags, without changing the already set bits. *

                      * Calling this method is equivalent to call {@code setIEEEFlags(getIEEEFlags() | bits)} *

                      * @param bits bits to set * @see #getIEEEFlags() * @see #clearIEEEFlags() * @see #setIEEEFlags(int) * @see #FLAG_INVALID * @see #FLAG_DIV_ZERO * @see #FLAG_OVERFLOW * @see #FLAG_UNDERFLOW * @see #FLAG_INEXACT */ public void setIEEEFlagsBits(final int bits) { ieeeFlags |= bits & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT); } /** Makes a {@link Dfp} with a value of 0. * @return a new {@link Dfp} with a value of 0 */ public Dfp newDfp() { return new Dfp(this); } /** Create an instance from a byte value. * @param x value to convert to an instance * @return a new {@link Dfp} with the same value as x */ public Dfp newDfp(final byte x) { return new Dfp(this, x); } /** Create an instance from an int value. * @param x value to convert to an instance * @return a new {@link Dfp} with the same value as x */ public Dfp newDfp(final int x) { return new Dfp(this, x); } /** Create an instance from a long value. * @param x value to convert to an instance * @return a new {@link Dfp} with the same value as x */ public Dfp newDfp(final long x) { return new Dfp(this, x); } /** Create an instance from a double value. * @param x value to convert to an instance * @return a new {@link Dfp} with the same value as x */ public Dfp newDfp(final double x) { return new Dfp(this, x); } /** Copy constructor. * @param d instance to copy * @return a new {@link Dfp} with the same value as d */ public Dfp newDfp(Dfp d) { return new Dfp(d); } /** Create a {@link Dfp} given a String representation. * @param s string representation of the instance * @return a new {@link Dfp} parsed from specified string */ public Dfp newDfp(final String s) { return new Dfp(this, s); } /** Creates a {@link Dfp} with a non-finite value. * @param sign sign of the Dfp to create * @param nans code of the value, must be one of {@link Dfp#INFINITE}, * {@link Dfp#SNAN}, {@link Dfp#QNAN} * @return a new {@link Dfp} with a non-finite value */ public Dfp newDfp(final byte sign, final byte nans) { return new Dfp(this, sign, nans); } /** Get the constant 0. * @return a {@link Dfp} with value 0 */ public Dfp getZero() { return zero; } /** Get the constant 1. * @return a {@link Dfp} with value 1 */ public Dfp getOne() { return one; } /** Get the constant 2. * @return a {@link Dfp} with value 2 */ public Dfp getTwo() { return two; } /** Get the constant √2. * @return a {@link Dfp} with value √2 */ public Dfp getSqr2() { return sqr2; } /** Get the constant √2 split in two pieces. * @return a {@link Dfp} with value √2 split in two pieces */ public Dfp[] getSqr2Split() { return sqr2Split.clone(); } /** Get the constant √2 / 2. * @return a {@link Dfp} with value √2 / 2 */ public Dfp getSqr2Reciprocal() { return sqr2Reciprocal; } /** Get the constant √3. * @return a {@link Dfp} with value √3 */ public Dfp getSqr3() { return sqr3; } /** Get the constant √3 / 3. * @return a {@link Dfp} with value √3 / 3 */ public Dfp getSqr3Reciprocal() { return sqr3Reciprocal; } /** Get the constant π. * @return a {@link Dfp} with value π */ public Dfp getPi() { return pi; } /** Get the constant π split in two pieces. * @return a {@link Dfp} with value π split in two pieces */ public Dfp[] getPiSplit() { return piSplit.clone(); } /** Get the constant e. * @return a {@link Dfp} with value e */ public Dfp getE() { return e; } /** Get the constant e split in two pieces. * @return a {@link Dfp} with value e split in two pieces */ public Dfp[] getESplit() { return eSplit.clone(); } /** Get the constant ln(2). * @return a {@link Dfp} with value ln(2) */ public Dfp getLn2() { return ln2; } /** Get the constant ln(2) split in two pieces. * @return a {@link Dfp} with value ln(2) split in two pieces */ public Dfp[] getLn2Split() { return ln2Split.clone(); } /** Get the constant ln(5). * @return a {@link Dfp} with value ln(5) */ public Dfp getLn5() { return ln5; } /** Get the constant ln(5) split in two pieces. * @return a {@link Dfp} with value ln(5) split in two pieces */ public Dfp[] getLn5Split() { return ln5Split.clone(); } /** Get the constant ln(10). * @return a {@link Dfp} with value ln(10) */ public Dfp getLn10() { return ln10; } /** Breaks a string representation up into two {@link Dfp}'s. * The split is such that the sum of them is equivalent to the input string, * but has higher precision than using a single Dfp. * @param a string representation of the number to split * @return an array of two {@link Dfp Dfp} instances which sum equals a */ private Dfp[] split(final String a) { Dfp result[] = new Dfp[2]; boolean leading = true; int sp = 0; int sig = 0; char[] buf = new char[a.length()]; for (int i = 0; i < buf.length; i++) { buf[i] = a.charAt(i); if (buf[i] >= '1' && buf[i] <= '9') { leading = false; } if (buf[i] == '.') { sig += (400 - sig) % 4; leading = false; } if (sig == (radixDigits / 2) * 4) { sp = i; break; } if (buf[i] >= '0' && buf[i] <= '9' && !leading) { sig ++; } } result[0] = new Dfp(this, new String(buf, 0, sp)); for (int i = 0; i < buf.length; i++) { buf[i] = a.charAt(i); if (buf[i] >= '0' && buf[i] <= '9' && i < sp) { buf[i] = '0'; } } result[1] = new Dfp(this, new String(buf)); return result; } /** Recompute the high precision string constants. * @param highPrecisionDecimalDigits precision at which the string constants mus be computed */ private static void computeStringConstants(final int highPrecisionDecimalDigits) { if (sqr2String == null || sqr2String.length() < highPrecisionDecimalDigits - 3) { // recompute the string representation of the transcendental constants final DfpField highPrecisionField = new DfpField(highPrecisionDecimalDigits, false); final Dfp highPrecisionOne = new Dfp(highPrecisionField, 1); final Dfp highPrecisionTwo = new Dfp(highPrecisionField, 2); final Dfp highPrecisionThree = new Dfp(highPrecisionField, 3); final Dfp highPrecisionSqr2 = highPrecisionTwo.sqrt(); sqr2String = highPrecisionSqr2.toString(); sqr2ReciprocalString = highPrecisionOne.divide(highPrecisionSqr2).toString(); final Dfp highPrecisionSqr3 = highPrecisionThree.sqrt(); sqr3String = highPrecisionSqr3.toString(); sqr3ReciprocalString = highPrecisionOne.divide(highPrecisionSqr3).toString(); piString = computePi(highPrecisionOne, highPrecisionTwo, highPrecisionThree).toString(); eString = computeExp(highPrecisionOne, highPrecisionOne).toString(); ln2String = computeLn(highPrecisionTwo, highPrecisionOne, highPrecisionTwo).toString(); ln5String = computeLn(new Dfp(highPrecisionField, 5), highPrecisionOne, highPrecisionTwo).toString(); ln10String = computeLn(new Dfp(highPrecisionField, 10), highPrecisionOne, highPrecisionTwo).toString(); } } /** Compute π using Jonathan and Peter Borwein quartic formula. * @param one constant with value 1 at desired precision * @param two constant with value 2 at desired precision * @param three constant with value 3 at desired precision * @return π */ private static Dfp computePi(final Dfp one, final Dfp two, final Dfp three) { Dfp sqrt2 = two.sqrt(); Dfp yk = sqrt2.subtract(one); Dfp four = two.add(two); Dfp two2kp3 = two; Dfp ak = two.multiply(three.subtract(two.multiply(sqrt2))); // The formula converges quartically. This means the number of correct // digits is multiplied by 4 at each iteration! Five iterations are // sufficient for about 160 digits, eight iterations give about // 10000 digits (this has been checked) and 20 iterations more than // 160 billions of digits (this has NOT been checked). // So the limit here is considered sufficient for most purposes ... for (int i = 1; i < 20; i++) { final Dfp ykM1 = yk; final Dfp y2 = yk.multiply(yk); final Dfp oneMinusY4 = one.subtract(y2.multiply(y2)); final Dfp s = oneMinusY4.sqrt().sqrt(); yk = one.subtract(s).divide(one.add(s)); two2kp3 = two2kp3.multiply(four); final Dfp p = one.add(yk); final Dfp p2 = p.multiply(p); ak = ak.multiply(p2.multiply(p2)).subtract(two2kp3.multiply(yk).multiply(one.add(yk).add(yk.multiply(yk)))); if (yk.equals(ykM1)) { break; } } return one.divide(ak); } /** Compute exp(a). * @param a number for which we want the exponential * @param one constant with value 1 at desired precision * @return exp(a) */ public static Dfp computeExp(final Dfp a, final Dfp one) { Dfp y = new Dfp(one); Dfp py = new Dfp(one); Dfp f = new Dfp(one); Dfp fi = new Dfp(one); Dfp x = new Dfp(one); for (int i = 0; i < 10000; i++) { x = x.multiply(a); y = y.add(x.divide(f)); fi = fi.add(one); f = f.multiply(fi); if (y.equals(py)) { break; } py = new Dfp(y); } return y; } /** Compute ln(a). * * Let f(x) = ln(x), * * We know that f'(x) = 1/x, thus from Taylor's theorem we have: * * ----- n+1 n * f(x) = \ (-1) (x - 1) * / ---------------- for 1 <= n <= infinity * ----- n * * or * 2 3 4 * (x-1) (x-1) (x-1) * ln(x) = (x-1) - ----- + ------ - ------ + ... * 2 3 4 * * alternatively, * * 2 3 4 * x x x * ln(x+1) = x - - + - - - + ... * 2 3 4 * * This series can be used to compute ln(x), but it converges too slowly. * * If we substitute -x for x above, we get * * 2 3 4 * x x x * ln(1-x) = -x - - - - - - + ... * 2 3 4 * * Note that all terms are now negative. Because the even powered ones * absorbed the sign. Now, subtract the series above from the previous * one to get ln(x+1) - ln(1-x). Note the even terms cancel out leaving * only the odd ones * * 3 5 7 * 2x 2x 2x * ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ... * 3 5 7 * * By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have: * * 3 5 7 * x+1 / x x x \ * ln ----- = 2 * | x + ---- + ---- + ---- + ... | * x-1 \ 3 5 7 / * * But now we want to find ln(a), so we need to find the value of x * such that a = (x+1)/(x-1). This is easily solved to find that * x = (a-1)/(a+1). * @param a number for which we want the exponential * @param one constant with value 1 at desired precision * @param two constant with value 2 at desired precision * @return ln(a) */ public static Dfp computeLn(final Dfp a, final Dfp one, final Dfp two) { int den = 1; Dfp x = a.add(new Dfp(a.getField(), -1)).divide(a.add(one)); Dfp y = new Dfp(x); Dfp num = new Dfp(x); Dfp py = new Dfp(y); for (int i = 0; i < 10000; i++) { num = num.multiply(x); num = num.multiply(x); den = den + 2; Dfp t = num.divide(den); y = y.add(t); if (y.equals(py)) { break; } py = new Dfp(y); } return y.multiply(two); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/DiscreteDistribution.java100644 1750 1750 2725 11532241245 32076 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Base interface for discrete distributions. * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface DiscreteDistribution extends Distribution { /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X = x). In other words, this * method represents the probability mass function, or PMF for the distribution. * * @param x the value at which the probability mass function is evaluated. * @return the value of the probability mass function at x */ double probability(double x); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java100644 1750 1750 20226 11532241245 32045 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.special.Beta; import org.apache.commons.math.util.FastMath; /** * Implements the Beta distribution. *

                      * References: *

                      *

                      * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ * @since 2.0 */ public class BetaDistributionImpl extends AbstractContinuousDistribution implements BetaDistribution { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier. */ private static final long serialVersionUID = -1221965979403477668L; /** First shape parameter. */ private double alpha; /** Second shape parameter. */ private double beta; /** Normalizing factor used in density computations. * updated whenever alpha or beta are changed. */ private double z; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Build a new instance. * @param alpha first shape parameter (must be positive) * @param beta second shape parameter (must be positive) * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public BetaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) { this.alpha = alpha; this.beta = beta; z = Double.NaN; solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Build a new instance. * @param alpha first shape parameter (must be positive) * @param beta second shape parameter (must be positive) */ public BetaDistributionImpl(double alpha, double beta) { this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** {@inheritDoc} * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setAlpha(double alpha) { this.alpha = alpha; z = Double.NaN; } /** {@inheritDoc} */ public double getAlpha() { return alpha; } /** {@inheritDoc} * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setBeta(double beta) { this.beta = beta; z = Double.NaN; } /** {@inheritDoc} */ public double getBeta() { return beta; } /** * Recompute the normalization factor. */ private void recomputeZ() { if (Double.isNaN(z)) { z = Gamma.logGamma(alpha) + Gamma.logGamma(beta) - Gamma.logGamma(alpha + beta); } } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @deprecated */ @Deprecated public double density(Double x) { return density(x.doubleValue()); } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { recomputeZ(); if (x < 0 || x > 1) { return 0; } else if (x == 0) { if (alpha < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA, alpha); } return 0; } else if (x == 1) { if (beta < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA, beta); } return 0; } else { double logX = FastMath.log(x); double log1mX = FastMath.log1p(-x); return FastMath.exp((alpha - 1) * logX + (beta - 1) * log1mX - z); } } /** {@inheritDoc} */ @Override public double inverseCumulativeProbability(double p) throws MathException { if (p == 0) { return 0; } else if (p == 1) { return 1; } else { return super.inverseCumulativeProbability(p); } } /** {@inheritDoc} */ @Override protected double getInitialDomain(double p) { return p; } /** {@inheritDoc} */ @Override protected double getDomainLowerBound(double p) { return 0; } /** {@inheritDoc} */ @Override protected double getDomainUpperBound(double p) { return 1; } /** {@inheritDoc} */ public double cumulativeProbability(double x) throws MathException { if (x <= 0) { return 0; } else if (x >= 1) { return 1; } else { return Beta.regularizedBeta(x, alpha, beta); } } /** {@inheritDoc} */ @Override public double cumulativeProbability(double x0, double x1) throws MathException { return cumulativeProbability(x1) - cumulativeProbability(x0); } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for this distribution. * The support of the Beta distribution is always [0, 1], regardless * of the parameters, so this method always returns 0. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for this distribution. * The support of the Beta distribution is always [0, 1], regardless * of the parameters, so this method always returns 1. * * @return lower bound of the support (always 1) * @since 2.2 */ public double getSupportUpperBound() { return 1; } /** * Returns the mean. * * For first shape parameter s1 and * second shape parameter s2, the mean is * s1 / (s1 + s2) * * @return the mean * @since 2.2 */ public double getNumericalMean() { final double a = getAlpha(); return a / (a + getBeta()); } /** * Returns the variance. * * For first shape parameter s1 and * second shape parameter s2, * the variance is * [ s1 * s2 ] / [ (s1 + s2)^2 * (s1 + s2 + 1) ] * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double a = getAlpha(); final double b = getBeta(); final double alphabetasum = a + b; return (a * b) / ((alphabetasum * alphabetasum) * (alphabetasum + 1)); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/GammaDistribution.java100644 1750 1750 3711 11532241245 31352 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Gamma Distribution. * *

                      * References: *

                      *

                      * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface GammaDistribution extends ContinuousDistribution, HasDensity { /** * Modify the shape parameter, alpha. * @param alpha the new shape parameter. * @deprecated as of v2.1 */ @Deprecated void setAlpha(double alpha); /** * Access the shape parameter, alpha * @return alpha. */ double getAlpha(); /** * Modify the scale parameter, beta. * @param beta the new scale parameter. * @deprecated as of v2.1 */ @Deprecated void setBeta(double beta); /** * Access the scale parameter, beta * @return beta. */ double getBeta(); /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. */ double density(Double x); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/TDistribution.java100644 1750 1750 3013 11532241245 30526 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Student's t-Distribution. * *

                      * References: *

                      *

                      * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface TDistribution extends ContinuousDistribution { /** * Modify the degrees of freedom. * @param degreesOfFreedom the new degrees of freedom. * @deprecated as of v2.1 */ @Deprecated void setDegreesOfFreedom(double degreesOfFreedom); /** * Access the degrees of freedom. * @return the degrees of freedom. */ double getDegreesOfFreedom(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/BetaDistribution.java100644 1750 1750 4200 11532241245 31175 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** * Computes the cumulative, inverse cumulative and density functions for the beta distribuiton. * * @see Beta_distribution * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ * @since 2.0 */ public interface BetaDistribution extends ContinuousDistribution, HasDensity { /** * Modify the shape parameter, alpha. * @param alpha the new shape parameter. * @deprecated as of 2.1 */ @Deprecated void setAlpha(double alpha); /** * Access the shape parameter, alpha * @return alpha. */ double getAlpha(); /** * Modify the shape parameter, beta. * @param beta the new scale parameter. * @deprecated as of 2.1 */ @Deprecated void setBeta(double beta); /** * Access the shape parameter, beta * @return beta. */ double getBeta(); /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. * @exception MathException if probability density cannot be computed */ double density(Double x) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/HasDensity.java100644 1750 1750 3441 11532241245 30003 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** *

                      Interface that signals that a distribution can compute the probability density function * for a particular point. * @param

                      the type of the point at which density is to be computed, this * may be for example Double.

                      * *

                      This interface is deprecated. As of version 2.0, the {@link ContinuousDistribution} * interface will be extended to include a density(double) method.

                      * * @deprecated to be removed in math 3.0 * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $ */ @Deprecated public interface HasDensity

                      { /** * Compute the probability density function. * @param x point for which the probability density is requested * @return probability density at point x * @throws MathException if probability density cannot be computed at specifed point */ double density(P x) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/IntegerDistribution.java100644 1750 1750 7335 11532241245 31733 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** * Interface for discrete distributions of integer-valued random variables. * * @version $Revision: 949535 $ $Date: 2010-05-30 19:00:15 +0200 (dim. 30 mai 2010) $ */ public interface IntegerDistribution extends DiscreteDistribution { /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X = x). In other words, this * method represents the probability mass function for the distribution. * * @param x the value at which the probability density function is evaluated. * @return the value of the probability density function at x */ double probability(int x); /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X ≤ x). In other words, * this method represents the probability distribution function, or PDF * for the distribution. * * @param x the value at which the PDF is evaluated. * @return PDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ double cumulativeProbability(int x) throws MathException; /** * For this distribution, X, this method returns P(x0 ≤ X ≤ x1). * @param x0 the inclusive, lower bound * @param x1 the inclusive, upper bound * @return the cumulative probability. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if x0 > x1 */ double cumulativeProbability(int x0, int x1) throws MathException; /** * For this distribution, X, this method returns the largest x such that * P(X ≤ x) <= p. *

                      * Note that this definition implies:

                        *
                      • If there is a minimum value, m, with positive * probability under (the density of) X, then m - 1 is * returned by inverseCumulativeProbability(0). If there is * no such value m, Integer.MIN_VALUE is * returned.
                      • *
                      • If there is a maximum value, M, such that * P(X ≤ M) =1, then M is returned by * inverseCumulativeProbability(1). * If there is no such value, M, Integer.MAX_VALUE is * returned.

                      * * @param p the cumulative probability. * @return the largest x such that P(X ≤ x) <= p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not between 0 and 1 (inclusive) */ int inverseCumulativeProbability(double p) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/SaddlePointExpansion.java100644 1750 1750 15603 11532241245 32046 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** *

                      * Utility class used by various distributions to accurately compute their * respective probability mass functions. The implementation for this class is * based on the Catherine Loader's dbinom routines. *

                      *

                      * This class is not intended to be called directly. *

                      *

                      * References: *

                        *
                      1. Catherine Loader (2000). "Fast and Accurate Computation of Binomial * Probabilities.". * http://www.herine.net/stat/papers/dbinom.pdf
                      2. *
                      *

                      * * @since 2.1 * @version $Revision$ $Date$ */ final class SaddlePointExpansion { /** 1/2 * log(2 π). */ private static final double HALF_LOG_2_PI = 0.5 * FastMath.log(MathUtils.TWO_PI); /** exact Stirling expansion error for certain values. */ private static final double[] EXACT_STIRLING_ERRORS = { 0.0, /* 0.0 */ 0.1534264097200273452913848, /* 0.5 */ 0.0810614667953272582196702, /* 1.0 */ 0.0548141210519176538961390, /* 1.5 */ 0.0413406959554092940938221, /* 2.0 */ 0.03316287351993628748511048, /* 2.5 */ 0.02767792568499833914878929, /* 3.0 */ 0.02374616365629749597132920, /* 3.5 */ 0.02079067210376509311152277, /* 4.0 */ 0.01848845053267318523077934, /* 4.5 */ 0.01664469118982119216319487, /* 5.0 */ 0.01513497322191737887351255, /* 5.5 */ 0.01387612882307074799874573, /* 6.0 */ 0.01281046524292022692424986, /* 6.5 */ 0.01189670994589177009505572, /* 7.0 */ 0.01110455975820691732662991, /* 7.5 */ 0.010411265261972096497478567, /* 8.0 */ 0.009799416126158803298389475, /* 8.5 */ 0.009255462182712732917728637, /* 9.0 */ 0.008768700134139385462952823, /* 9.5 */ 0.008330563433362871256469318, /* 10.0 */ 0.007934114564314020547248100, /* 10.5 */ 0.007573675487951840794972024, /* 11.0 */ 0.007244554301320383179543912, /* 11.5 */ 0.006942840107209529865664152, /* 12.0 */ 0.006665247032707682442354394, /* 12.5 */ 0.006408994188004207068439631, /* 13.0 */ 0.006171712263039457647532867, /* 13.5 */ 0.005951370112758847735624416, /* 14.0 */ 0.005746216513010115682023589, /* 14.5 */ 0.005554733551962801371038690 /* 15.0 */ }; /** * Default constructor. */ private SaddlePointExpansion() { super(); } /** * Compute the error of Stirling's series at the given value. *

                      * References: *

                        *
                      1. Eric W. Weisstein. "Stirling's Series." From MathWorld--A Wolfram Web * Resource. * http://mathworld.wolfram.com/StirlingsSeries.html
                      2. *
                      *

                      * * @param z the value. * @return the Striling's series error. */ static double getStirlingError(double z) { double ret; if (z < 15.0) { double z2 = 2.0 * z; if (FastMath.floor(z2) == z2) { ret = EXACT_STIRLING_ERRORS[(int) z2]; } else { ret = Gamma.logGamma(z + 1.0) - (z + 0.5) * FastMath.log(z) + z - HALF_LOG_2_PI; } } else { double z2 = z * z; ret = (0.083333333333333333333 - (0.00277777777777777777778 - (0.00079365079365079365079365 - (0.000595238095238095238095238 - 0.0008417508417508417508417508 / z2) / z2) / z2) / z2) / z; } return ret; } /** * A part of the deviance portion of the saddle point approximation. *

                      * References: *

                        *
                      1. Catherine Loader (2000). "Fast and Accurate Computation of Binomial * Probabilities.". * http://www.herine.net/stat/papers/dbinom.pdf
                      2. *
                      *

                      * * @param x the x value. * @param mu the average. * @return a part of the deviance. */ static double getDeviancePart(double x, double mu) { double ret; if (FastMath.abs(x - mu) < 0.1 * (x + mu)) { double d = x - mu; double v = d / (x + mu); double s1 = v * d; double s = Double.NaN; double ej = 2.0 * x * v; v = v * v; int j = 1; while (s1 != s) { s = s1; ej *= v; s1 = s + ej / ((j * 2) + 1); ++j; } ret = s1; } else { ret = x * FastMath.log(x / mu) + mu - x; } return ret; } /** * Compute the PMF for a binomial distribution using the saddle point * expansion. * * @param x the value at which the probability is evaluated. * @param n the number of trials. * @param p the probability of success. * @param q the probability of failure (1 - p). * @return log(p(x)). */ static double logBinomialProbability(int x, int n, double p, double q) { double ret; if (x == 0) { if (p < 0.1) { ret = -getDeviancePart(n, n * q) - n * p; } else { ret = n * FastMath.log(q); } } else if (x == n) { if (q < 0.1) { ret = -getDeviancePart(n, n * p) - n * q; } else { ret = n * FastMath.log(p); } } else { ret = getStirlingError(n) - getStirlingError(x) - getStirlingError(n - x) - getDeviancePart(x, n * p) - getDeviancePart(n - x, n * q); double f = (MathUtils.TWO_PI * x * (n - x)) / n; ret = -0.5 * FastMath.log(f) + ret; } return ret; } } ././@LongLink100644 0 0 150 11532242443 10247 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.j100644 1750 1750 23764 11532241245 32544 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; /** * The default implementation of {@link ChiSquaredDistribution} * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class ChiSquaredDistributionImpl extends AbstractContinuousDistribution implements ChiSquaredDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = -8352658048349159782L; /** Internal Gamma distribution. */ private GammaDistribution gamma; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a Chi-Squared distribution with the given degrees of freedom. * @param df degrees of freedom. */ public ChiSquaredDistributionImpl(double df) { this(df, new GammaDistributionImpl(df / 2.0, 2.0)); } /** * Create a Chi-Squared distribution with the given degrees of freedom. * @param df degrees of freedom. * @param g the underlying gamma distribution used to compute probabilities. * @since 1.2 * @deprecated as of 2.1 (to avoid possibly inconsistent state, the * "GammaDistribution" will be instantiated internally) */ @Deprecated public ChiSquaredDistributionImpl(double df, GammaDistribution g) { super(); setGammaInternal(g); setDegreesOfFreedomInternal(df); solverAbsoluteAccuracy = DEFAULT_INVERSE_ABSOLUTE_ACCURACY; } /** * Create a Chi-Squared distribution with the given degrees of freedom and * inverse cumulative probability accuracy. * @param df degrees of freedom. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public ChiSquaredDistributionImpl(double df, double inverseCumAccuracy) { super(); gamma = new GammaDistributionImpl(df / 2.0, 2.0); setDegreesOfFreedomInternal(df); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Modify the degrees of freedom. * @param degreesOfFreedom the new degrees of freedom. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setDegreesOfFreedom(double degreesOfFreedom) { setDegreesOfFreedomInternal(degreesOfFreedom); } /** * Modify the degrees of freedom. * @param degreesOfFreedom the new degrees of freedom. */ private void setDegreesOfFreedomInternal(double degreesOfFreedom) { gamma.setAlpha(degreesOfFreedom / 2.0); } /** * Access the degrees of freedom. * @return the degrees of freedom. */ public double getDegreesOfFreedom() { return gamma.getAlpha() * 2.0; } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @deprecated */ @Deprecated public double density(Double x) { return density(x.doubleValue()); } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { return gamma.density(x); } /** * For this distribution, X, this method returns P(X < x). * @param x the value at which the CDF is evaluated. * @return CDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException { return gamma.cumulativeProbability(x); } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                      * Returns 0 for p=0 and Double.POSITIVE_INFINITY for p=1.

                      * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(final double p) throws MathException { if (p == 0) { return 0d; } if (p == 1) { return Double.POSITIVE_INFINITY; } return super.inverseCumulativeProbability(p); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { return Double.MIN_VALUE * gamma.getBeta(); } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { // NOTE: chi squared is skewed to the left // NOTE: therefore, P(X < μ) > .5 double ret; if (p < .5) { // use mean ret = getDegreesOfFreedom(); } else { // use max ret = Double.MAX_VALUE; } return ret; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { // NOTE: chi squared is skewed to the left // NOTE: therefore, P(X < μ) > .5 double ret; if (p < .5) { // use 1/2 mean ret = getDegreesOfFreedom() * .5; } else { // use mean ret = getDegreesOfFreedom(); } return ret; } /** * Modify the underlying gamma distribution. The caller is responsible for * insuring the gamma distribution has the proper parameter settings. * @param g the new distribution. * @since 1.2 made public * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setGamma(GammaDistribution g) { setGammaInternal(g); } /** * Modify the underlying gamma distribution. The caller is responsible for * insuring the gamma distribution has the proper parameter settings. * @param g the new distribution. * @since 1.2 made public */ private void setGammaInternal(GammaDistribution g) { this.gamma = g; } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0 no matter the * degrees of freedom. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound for the support for the distribution. * * The upper bound of the support is always positive infinity no matter the * degrees of freedom. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean of the distribution. * * For k degrees of freedom, the mean is * k * * @return the mean * @since 2.2 */ public double getNumericalMean() { return getDegreesOfFreedom(); } /** * Returns the variance of the distribution. * * For k degrees of freedom, the variance is * 2 * k * * @return the variance * @since 2.2 */ public double getNumericalVariance() { return 2*getDegreesOfFreedom(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/Distribution.java100644 1750 1750 4653 11532241245 30415 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** * Base interface for probability distributions. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public interface Distribution { /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X ≤ x). In other words, * this method represents the (cumulative) distribution function, or * CDF, for this distribution. * * @param x the value at which the distribution function is evaluated. * @return the probability that a random variable with this * distribution takes a value less than or equal to x * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ double cumulativeProbability(double x) throws MathException; /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(x0 ≤ X ≤ x1). * * @param x0 the (inclusive) lower bound * @param x1 the (inclusive) upper bound * @return the probability that a random variable with this distribution * will take a value between x0 and x1, * including the endpoints * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if x0 > x1 */ double cumulativeProbability(double x0, double x1) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ZipfDistribution.java100644 1750 1750 4302 11532241245 31235 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Zipf (or zeta) Distribution. *

                      * References: *

                      *

                      * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface ZipfDistribution extends IntegerDistribution { /** * Get the number of elements (e.g. corpus size) for the distribution. * * @return the number of elements */ int getNumberOfElements(); /** * Set the number of elements (e.g. corpus size) for the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param n the number of elements * @throws IllegalArgumentException if n ≤ 0 * @deprecated as of v2.1 */ @Deprecated void setNumberOfElements(int n); /** * Get the exponent characterising the distribution. * * @return the exponent */ double getExponent(); /** * Set the exponent characterising the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param s the exponent * @throws IllegalArgumentException if s ≤ 0.0 * @deprecated as of v2.1 */ @Deprecated void setExponent(double s); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java100644 1750 1750 21724 11532241245 32401 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Beta; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * The default implementation of {@link PascalDistribution}. * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ * @since 1.2 */ public class PascalDistributionImpl extends AbstractIntegerDistribution implements PascalDistribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 6751309484392813623L; /** The number of successes */ private int numberOfSuccesses; /** The probability of success */ private double probabilityOfSuccess; /** * Create a Pascal distribution with the given number of trials and * probability of success. * @param r the number of successes * @param p the probability of success */ public PascalDistributionImpl(int r, double p) { super(); setNumberOfSuccessesInternal(r); setProbabilityOfSuccessInternal(p); } /** * Access the number of successes for this distribution. * @return the number of successes */ public int getNumberOfSuccesses() { return numberOfSuccesses; } /** * Access the probability of success for this distribution. * @return the probability of success */ public double getProbabilityOfSuccess() { return probabilityOfSuccess; } /** * Change the number of successes for this distribution. * @param successes the new number of successes * @throws IllegalArgumentException if successes is not * positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNumberOfSuccesses(int successes) { setNumberOfSuccessesInternal(successes); } /** * Change the number of successes for this distribution. * @param successes the new number of successes * @throws IllegalArgumentException if successes is not * positive. */ private void setNumberOfSuccessesInternal(int successes) { if (successes < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_NUMBER_OF_SUCCESSES, successes); } numberOfSuccesses = successes; } /** * Change the probability of success for this distribution. * @param p the new probability of success * @throws IllegalArgumentException if p is not a valid * probability. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setProbabilityOfSuccess(double p) { setProbabilityOfSuccessInternal(p); } /** * Change the probability of success for this distribution. * @param p the new probability of success * @throws IllegalArgumentException if p is not a valid * probability. */ private void setProbabilityOfSuccessInternal(double p) { if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } probabilityOfSuccess = p; } /** * Access the domain value lower bound, based on p, used to * bracket a PDF root. * @param p the desired probability for the critical value * @return domain value lower bound, i.e. P(X < lower bound) < * p */ @Override protected int getDomainLowerBound(double p) { return -1; } /** * Access the domain value upper bound, based on p, used to * bracket a PDF root. * @param p the desired probability for the critical value * @return domain value upper bound, i.e. P(X < upper bound) > * p */ @Override protected int getDomainUpperBound(double p) { // use MAX - 1 because MAX causes loop return Integer.MAX_VALUE - 1; } /** * For this distribution, X, this method returns P(X ≤ x). * @param x the value at which the PDF is evaluated * @return PDF for this distribution * @throws MathException if the cumulative probability can not be computed * due to convergence or other numerical errors */ @Override public double cumulativeProbability(int x) throws MathException { double ret; if (x < 0) { ret = 0.0; } else { ret = Beta.regularizedBeta(probabilityOfSuccess, numberOfSuccesses, x + 1); } return ret; } /** * For this distribution, X, this method returns P(X = x). * @param x the value at which the PMF is evaluated * @return PMF for this distribution */ public double probability(int x) { double ret; if (x < 0) { ret = 0.0; } else { ret = MathUtils.binomialCoefficientDouble(x + numberOfSuccesses - 1, numberOfSuccesses - 1) * FastMath.pow(probabilityOfSuccess, numberOfSuccesses) * FastMath.pow(1.0 - probabilityOfSuccess, x); } return ret; } /** * For this distribution, X, this method returns the largest x, such that * P(X ≤ x) ≤ p. *

                      * Returns -1 for p=0 and Integer.MAX_VALUE * for p=1.

                      * @param p the desired probability * @return the largest x such that P(X ≤ x) <= p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p < 0 or p > 1 */ @Override public int inverseCumulativeProbability(final double p) throws MathException { int ret; // handle extreme values explicitly if (p == 0) { ret = -1; } else if (p == 1) { ret = Integer.MAX_VALUE; } else { ret = super.inverseCumulativeProbability(p); } return ret; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0 no matter the parameters. * * @return lower bound of the support (always 0) * @since 2.2 */ public int getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity * no matter the parameters. Positive infinity is represented * by Integer.MAX_VALUE together with * {@link #isSupportUpperBoundInclusive()} being false * * @return upper bound of the support (always Integer.MAX_VALUE for positive infinity) * @since 2.2 */ public int getSupportUpperBound() { return Integer.MAX_VALUE; } /** * Returns the mean. * * For number of successes r and * probability of success p, the mean is * ( r * p ) / ( 1 - p ) * * @return the mean * @since 2.2 */ public double getNumericalMean() { final double p = getProbabilityOfSuccess(); final double r = getNumberOfSuccesses(); return ( r * p ) / ( 1 - p ); } /** * Returns the variance. * * For number of successes r and * probability of success p, the mean is * ( r * p ) / ( 1 - p )^2 * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double p = getProbabilityOfSuccess(); final double r = getNumberOfSuccesses(); final double pInv = 1 - p; return ( r * p ) / (pInv * pInv); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/PascalDistribution.java100644 1750 1750 5013 11532241245 31530 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Pascal distribution. The Pascal distribution is a special case of the * Negative Binomial distribution where the number of successes parameter is an * integer. * * There are various ways to express the probability mass and distribution * functions for the Pascal distribution. The convention employed by the * library is to express these functions in terms of the number of failures in * a Bernoulli experiment [2]. * *

                      * References: *

                        *
                      1. * Negative Binomial Distribution
                      2. * Waiting Time in a Bernoulli Process * *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ * @since 1.2 */ public interface PascalDistribution extends IntegerDistribution { /** * Access the number of successes for this distribution. * * @return the number of successes */ int getNumberOfSuccesses(); /** * Access the probability of success for this distribution. * * @return the probability of success */ double getProbabilityOfSuccess(); /** * Change the number of successes for this distribution. * * @param successes the new number of successes * @deprecated as of v2.1 */ @Deprecated void setNumberOfSuccesses(int successes); /** * Change the probability of success for this distribution. * * @param p the new probability of success * @deprecated as of v2.1 */ @Deprecated void setProbabilityOfSuccess(double p); } ././@LongLink100644 0 0 146 11532242443 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.jav100644 1750 1750 21170 11532241245 32562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Beta; import org.apache.commons.math.util.FastMath; /** * The default implementation of {@link BinomialDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class BinomialDistributionImpl extends AbstractIntegerDistribution implements BinomialDistribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 6751309484392813623L; /** The number of trials. */ private int numberOfTrials; /** The probability of success. */ private double probabilityOfSuccess; /** * Create a binomial distribution with the given number of trials and * probability of success. * * @param trials the number of trials. * @param p the probability of success. */ public BinomialDistributionImpl(int trials, double p) { super(); setNumberOfTrialsInternal(trials); setProbabilityOfSuccessInternal(p); } /** * Access the number of trials for this distribution. * * @return the number of trials. */ public int getNumberOfTrials() { return numberOfTrials; } /** * Access the probability of success for this distribution. * * @return the probability of success. */ public double getProbabilityOfSuccess() { return probabilityOfSuccess; } /** * Change the number of trials for this distribution. * * @param trials the new number of trials. * @throws IllegalArgumentException if trials is not a valid * number of trials. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNumberOfTrials(int trials) { setNumberOfTrialsInternal(trials); } /** * Change the number of trials for this distribution. * * @param trials the new number of trials. * @throws IllegalArgumentException if trials is not a valid * number of trials. */ private void setNumberOfTrialsInternal(int trials) { if (trials < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_NUMBER_OF_TRIALS, trials); } numberOfTrials = trials; } /** * Change the probability of success for this distribution. * * @param p the new probability of success. * @throws IllegalArgumentException if p is not a valid * probability. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setProbabilityOfSuccess(double p) { setProbabilityOfSuccessInternal(p); } /** * Change the probability of success for this distribution. * * @param p the new probability of success. * @throws IllegalArgumentException if p is not a valid * probability. */ private void setProbabilityOfSuccessInternal(double p) { if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } probabilityOfSuccess = p; } /** * Access the domain value lower bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. P(X < lower bound) < * p */ @Override protected int getDomainLowerBound(double p) { return -1; } /** * Access the domain value upper bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. P(X < upper bound) > * p */ @Override protected int getDomainUpperBound(double p) { return numberOfTrials; } /** * For this distribution, X, this method returns P(X ≤ x). * * @param x the value at which the PDF is evaluated. * @return PDF for this distribution. * @throws MathException if the cumulative probability can not be computed * due to convergence or other numerical errors. */ @Override public double cumulativeProbability(int x) throws MathException { double ret; if (x < 0) { ret = 0.0; } else if (x >= numberOfTrials) { ret = 1.0; } else { ret = 1.0 - Beta.regularizedBeta(getProbabilityOfSuccess(), x + 1.0, numberOfTrials - x); } return ret; } /** * For this distribution, X, this method returns P(X = x). * * @param x the value at which the PMF is evaluated. * @return PMF for this distribution. */ public double probability(int x) { double ret; if (x < 0 || x > numberOfTrials) { ret = 0.0; } else { ret = FastMath.exp(SaddlePointExpansion.logBinomialProbability(x, numberOfTrials, probabilityOfSuccess, 1.0 - probabilityOfSuccess)); } return ret; } /** * For this distribution, X, this method returns the largest x, such that * P(X ≤ x) ≤ p. *

                        * Returns -1 for p=0 and Integer.MAX_VALUE for * p=1. *

                        * * @param p the desired probability * @return the largest x such that P(X ≤ x) <= p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p < 0 or p > 1 */ @Override public int inverseCumulativeProbability(final double p) throws MathException { // handle extreme values explicitly if (p == 0) { return -1; } if (p == 1) { return Integer.MAX_VALUE; } // use default bisection impl return super.inverseCumulativeProbability(p); } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0 no matter the number of trials * and probability parameter. * * @return lower bound of the support (always 0) * @since 2.2 */ public int getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is the number of trials. * * @return upper bound of the support (equal to number of trials) * @since 2.2 */ public int getSupportUpperBound() { return getNumberOfTrials(); } /** * Returns the mean. * * For n number of trials and * probability parameter p, the mean is * n * p * * @return the mean * @since 2.2 */ public double getNumericalMean() { return (double)getNumberOfTrials() * getProbabilityOfSuccess(); } /** * Returns the variance. * * For n number of trials and * probability parameter p, the variance is * n * p * (1 - p) * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double p = getProbabilityOfSuccess(); return (double)getNumberOfTrials() * p * (1 - p); } } ././@LongLink100644 0 0 145 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/WeibullDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/WeibullDistributionImpl.java100644 1750 1750 26720 11532241245 32602 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.FastMath; /** * Default implementation of * {@link org.apache.commons.math.distribution.WeibullDistribution}. * * @since 1.1 * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class WeibullDistributionImpl extends AbstractContinuousDistribution implements WeibullDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = 8589540077390120676L; /** The shape parameter. */ private double shape; /** The scale parameter. */ private double scale; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** Cached numerical mean */ private double numericalMean = Double.NaN; /** Whether or not the numerical mean has been calculated */ private boolean numericalMeanIsCalculated = false; /** Cached numerical variance */ private double numericalVariance = Double.NaN; /** Whether or not the numerical variance has been calculated */ private boolean numericalVarianceIsCalculated = false; /** * Creates weibull distribution with the given shape and scale and a * location equal to zero. * @param alpha the shape parameter. * @param beta the scale parameter. */ public WeibullDistributionImpl(double alpha, double beta){ this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Creates weibull distribution with the given shape, scale and inverse * cumulative probability accuracy and a location equal to zero. * @param alpha the shape parameter. * @param beta the scale parameter. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public WeibullDistributionImpl(double alpha, double beta, double inverseCumAccuracy){ super(); setShapeInternal(alpha); setScaleInternal(beta); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * For this distribution, X, this method returns P(X < x). * @param x the value at which the CDF is evaluated. * @return CDF evaluated at x. */ public double cumulativeProbability(double x) { double ret; if (x <= 0.0) { ret = 0.0; } else { ret = 1.0 - FastMath.exp(-FastMath.pow(x / scale, shape)); } return ret; } /** * Access the shape parameter. * @return the shape parameter. */ public double getShape() { return shape; } /** * Access the scale parameter. * @return the scale parameter. */ public double getScale() { return scale; } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { if (x < 0) { return 0; } final double xscale = x / scale; final double xscalepow = FastMath.pow(xscale, shape - 1); /* * FastMath.pow(x / scale, shape) = * FastMath.pow(xscale, shape) = * FastMath.pow(xscale, shape - 1) * xscale */ final double xscalepowshape = xscalepow * xscale; return (shape / scale) * xscalepow * FastMath.exp(-xscalepowshape); } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns Double.NEGATIVE_INFINITY for p=0 and * Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(double p) { double ret; if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } else if (p == 0) { ret = 0.0; } else if (p == 1) { ret = Double.POSITIVE_INFINITY; } else { ret = scale * FastMath.pow(-FastMath.log(1.0 - p), 1.0 / shape); } return ret; } /** * Modify the shape parameter. * @param alpha the new shape parameter value. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setShape(double alpha) { setShapeInternal(alpha); invalidateParameterDependentMoments(); } /** * Modify the shape parameter. * @param alpha the new shape parameter value. */ private void setShapeInternal(double alpha) { if (alpha <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_SHAPE, alpha); } this.shape = alpha; } /** * Modify the scale parameter. * @param beta the new scale parameter value. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setScale(double beta) { setScaleInternal(beta); invalidateParameterDependentMoments(); } /** * Modify the scale parameter. * @param beta the new scale parameter value. */ private void setScaleInternal(double beta) { if (beta <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_SCALE, beta); } this.scale = beta; } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { return 0.0; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { return Double.MAX_VALUE; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { // use median return FastMath.pow(scale * FastMath.log(2.0), 1.0 / shape); } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0 no matter the parameters. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity * no matter the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Calculates the mean. * * The mean is scale * Gamma(1 + (1 / shape)) * where Gamma(...) is the Gamma-function * * @return the mean * @since 2.2 */ protected double calculateNumericalMean() { final double sh = getShape(); final double sc = getScale(); return sc * FastMath.exp(Gamma.logGamma(1 + (1 / sh))); } /** * Calculates the variance. * * The variance is * scale^2 * Gamma(1 + (2 / shape)) - mean^2 * where Gamma(...) is the Gamma-function * * @return the variance * @since 2.2 */ private double calculateNumericalVariance() { final double sh = getShape(); final double sc = getScale(); final double mn = getNumericalMean(); return (sc * sc) * FastMath.exp(Gamma.logGamma(1 + (2 / sh))) - (mn * mn); } /** * Returns the mean of the distribution. * * @return the mean or Double.NaN if it's not defined * @since 2.2 */ public double getNumericalMean() { if (!numericalMeanIsCalculated) { numericalMean = calculateNumericalMean(); numericalMeanIsCalculated = true; } return numericalMean; } /** * Returns the variance of the distribution. * * @return the variance (possibly Double.POSITIVE_INFINITY as * for certain cases in {@link TDistributionImpl}) or * Double.NaN if it's not defined * @since 2.2 */ public double getNumericalVariance() { if (!numericalVarianceIsCalculated) { numericalVariance = calculateNumericalVariance(); numericalVarianceIsCalculated = true; } return numericalVariance; } /** * Invalidates the cached mean and variance. */ private void invalidateParameterDependentMoments() { numericalMeanIsCalculated = false; numericalVarianceIsCalculated = false; } } ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionIm100644 1750 1750 33110 11532241245 32700 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * The default implementation of {@link HypergeometricDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution implements HypergeometricDistribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -436928820673516179L; /** The number of successes in the population. */ private int numberOfSuccesses; /** The population size. */ private int populationSize; /** The sample size. */ private int sampleSize; /** * Construct a new hypergeometric distribution with the given the population * size, the number of successes in the population, and the sample size. * * @param populationSize the population size. * @param numberOfSuccesses number of successes in the population. * @param sampleSize the sample size. */ public HypergeometricDistributionImpl(int populationSize, int numberOfSuccesses, int sampleSize) { super(); if (numberOfSuccesses > populationSize) { throw MathRuntimeException .createIllegalArgumentException( LocalizedFormats.NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE, numberOfSuccesses, populationSize); } if (sampleSize > populationSize) { throw MathRuntimeException .createIllegalArgumentException( LocalizedFormats.SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE, sampleSize, populationSize); } setPopulationSizeInternal(populationSize); setSampleSizeInternal(sampleSize); setNumberOfSuccessesInternal(numberOfSuccesses); } /** * For this distribution, X, this method returns P(X ≤ x). * * @param x the value at which the PDF is evaluated. * @return PDF for this distribution. */ @Override public double cumulativeProbability(int x) { double ret; int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); if (x < domain[0]) { ret = 0.0; } else if (x >= domain[1]) { ret = 1.0; } else { ret = innerCumulativeProbability(domain[0], x, 1, populationSize, numberOfSuccesses, sampleSize); } return ret; } /** * Return the domain for the given hypergeometric distribution parameters. * * @param n the population size. * @param m number of successes in the population. * @param k the sample size. * @return a two element array containing the lower and upper bounds of the * hypergeometric distribution. */ private int[] getDomain(int n, int m, int k) { return new int[] { getLowerDomain(n, m, k), getUpperDomain(m, k) }; } /** * Access the domain value lower bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. P(X < lower bound) < * p */ @Override protected int getDomainLowerBound(double p) { return getLowerDomain(populationSize, numberOfSuccesses, sampleSize); } /** * Access the domain value upper bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. P(X < upper bound) > * p */ @Override protected int getDomainUpperBound(double p) { return getUpperDomain(sampleSize, numberOfSuccesses); } /** * Return the lowest domain value for the given hypergeometric distribution * parameters. * * @param n the population size. * @param m number of successes in the population. * @param k the sample size. * @return the lowest domain value of the hypergeometric distribution. */ private int getLowerDomain(int n, int m, int k) { return FastMath.max(0, m - (n - k)); } /** * Access the number of successes. * * @return the number of successes. */ public int getNumberOfSuccesses() { return numberOfSuccesses; } /** * Access the population size. * * @return the population size. */ public int getPopulationSize() { return populationSize; } /** * Access the sample size. * * @return the sample size. */ public int getSampleSize() { return sampleSize; } /** * Return the highest domain value for the given hypergeometric distribution * parameters. * * @param m number of successes in the population. * @param k the sample size. * @return the highest domain value of the hypergeometric distribution. */ private int getUpperDomain(int m, int k) { return FastMath.min(k, m); } /** * For this distribution, X, this method returns P(X = x). * * @param x the value at which the PMF is evaluated. * @return PMF for this distribution. */ public double probability(int x) { double ret; int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); if (x < domain[0] || x > domain[1]) { ret = 0.0; } else { double p = (double) sampleSize / (double) populationSize; double q = (double) (populationSize - sampleSize) / (double) populationSize; double p1 = SaddlePointExpansion.logBinomialProbability(x, numberOfSuccesses, p, q); double p2 = SaddlePointExpansion.logBinomialProbability(sampleSize - x, populationSize - numberOfSuccesses, p, q); double p3 = SaddlePointExpansion.logBinomialProbability(sampleSize, populationSize, p, q); ret = FastMath.exp(p1 + p2 - p3); } return ret; } /** * For the distribution, X, defined by the given hypergeometric distribution * parameters, this method returns P(X = x). * * @param n the population size. * @param m number of successes in the population. * @param k the sample size. * @param x the value at which the PMF is evaluated. * @return PMF for the distribution. */ private double probability(int n, int m, int k, int x) { return FastMath.exp(MathUtils.binomialCoefficientLog(m, x) + MathUtils.binomialCoefficientLog(n - m, k - x) - MathUtils.binomialCoefficientLog(n, k)); } /** * Modify the number of successes. * * @param num the new number of successes. * @throws IllegalArgumentException if num is negative. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNumberOfSuccesses(int num) { setNumberOfSuccessesInternal(num); } /** * Modify the number of successes. * * @param num the new number of successes. * @throws IllegalArgumentException if num is negative. */ private void setNumberOfSuccessesInternal(int num) { if (num < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_NUMBER_OF_SUCCESSES, num); } numberOfSuccesses = num; } /** * Modify the population size. * * @param size the new population size. * @throws IllegalArgumentException if size is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setPopulationSize(int size) { setPopulationSizeInternal(size); } /** * Modify the population size. * * @param size the new population size. * @throws IllegalArgumentException if size is not positive. */ private void setPopulationSizeInternal(int size) { if (size <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_POPULATION_SIZE, size); } populationSize = size; } /** * Modify the sample size. * * @param size the new sample size. * @throws IllegalArgumentException if size is negative. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setSampleSize(int size) { setSampleSizeInternal(size); } /** * Modify the sample size. * * @param size the new sample size. * @throws IllegalArgumentException if size is negative. */ private void setSampleSizeInternal(int size) { if (size < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, size); } sampleSize = size; } /** * For this distribution, X, this method returns P(X ≥ x). * * @param x the value at which the CDF is evaluated. * @return upper tail CDF for this distribution. * @since 1.1 */ public double upperCumulativeProbability(int x) { double ret; final int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); if (x < domain[0]) { ret = 1.0; } else if (x > domain[1]) { ret = 0.0; } else { ret = innerCumulativeProbability(domain[1], x, -1, populationSize, numberOfSuccesses, sampleSize); } return ret; } /** * For this distribution, X, this method returns P(x0 ≤ X ≤ x1). This * probability is computed by summing the point probabilities for the values * x0, x0 + 1, x0 + 2, ..., x1, in the order directed by dx. * * @param x0 the inclusive, lower bound * @param x1 the inclusive, upper bound * @param dx the direction of summation. 1 indicates summing from x0 to x1. * 0 indicates summing from x1 to x0. * @param n the population size. * @param m number of successes in the population. * @param k the sample size. * @return P(x0 ≤ X ≤ x1). */ private double innerCumulativeProbability(int x0, int x1, int dx, int n, int m, int k) { double ret = probability(n, m, k, x0); while (x0 != x1) { x0 += dx; ret += probability(n, m, k, x0); } return ret; } /** * Returns the lower bound for the support for the distribution. * * For population size N, * number of successes m, and * sample size n, * the lower bound of the support is * max(0, n + m - N) * * @return lower bound of the support * @since 2.2 */ public int getSupportLowerBound() { return FastMath.max(0, getSampleSize() + getNumberOfSuccesses() - getPopulationSize()); } /** * Returns the upper bound for the support of the distribution. * * For number of successes m and * sample size n, * the upper bound of the support is * min(m, n) * * @return upper bound of the support * @since 2.2 */ public int getSupportUpperBound() { return FastMath.min(getNumberOfSuccesses(), getSampleSize()); } /** * Returns the mean. * * For population size N, * number of successes m, and * sample size n, the mean is * n * m / N * * @return the mean * @since 2.2 */ protected double getNumericalMean() { return (double)(getSampleSize() * getNumberOfSuccesses()) / (double)getPopulationSize(); } /** * Returns the variance. * * For population size N, * number of successes m, and * sample size n, the variance is * [ n * m * (N - n) * (N - m) ] / [ N^2 * (N - 1) ] * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double N = getPopulationSize(); final double m = getNumberOfSuccesses(); final double n = getSampleSize(); return ( n * m * (N - n) * (N - m) ) / ( (N*N * (N - 1)) ); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/PoissonDistribution.java100644 1750 1750 4104 11532241245 31757 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** * Interface representing the Poisson Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface PoissonDistribution extends IntegerDistribution { /** * Get the mean for the distribution. * * @return the mean for the distribution. */ double getMean(); /** * Set the mean for the distribution. * The parameter value must be positive; otherwise an * IllegalArgument is thrown. * * @param p the mean * @throws IllegalArgumentException if p ≤ 0 * @deprecated as of v2.1 */ @Deprecated void setMean(double p); /** * Calculates the Poisson distribution function using a normal approximation. * * @param x the upper bound, inclusive * @return the distribution function value calculated using a normal approximation * @throws MathException if an error occurs computing the normal approximation */ double normalApproximateProbability(int x) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/GammaDistributionImpl.java100644 1750 1750 25456 11532241245 32226 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.FastMath; /** * The default implementation of {@link GammaDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class GammaDistributionImpl extends AbstractContinuousDistribution implements GammaDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = -3239549463135430361L; /** The shape parameter. */ private double alpha; /** The scale parameter. */ private double beta; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a new gamma distribution with the given alpha and beta values. * @param alpha the shape parameter. * @param beta the scale parameter. */ public GammaDistributionImpl(double alpha, double beta) { this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Create a new gamma distribution with the given alpha and beta values. * @param alpha the shape parameter. * @param beta the scale parameter. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public GammaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) { super(); setAlphaInternal(alpha); setBetaInternal(beta); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * For this distribution, X, this method returns P(X < x). * * The implementation of this method is based on: *
                          *
                        • * * Chi-Squared Distribution, equation (9).
                        • *
                        • Casella, G., & Berger, R. (1990). Statistical Inference. * Belmont, CA: Duxbury Press.
                        • *
                        * * @param x the value at which the CDF is evaluated. * @return CDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException{ double ret; if (x <= 0.0) { ret = 0.0; } else { ret = Gamma.regularizedGammaP(alpha, x / beta); } return ret; } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns 0 for p=0 and Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(final double p) throws MathException { if (p == 0) { return 0d; } if (p == 1) { return Double.POSITIVE_INFINITY; } return super.inverseCumulativeProbability(p); } /** * Modify the shape parameter, alpha. * @param alpha the new shape parameter. * @throws IllegalArgumentException if alpha is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setAlpha(double alpha) { setAlphaInternal(alpha); } /** * Modify the shape parameter, alpha. * @param newAlpha the new shape parameter. * @throws IllegalArgumentException if newAlpha is not positive. */ private void setAlphaInternal(double newAlpha) { if (newAlpha <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_ALPHA, newAlpha); } this.alpha = newAlpha; } /** * Access the shape parameter, alpha * @return alpha. */ public double getAlpha() { return alpha; } /** * Modify the scale parameter, beta. * @param newBeta the new scale parameter. * @throws IllegalArgumentException if newBeta is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setBeta(double newBeta) { setBetaInternal(newBeta); } /** * Modify the scale parameter, beta. * @param newBeta the new scale parameter. * @throws IllegalArgumentException if newBeta is not positive. */ private void setBetaInternal(double newBeta) { if (newBeta <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_BETA, newBeta); } this.beta = newBeta; } /** * Access the scale parameter, beta * @return beta. */ public double getBeta() { return beta; } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. */ @Override public double density(double x) { if (x < 0) return 0; return FastMath.pow(x / beta, alpha - 1) / beta * FastMath.exp(-x / beta) / FastMath.exp(Gamma.logGamma(alpha)); } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @deprecated */ @Deprecated public double density(Double x) { return density(x.doubleValue()); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { // TODO: try to improve on this estimate return Double.MIN_VALUE; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { // TODO: try to improve on this estimate // NOTE: gamma is skewed to the left // NOTE: therefore, P(X < μ) > .5 double ret; if (p < .5) { // use mean ret = alpha * beta; } else { // use max value ret = Double.MAX_VALUE; } return ret; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { // TODO: try to improve on this estimate // Gamma is skewed to the left, therefore, P(X < μ) > .5 double ret; if (p < .5) { // use 1/2 mean ret = alpha * beta * .5; } else { // use mean ret = alpha * beta; } return ret; } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the upper bound of the support for the distribution. * * The lower bound of the support is always 0, regardless of the parameters. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity, * regardless of the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean. * * For shape parameter alpha and scale * parameter beta, the mean is * alpha * beta * * @return the mean * @since 2.2 */ public double getNumericalMean() { return getAlpha() * getBeta(); } /** * Returns the variance. * * For shape parameter alpha and scale * parameter beta, the variance is * alpha * beta^2 * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double b = getBeta(); return getAlpha() * b * b; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java100644 1750 1750 5122 11532241245 32071 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Base class for probability distributions. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public abstract class AbstractDistribution implements Distribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -38038050983108802L; /** * Default constructor. */ protected AbstractDistribution() { super(); } /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(x0 ≤ X ≤ x1). *

                        * The default implementation uses the identity

                        *

                        * P(x0 ≤ X ≤ x1) = P(X ≤ x1) - P(X ≤ x0)

                        * * @param x0 the (inclusive) lower bound * @param x1 the (inclusive) upper bound * @return the probability that a random variable with this distribution * will take a value between x0 and x1, * including the endpoints. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if x0 > x1 */ public double cumulativeProbability(double x0, double x1) throws MathException { if (x0 > x1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1); } return cumulativeProbability(x1) - cumulativeProbability(x0); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/package.html100644 1750 1750 1726 11532241245 27352 0ustarlucluc 0 0 Implementations of common discrete and continuous distributions. ././@LongLink100644 0 0 154 11532242443 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistributi100644 1750 1750 21773 11532241245 32735 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomDataImpl; import org.apache.commons.math.util.FastMath; /** * Base class for continuous distributions. Default implementations are * provided for some of the methods that do not vary from distribution to * distribution. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ */ public abstract class AbstractContinuousDistribution extends AbstractDistribution implements ContinuousDistribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -38038050983108802L; /** * RandomData instance used to generate samples from the distribution * @since 2.2 */ protected final RandomDataImpl randomData = new RandomDataImpl(); /** * Solver absolute accuracy for inverse cumulative computation * @since 2.1 */ private double solverAbsoluteAccuracy = BrentSolver.DEFAULT_ABSOLUTE_ACCURACY; /** * Default constructor. */ protected AbstractContinuousDistribution() { super(); } /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. * @throws MathRuntimeException if the specialized class hasn't implemented this function * @since 2.1 */ public double density(double x) throws MathRuntimeException { throw new MathRuntimeException(new UnsupportedOperationException(), LocalizedFormats.NO_DENSITY_FOR_THIS_DISTRIBUTION); } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ public double inverseCumulativeProbability(final double p) throws MathException { if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } // by default, do simple root finding using bracketing and default solver. // subclasses can override if there is a better method. UnivariateRealFunction rootFindingFunction = new UnivariateRealFunction() { public double value(double x) throws FunctionEvaluationException { double ret = Double.NaN; try { ret = cumulativeProbability(x) - p; } catch (MathException ex) { throw new FunctionEvaluationException(x, ex.getSpecificPattern(), ex.getGeneralPattern(), ex.getArguments()); } if (Double.isNaN(ret)) { throw new FunctionEvaluationException(x, LocalizedFormats.CUMULATIVE_PROBABILITY_RETURNED_NAN, x, p); } return ret; } }; // Try to bracket root, test domain endpoints if this fails double lowerBound = getDomainLowerBound(p); double upperBound = getDomainUpperBound(p); double[] bracket = null; try { bracket = UnivariateRealSolverUtils.bracket( rootFindingFunction, getInitialDomain(p), lowerBound, upperBound); } catch (ConvergenceException ex) { /* * Check domain endpoints to see if one gives value that is within * the default solver's defaultAbsoluteAccuracy of 0 (will be the * case if density has bounded support and p is 0 or 1). */ if (FastMath.abs(rootFindingFunction.value(lowerBound)) < getSolverAbsoluteAccuracy()) { return lowerBound; } if (FastMath.abs(rootFindingFunction.value(upperBound)) < getSolverAbsoluteAccuracy()) { return upperBound; } // Failed bracket convergence was not because of corner solution throw new MathException(ex); } // find root double root = UnivariateRealSolverUtils.solve(rootFindingFunction, // override getSolverAbsoluteAccuracy() to use a Brent solver with // absolute accuracy different from BrentSolver default bracket[0],bracket[1], getSolverAbsoluteAccuracy()); return root; } /** * Reseeds the random generator used to generate samples. * * @param seed the new seed * @since 2.2 */ public void reseedRandomGenerator(long seed) { randomData.reSeed(seed); } /** * Generates a random value sampled from this distribution. The default * implementation uses the * inversion method. * * @return random value * @since 2.2 * @throws MathException if an error occurs generating the random value */ public double sample() throws MathException { return randomData.nextInversionDeviate(this); } /** * Generates a random sample from the distribution. The default implementation * generates the sample by calling {@link #sample()} in a loop. * * @param sampleSize number of random values to generate * @since 2.2 * @return an array representing the random sample * @throws MathException if an error occurs generating the sample * @throws IllegalArgumentException if sampleSize is not positive */ public double[] sample(int sampleSize) throws MathException { if (sampleSize <= 0) { MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, sampleSize); } double[] out = new double[sampleSize]; for (int i = 0; i < sampleSize; i++) { out[i] = sample(); } return out; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ protected abstract double getInitialDomain(double p); /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ protected abstract double getDomainLowerBound(double p); /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ protected abstract double getDomainUpperBound(double p); /** * Returns the solver absolute accuracy for inverse cumulative computation. * * @return the maximum absolute error in inverse cumulative probability estimates * @since 2.1 */ protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java100644 1750 1750 23141 11532241245 31374 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Beta; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.FastMath; /** * Default implementation of * {@link org.apache.commons.math.distribution.TDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class TDistributionImpl extends AbstractContinuousDistribution implements TDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = -5852615386664158222L; /** The degrees of freedom*/ private double degreesOfFreedom; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a t distribution using the given degrees of freedom and the * specified inverse cumulative probability absolute accuracy. * * @param degreesOfFreedom the degrees of freedom. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public TDistributionImpl(double degreesOfFreedom, double inverseCumAccuracy) { super(); setDegreesOfFreedomInternal(degreesOfFreedom); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Create a t distribution using the given degrees of freedom. * @param degreesOfFreedom the degrees of freedom. */ public TDistributionImpl(double degreesOfFreedom) { this(degreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Modify the degrees of freedom. * @param degreesOfFreedom the new degrees of freedom. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setDegreesOfFreedom(double degreesOfFreedom) { setDegreesOfFreedomInternal(degreesOfFreedom); } /** * Modify the degrees of freedom. * @param newDegreesOfFreedom the new degrees of freedom. */ private void setDegreesOfFreedomInternal(double newDegreesOfFreedom) { if (newDegreesOfFreedom <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM, newDegreesOfFreedom); } this.degreesOfFreedom = newDegreesOfFreedom; } /** * Access the degrees of freedom. * @return the degrees of freedom. */ public double getDegreesOfFreedom() { return degreesOfFreedom; } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { final double n = degreesOfFreedom; final double nPlus1Over2 = (n + 1) / 2; return FastMath.exp(Gamma.logGamma(nPlus1Over2) - 0.5 * (FastMath.log(FastMath.PI) + FastMath.log(n)) - Gamma.logGamma(n/2) - nPlus1Over2 * FastMath.log(1 + x * x /n)); } /** * For this distribution, X, this method returns P(X < x). * @param x the value at which the CDF is evaluated. * @return CDF evaluated at x. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException{ double ret; if (x == 0.0) { ret = 0.5; } else { double t = Beta.regularizedBeta( degreesOfFreedom / (degreesOfFreedom + (x * x)), 0.5 * degreesOfFreedom, 0.5); if (x < 0.0) { ret = 0.5 * t; } else { ret = 1.0 - 0.5 * t; } } return ret; } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns Double.NEGATIVE_INFINITY for p=0 and * Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(final double p) throws MathException { if (p == 0) { return Double.NEGATIVE_INFINITY; } if (p == 1) { return Double.POSITIVE_INFINITY; } return super.inverseCumulativeProbability(p); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { return -Double.MAX_VALUE; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { return Double.MAX_VALUE; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { return 0.0; } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always negative infinity * no matter the parameters. * * @return lower bound of the support (always Double.NEGATIVE_INFINITY) * @since 2.2 */ public double getSupportLowerBound() { return Double.NEGATIVE_INFINITY; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity * no matter the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean. * * For degrees of freedom parameter df, the mean is *
                          *
                        • if df > 1 then 0
                        • *
                        • else undefined
                        • *
                        * * @return the mean * @since 2.2 */ public double getNumericalMean() { final double df = getDegreesOfFreedom(); if (df > 1) { return 0; } return Double.NaN; } /** * Returns the variance. * * For degrees of freedom parameter df, the variance is *
                          *
                        • if df > 2 then df / (df - 2)
                        • *
                        • if 1 < df <= 2 then positive infinity
                        • *
                        • else undefined
                        • *
                        * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double df = getDegreesOfFreedom(); if (df > 2) { return df / (df - 2); } if (df > 1 && df <= 2) { return Double.POSITIVE_INFINITY; } return Double.NaN; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/CauchyDistribution.java100644 1750 1750 3406 11532241245 31545 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Cauchy Distribution. * *

                        * References: *

                        *

                        * * @since 1.1 * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface CauchyDistribution extends ContinuousDistribution { /** * Access the median. * @return median for this distribution */ double getMedian(); /** * Access the scale parameter. * @return scale parameter for this distribution */ double getScale(); /** * Modify the median. * @param median for this distribution * @deprecated as of v2.1 */ @Deprecated void setMedian(double median); /** * Modify the scale parameter. * @param s scale parameter for this distribution * @deprecated as of v2.1 */ @Deprecated void setScale(double s); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/BinomialDistribution.java100644 1750 1750 3616 11532241245 32066 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Binomial Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface BinomialDistribution extends IntegerDistribution { /** * Access the number of trials for this distribution. * @return the number of trials. */ int getNumberOfTrials(); /** * Access the probability of success for this distribution. * @return the probability of success. */ double getProbabilityOfSuccess(); /** * Change the number of trials for this distribution. * @param trials the new number of trials. * @deprecated as of v2.1 */ @Deprecated void setNumberOfTrials(int trials); /** * Change the probability of success for this distribution. * @param p the new probability of success. * @deprecated as of v2.1 */ @Deprecated void setProbabilityOfSuccess(double p); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/NormalDistribution.java100644 1750 1750 4004 11532241245 31554 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Normal (Gauss) Distribution. * *

                        * References:

                        *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface NormalDistribution extends ContinuousDistribution, HasDensity { /** * Access the mean. * @return mean for this distribution */ double getMean(); /** * Modify the mean. * @param mean for this distribution * @deprecated as of v2.1 */ @Deprecated void setMean(double mean); /** * Access the standard deviation. * @return standard deviation for this distribution */ double getStandardDeviation(); /** * Modify the standard deviation. * @param sd standard deviation for this distribution * @deprecated as of v2.1 */ @Deprecated void setStandardDeviation(double sd); /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. */ double density(Double x); } ././@LongLink100644 0 0 151 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.100644 1750 1750 23220 11532241245 32613 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * The default implementation of {@link ExponentialDistribution}. * * @version $Revision: 1055914 $ $Date: 2011-01-06 16:34:34 +0100 (jeu. 06 janv. 2011) $ */ public class ExponentialDistributionImpl extends AbstractContinuousDistribution implements ExponentialDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = 2401296428283614780L; /** The mean of this distribution. */ private double mean; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a exponential distribution with the given mean. * @param mean mean of this distribution. */ public ExponentialDistributionImpl(double mean) { this(mean, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Create a exponential distribution with the given mean. * @param mean mean of this distribution. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public ExponentialDistributionImpl(double mean, double inverseCumAccuracy) { super(); setMeanInternal(mean); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Modify the mean. * @param mean the new mean. * @throws IllegalArgumentException if mean is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setMean(double mean) { setMeanInternal(mean); } /** * Modify the mean. * @param newMean the new mean. * @throws IllegalArgumentException if newMean is not positive. */ private void setMeanInternal(double newMean) { if (newMean <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_MEAN, newMean); } this.mean = newMean; } /** * Access the mean. * @return the mean. */ public double getMean() { return mean; } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @deprecated - use density(double) */ @Deprecated public double density(Double x) { return density(x.doubleValue()); } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { if (x < 0) { return 0; } return FastMath.exp(-x / mean) / mean; } /** * For this distribution, X, this method returns P(X < x). * * The implementation of this method is based on: * * * @param x the value at which the CDF is evaluated. * @return CDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException{ double ret; if (x <= 0.0) { ret = 0.0; } else { ret = 1.0 - FastMath.exp(-x / mean); } return ret; } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns 0 for p=0 and Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p < 0 or p > 1. */ @Override public double inverseCumulativeProbability(double p) throws MathException { double ret; if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } else if (p == 1.0) { ret = Double.POSITIVE_INFINITY; } else { ret = -mean * FastMath.log(1.0 - p); } return ret; } /** * Generates a random value sampled from this distribution. * *

                        Algorithm Description: Uses the Inversion * Method to generate exponentially distributed random values from * uniform deviates.

                        * * @return random value * @since 2.2 * @throws MathException if an error occurs generating the random value */ @Override public double sample() throws MathException { return randomData.nextExponential(mean); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { return 0; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { // NOTE: exponential is skewed to the left // NOTE: therefore, P(X < μ) > .5 if (p < .5) { // use mean return mean; } else { // use max return Double.MAX_VALUE; } } /** * Access the initial domain value, based on p, used to * bracket a CDF root. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { // TODO: try to improve on this estimate // TODO: what should really happen here is not derive from AbstractContinuousDistribution // TODO: because the inverse cumulative distribution is simple. // Exponential is skewed to the left, therefore, P(X < μ) > .5 if (p < .5) { // use 1/2 mean return mean * .5; } else { // use mean return mean; } } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0, regardless of the mean. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity, * regardless of the mean. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean of the distribution. * * For mean parameter k, the mean is * k * * @return the mean * @since 2.2 */ public double getNumericalMean() { return getMean(); } /** * Returns the variance of the distribution. * * For mean parameter k, the variance is * k^2 * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double m = getMean(); return m * m; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java100644 1750 1750 23046 11532241245 32411 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Default implementation of * {@link org.apache.commons.math.distribution.CauchyDistribution}. * * @since 1.1 * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class CauchyDistributionImpl extends AbstractContinuousDistribution implements CauchyDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = 8589540077390120676L; /** The median of this distribution. */ private double median = 0; /** The scale of this distribution. */ private double scale = 1; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Creates cauchy distribution with the medain equal to zero and scale * equal to one. */ public CauchyDistributionImpl(){ this(0.0, 1.0); } /** * Create a cauchy distribution using the given median and scale. * @param median median for this distribution * @param s scale parameter for this distribution */ public CauchyDistributionImpl(double median, double s){ this(median, s, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Create a cauchy distribution using the given median and scale. * @param median median for this distribution * @param s scale parameter for this distribution * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public CauchyDistributionImpl(double median, double s, double inverseCumAccuracy) { super(); setMedianInternal(median); setScaleInternal(s); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * For this distribution, X, this method returns P(X < x). * @param x the value at which the CDF is evaluated. * @return CDF evaluated at x. */ public double cumulativeProbability(double x) { return 0.5 + (FastMath.atan((x - median) / scale) / FastMath.PI); } /** * Access the median. * @return median for this distribution */ public double getMedian() { return median; } /** * Access the scale parameter. * @return scale parameter for this distribution */ public double getScale() { return scale; } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { final double dev = x - median; return (1 / FastMath.PI) * (scale / (dev * dev + scale * scale)); } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns Double.NEGATIVE_INFINITY for p=0 and * Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(double p) { double ret; if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } else if (p == 0) { ret = Double.NEGATIVE_INFINITY; } else if (p == 1) { ret = Double.POSITIVE_INFINITY; } else { ret = median + scale * FastMath.tan(FastMath.PI * (p - .5)); } return ret; } /** * Modify the median. * @param median for this distribution * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setMedian(double median) { setMedianInternal(median); } /** * Modify the median. * @param newMedian for this distribution */ private void setMedianInternal(double newMedian) { this.median = newMedian; } /** * Modify the scale parameter. * @param s scale parameter for this distribution * @throws IllegalArgumentException if sd is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setScale(double s) { setScaleInternal(s); } /** * Modify the scale parameter. * @param s scale parameter for this distribution * @throws IllegalArgumentException if sd is not positive. */ private void setScaleInternal(double s) { if (s <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_SCALE, s); } scale = s; } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { double ret; if (p < .5) { ret = -Double.MAX_VALUE; } else { ret = median; } return ret; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { double ret; if (p < .5) { ret = median; } else { ret = Double.MAX_VALUE; } return ret; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { double ret; if (p < .5) { ret = median - scale; } else if (p > .5) { ret = median + scale; } else { ret = median; } return ret; } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for this distribution. * The lower bound of the support of the Cauchy distribution is always * negative infinity, regardless of the parameters. * * @return lower bound of the support (always Double.NEGATIVE_INFINITY) * @since 2.2 */ public double getSupportLowerBound() { return Double.NEGATIVE_INFINITY; } /** * Returns the upper bound of the support for this distribution. * The upper bound of the support of the Cauchy distribution is always * positive infinity, regardless of the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean. * * The mean is always undefined, regardless of the parameters. * * @return mean (always Double.NaN) * @since 2.2 */ public double getNumericalMean() { return Double.NaN; } /** * Returns the variance. * * The variance is always undefined, regardless of the parameters. * * @return variance (always Double.NaN) * @since 2.2 */ public double getNumericalVariance() { return Double.NaN; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java100644 1750 1750 25216 11532241245 32426 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Erf; import org.apache.commons.math.util.FastMath; /** * Default implementation of * {@link org.apache.commons.math.distribution.NormalDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class NormalDistributionImpl extends AbstractContinuousDistribution implements NormalDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = 8589540077390120676L; /** &sqrt;(2 π) */ private static final double SQRT2PI = FastMath.sqrt(2 * FastMath.PI); /** The mean of this distribution. */ private double mean = 0; /** The standard deviation of this distribution. */ private double standardDeviation = 1; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a normal distribution using the given mean and standard deviation. * @param mean mean for this distribution * @param sd standard deviation for this distribution */ public NormalDistributionImpl(double mean, double sd){ this(mean, sd, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Create a normal distribution using the given mean, standard deviation and * inverse cumulative distribution accuracy. * * @param mean mean for this distribution * @param sd standard deviation for this distribution * @param inverseCumAccuracy inverse cumulative probability accuracy * @since 2.1 */ public NormalDistributionImpl(double mean, double sd, double inverseCumAccuracy) { super(); setMeanInternal(mean); setStandardDeviationInternal(sd); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Creates normal distribution with the mean equal to zero and standard * deviation equal to one. */ public NormalDistributionImpl(){ this(0.0, 1.0); } /** * Access the mean. * @return mean for this distribution */ public double getMean() { return mean; } /** * Modify the mean. * @param mean for this distribution * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setMean(double mean) { setMeanInternal(mean); } /** * Modify the mean. * @param newMean for this distribution */ private void setMeanInternal(double newMean) { this.mean = newMean; } /** * Access the standard deviation. * @return standard deviation for this distribution */ public double getStandardDeviation() { return standardDeviation; } /** * Modify the standard deviation. * @param sd standard deviation for this distribution * @throws IllegalArgumentException if sd is not positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setStandardDeviation(double sd) { setStandardDeviationInternal(sd); } /** * Modify the standard deviation. * @param sd standard deviation for this distribution * @throws IllegalArgumentException if sd is not positive. */ private void setStandardDeviationInternal(double sd) { if (sd <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_STANDARD_DEVIATION, sd); } standardDeviation = sd; } /** * Return the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @deprecated */ @Deprecated public double density(Double x) { return density(x.doubleValue()); } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { double x0 = x - mean; return FastMath.exp(-x0 * x0 / (2 * standardDeviation * standardDeviation)) / (standardDeviation * SQRT2PI); } /** * For this distribution, X, this method returns P(X < x). * If xis more than 40 standard deviations from the mean, 0 or 1 is returned, * as in these cases the actual value is within Double.MIN_VALUE of 0 or 1. * * @param x the value at which the CDF is evaluated. * @return CDF evaluated at x. * @throws MathException if the algorithm fails to converge */ public double cumulativeProbability(double x) throws MathException { final double dev = x - mean; if (FastMath.abs(dev) > 40 * standardDeviation) { return dev < 0 ? 0.0d : 1.0d; } return 0.5 * (1.0 + Erf.erf(dev / (standardDeviation * FastMath.sqrt(2.0)))); } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns Double.NEGATIVE_INFINITY for p=0 and * Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(final double p) throws MathException { if (p == 0) { return Double.NEGATIVE_INFINITY; } if (p == 1) { return Double.POSITIVE_INFINITY; } return super.inverseCumulativeProbability(p); } /** * Generates a random value sampled from this distribution. * * @return random value * @since 2.2 * @throws MathException if an error occurs generating the random value */ @Override public double sample() throws MathException { return randomData.nextGaussian(mean, standardDeviation); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { double ret; if (p < .5) { ret = -Double.MAX_VALUE; } else { ret = mean; } return ret; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { double ret; if (p < .5) { ret = mean; } else { ret = Double.MAX_VALUE; } return ret; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { double ret; if (p < .5) { ret = mean - standardDeviation; } else if (p > .5) { ret = mean + standardDeviation; } else { ret = mean; } return ret; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always negative infinity * no matter the parameters. * * @return lower bound of the support (always Double.NEGATIVE_INFINITY) * @since 2.2 */ public double getSupportLowerBound() { return Double.NEGATIVE_INFINITY; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity * no matter the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the variance. * * For standard deviation parameter s, * the variance is s^2 * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double s = getStandardDeviation(); return s * s; } } ././@LongLink100644 0 0 151 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.100644 1750 1750 30127 11532241245 32570 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomDataImpl; import org.apache.commons.math.util.FastMath; /** * Base class for integer-valued discrete distributions. Default * implementations are provided for some of the methods that do not vary * from distribution to distribution. * * @version $Revision: 1067494 $ $Date: 2011-02-05 20:49:07 +0100 (sam. 05 févr. 2011) $ */ public abstract class AbstractIntegerDistribution extends AbstractDistribution implements IntegerDistribution, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1146319659338487221L; /** * RandomData instance used to generate samples from the distribution * @since 2.2 */ protected final RandomDataImpl randomData = new RandomDataImpl(); /** * Default constructor. */ protected AbstractIntegerDistribution() { super(); } /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X ≤ x). In other words, * this method represents the (cumulative) distribution function, or * CDF, for this distribution. *

                        * If x does not represent an integer value, the CDF is * evaluated at the greatest integer less than x. * * @param x the value at which the distribution function is evaluated. * @return cumulative probability that a random variable with this * distribution takes a value less than or equal to x * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException { return cumulativeProbability((int) FastMath.floor(x)); } /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(x0 ≤ X ≤ x1). * * @param x0 the (inclusive) lower bound * @param x1 the (inclusive) upper bound * @return the probability that a random variable with this distribution * will take a value between x0 and x1, * including the endpoints. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if x0 > x1 */ @Override public double cumulativeProbability(double x0, double x1) throws MathException { if (x0 > x1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1); } if (FastMath.floor(x0) < x0) { return cumulativeProbability(((int) FastMath.floor(x0)) + 1, (int) FastMath.floor(x1)); // don't want to count mass below x0 } else { // x0 is mathematical integer, so use as is return cumulativeProbability((int) FastMath.floor(x0), (int) FastMath.floor(x1)); } } /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X ≤ x). In other words, * this method represents the probability distribution function, or PDF, * for this distribution. * * @param x the value at which the PDF is evaluated. * @return PDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public abstract double cumulativeProbability(int x) throws MathException; /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(X = x). In other words, this * method represents the probability mass function, or PMF, for the distribution. *

                        * If x does not represent an integer value, 0 is returned. * * @param x the value at which the probability density function is evaluated * @return the value of the probability density function at x */ public double probability(double x) { double fl = FastMath.floor(x); if (fl == x) { return this.probability((int) x); } else { return 0; } } /** * For a random variable X whose values are distributed according * to this distribution, this method returns P(x0 ≤ X ≤ x1). * * @param x0 the inclusive, lower bound * @param x1 the inclusive, upper bound * @return the cumulative probability. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if x0 > x1 */ public double cumulativeProbability(int x0, int x1) throws MathException { if (x0 > x1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1); } return cumulativeProbability(x1) - cumulativeProbability(x0 - 1); } /** * For a random variable X whose values are distributed according * to this distribution, this method returns the largest x, such * that P(X ≤ x) ≤ p. * * @param p the desired probability * @return the largest x such that P(X ≤ x) <= p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p < 0 or p > 1 */ public int inverseCumulativeProbability(final double p) throws MathException{ if (p < 0.0 || p > 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); } // by default, do simple bisection. // subclasses can override if there is a better method. int x0 = getDomainLowerBound(p); int x1 = getDomainUpperBound(p); double pm; while (x0 < x1) { int xm = x0 + (x1 - x0) / 2; pm = checkedCumulativeProbability(xm); if (pm > p) { // update x1 if (xm == x1) { // this can happen with integer division // simply decrement x1 --x1; } else { // update x1 normally x1 = xm; } } else { // update x0 if (xm == x0) { // this can happen with integer division // simply increment x0 ++x0; } else { // update x0 normally x0 = xm; } } } // insure x0 is the correct critical point pm = checkedCumulativeProbability(x0); while (pm > p) { --x0; pm = checkedCumulativeProbability(x0); } return x0; } /** * Reseeds the random generator used to generate samples. * * @param seed the new seed * @since 2.2 */ public void reseedRandomGenerator(long seed) { randomData.reSeed(seed); } /** * Generates a random value sampled from this distribution. The default * implementation uses the * inversion method. * * @return random value * @since 2.2 * @throws MathException if an error occurs generating the random value */ public int sample() throws MathException { return randomData.nextInversionDeviate(this); } /** * Generates a random sample from the distribution. The default implementation * generates the sample by calling {@link #sample()} in a loop. * * @param sampleSize number of random values to generate * @since 2.2 * @return an array representing the random sample * @throws MathException if an error occurs generating the sample * @throws IllegalArgumentException if sampleSize is not positive */ public int[] sample(int sampleSize) throws MathException { if (sampleSize <= 0) { MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, sampleSize); } int[] out = new int[sampleSize]; for (int i = 0; i < sampleSize; i++) { out[i] = sample(); } return out; } /** * Computes the cumulative probability function and checks for NaN values returned. * Throws MathException if the value is NaN. Rethrows any MathException encountered * evaluating the cumulative probability function. Throws * MathException if the cumulative probability function returns NaN. * * @param argument input value * @return cumulative probability * @throws MathException if the cumulative probability is NaN */ private double checkedCumulativeProbability(int argument) throws MathException { double result = Double.NaN; result = cumulativeProbability(argument); if (Double.isNaN(result)) { throw new MathException(LocalizedFormats.DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN, argument); } return result; } /** * Access the domain value lower bound, based on p, used to * bracket a PDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ protected abstract int getDomainLowerBound(double p); /** * Access the domain value upper bound, based on p, used to * bracket a PDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ protected abstract int getDomainUpperBound(double p); /** * Use this method to get information about whether the lower bound * of the support is inclusive or not. For discrete support, * only true here is meaningful. * * @return true (always but at Integer.MIN_VALUE because of the nature of discrete support) * @since 2.2 */ public boolean isSupportLowerBoundInclusive() { return true; } /** * Use this method to get information about whether the upper bound * of the support is inclusive or not. For discrete support, * only true here is meaningful. * * @return true (always but at Integer.MAX_VALUE because of the nature of discrete support) * @since 2.2 */ public boolean isSupportUpperBoundInclusive() { return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ContinuousDistribution.java100644 1750 1750 3572 11532241245 32503 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import org.apache.commons.math.MathException; /** *

                        Base interface for continuous distributions.

                        * *

                        Note: this interface will be extended in version 3.0 to include *
                        public double density(double x)
                        * that is, from version 3.0 forward, continuous distributions must * include implementations of probability density functions. As of version * 2.1, all continuous distribution implementations included in commons-math * provide implementations of this method.

                        * * @version $Revision: 924362 $ $Date: 2010-03-17 17:45:31 +0100 (mer. 17 mars 2010) $ */ public interface ContinuousDistribution extends Distribution { /** * For this distribution, X, this method returns x such that P(X < x) = p. * @param p the cumulative probability. * @return x. * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. */ double inverseCumulativeProbability(double p) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java100644 1750 1750 30706 11532241245 31363 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Beta; import org.apache.commons.math.util.FastMath; /** * Default implementation of * {@link org.apache.commons.math.distribution.FDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class FDistributionImpl extends AbstractContinuousDistribution implements FDistribution, Serializable { /** * Default inverse cumulative probability accuracy * @since 2.1 */ public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; /** Serializable version identifier */ private static final long serialVersionUID = -8516354193418641566L; /** The numerator degrees of freedom*/ private double numeratorDegreesOfFreedom; /** The numerator degrees of freedom*/ private double denominatorDegreesOfFreedom; /** Inverse cumulative probability accuracy */ private final double solverAbsoluteAccuracy; /** * Create a F distribution using the given degrees of freedom. * @param numeratorDegreesOfFreedom the numerator degrees of freedom. * @param denominatorDegreesOfFreedom the denominator degrees of freedom. */ public FDistributionImpl(double numeratorDegreesOfFreedom, double denominatorDegreesOfFreedom) { this(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); } /** * Create a F distribution using the given degrees of freedom and inverse cumulative probability accuracy. * @param numeratorDegreesOfFreedom the numerator degrees of freedom. * @param denominatorDegreesOfFreedom the denominator degrees of freedom. * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) * @since 2.1 */ public FDistributionImpl(double numeratorDegreesOfFreedom, double denominatorDegreesOfFreedom, double inverseCumAccuracy) { super(); setNumeratorDegreesOfFreedomInternal(numeratorDegreesOfFreedom); setDenominatorDegreesOfFreedomInternal(denominatorDegreesOfFreedom); solverAbsoluteAccuracy = inverseCumAccuracy; } /** * Returns the probability density for a particular point. * * @param x The point at which the density should be computed. * @return The pdf at point x. * @since 2.1 */ @Override public double density(double x) { final double nhalf = numeratorDegreesOfFreedom / 2; final double mhalf = denominatorDegreesOfFreedom / 2; final double logx = FastMath.log(x); final double logn = FastMath.log(numeratorDegreesOfFreedom); final double logm = FastMath.log(denominatorDegreesOfFreedom); final double lognxm = FastMath.log(numeratorDegreesOfFreedom * x + denominatorDegreesOfFreedom); return FastMath.exp(nhalf*logn + nhalf*logx - logx + mhalf*logm - nhalf*lognxm - mhalf*lognxm - Beta.logBeta(nhalf, mhalf)); } /** * For this distribution, X, this method returns P(X < x). * * The implementation of this method is based on: * * * @param x the value at which the CDF is evaluated. * @return CDF for this distribution. * @throws MathException if the cumulative probability can not be * computed due to convergence or other numerical errors. */ public double cumulativeProbability(double x) throws MathException { double ret; if (x <= 0.0) { ret = 0.0; } else { double n = numeratorDegreesOfFreedom; double m = denominatorDegreesOfFreedom; ret = Beta.regularizedBeta((n * x) / (m + n * x), 0.5 * n, 0.5 * m); } return ret; } /** * For this distribution, X, this method returns the critical point x, such * that P(X < x) = p. *

                        * Returns 0 for p=0 and Double.POSITIVE_INFINITY for p=1.

                        * * @param p the desired probability * @return x, such that P(X < x) = p * @throws MathException if the inverse cumulative probability can not be * computed due to convergence or other numerical errors. * @throws IllegalArgumentException if p is not a valid * probability. */ @Override public double inverseCumulativeProbability(final double p) throws MathException { if (p == 0) { return 0d; } if (p == 1) { return Double.POSITIVE_INFINITY; } return super.inverseCumulativeProbability(p); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected double getDomainLowerBound(double p) { return 0.0; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected double getDomainUpperBound(double p) { return Double.MAX_VALUE; } /** * Access the initial domain value, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return initial domain value */ @Override protected double getInitialDomain(double p) { double ret = 1.0; double d = denominatorDegreesOfFreedom; if (d > 2.0) { // use mean ret = d / (d - 2.0); } return ret; } /** * Modify the numerator degrees of freedom. * @param degreesOfFreedom the new numerator degrees of freedom. * @throws IllegalArgumentException if degreesOfFreedom is not * positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) { setNumeratorDegreesOfFreedomInternal(degreesOfFreedom); } /** * Modify the numerator degrees of freedom. * @param degreesOfFreedom the new numerator degrees of freedom. * @throws IllegalArgumentException if degreesOfFreedom is not * positive. */ private void setNumeratorDegreesOfFreedomInternal(double degreesOfFreedom) { if (degreesOfFreedom <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM, degreesOfFreedom); } this.numeratorDegreesOfFreedom = degreesOfFreedom; } /** * Access the numerator degrees of freedom. * @return the numerator degrees of freedom. */ public double getNumeratorDegreesOfFreedom() { return numeratorDegreesOfFreedom; } /** * Modify the denominator degrees of freedom. * @param degreesOfFreedom the new denominator degrees of freedom. * @throws IllegalArgumentException if degreesOfFreedom is not * positive. * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) { setDenominatorDegreesOfFreedomInternal(degreesOfFreedom); } /** * Modify the denominator degrees of freedom. * @param degreesOfFreedom the new denominator degrees of freedom. * @throws IllegalArgumentException if degreesOfFreedom is not * positive. */ private void setDenominatorDegreesOfFreedomInternal(double degreesOfFreedom) { if (degreesOfFreedom <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM, degreesOfFreedom); } this.denominatorDegreesOfFreedom = degreesOfFreedom; } /** * Access the denominator degrees of freedom. * @return the denominator degrees of freedom. */ public double getDenominatorDegreesOfFreedom() { return denominatorDegreesOfFreedom; } /** * Return the absolute accuracy setting of the solver used to estimate * inverse cumulative probabilities. * * @return the solver absolute accuracy * @since 2.1 */ @Override protected double getSolverAbsoluteAccuracy() { return solverAbsoluteAccuracy; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0, regardless of the parameters. * * @return lower bound of the support (always 0) * @since 2.2 */ public double getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is always positive infinity, * regardless of the parameters. * * @return upper bound of the support (always Double.POSITIVE_INFINITY) * @since 2.2 */ public double getSupportUpperBound() { return Double.POSITIVE_INFINITY; } /** * Returns the mean of the distribution. * * For denominator degrees of freedom parameter b, * the mean is *
                          *
                        • if b > 2 then b / (b - 2)
                        • *
                        • else undefined *
                        * * @return the mean * @since 2.2 */ public double getNumericalMean() { final double denominatorDF = getDenominatorDegreesOfFreedom(); if (denominatorDF > 2) { return denominatorDF / (denominatorDF - 2); } return Double.NaN; } /** * Returns the variance of the distribution. * * For numerator degrees of freedom parameter a * and denominator degrees of freedom parameter b, * the variance is *
                          *
                        • * if b > 4 then * [ 2 * b^2 * (a + b - 2) ] / [ a * (b - 2)^2 * (b - 4) ] *
                        • *
                        • else undefined *
                        * * @return the variance * @since 2.2 */ public double getNumericalVariance() { final double denominatorDF = getDenominatorDegreesOfFreedom(); if (denominatorDF > 4) { final double numeratorDF = getNumeratorDegreesOfFreedom(); final double denomDFMinusTwo = denominatorDF - 2; return ( 2 * (denominatorDF * denominatorDF) * (numeratorDF + denominatorDF - 2) ) / ( (numeratorDF * (denomDFMinusTwo * denomDFMinusTwo) * (denominatorDF - 4)) ); } return Double.NaN; } } ././@LongLink100644 0 0 150 11532242444 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/HypergeometricDistribution.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/HypergeometricDistribution.j100644 1750 1750 4105 11532241245 32624 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Hypergeometric Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface HypergeometricDistribution extends IntegerDistribution { /** * Access the number of successes. * @return the number of successes. */ int getNumberOfSuccesses(); /** * Access the population size. * @return the population size. */ int getPopulationSize(); /** * Access the sample size. * @return the sample size. */ int getSampleSize(); /** * Modify the number of successes. * @param num the new number of successes. * @deprecated as of v2.1 */ @Deprecated void setNumberOfSuccesses(int num); /** * Modify the population size. * @param size the new population size. * @deprecated as of v2.1 */ @Deprecated void setPopulationSize(int size); /** * Modify the sample size. * @param size the new sample size. * @deprecated as of v2.1 */ @Deprecated void setSampleSize(int size); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java100644 1750 1750 21664 11532241245 32111 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implementation for the {@link ZipfDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class ZipfDistributionImpl extends AbstractIntegerDistribution implements ZipfDistribution, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -140627372283420404L; /** Number of elements. */ private int numberOfElements; /** Exponent parameter of the distribution. */ private double exponent; /** * Create a new Zipf distribution with the given number of elements and * exponent. Both values must be positive; otherwise an * IllegalArgumentException is thrown. * * @param numberOfElements the number of elements * @param exponent the exponent * @exception IllegalArgumentException if n ≤ 0 or s ≤ 0.0 */ public ZipfDistributionImpl(final int numberOfElements, final double exponent) throws IllegalArgumentException { setNumberOfElementsInternal(numberOfElements); setExponentInternal(exponent); } /** * Get the number of elements (e.g. corpus size) for the distribution. * * @return the number of elements */ public int getNumberOfElements() { return numberOfElements; } /** * Set the number of elements (e.g. corpus size) for the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param n the number of elements * @exception IllegalArgumentException if n ≤ 0 * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNumberOfElements(final int n) { setNumberOfElementsInternal(n); } /** * Set the number of elements (e.g. corpus size) for the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param n the number of elements * @exception IllegalArgumentException if n ≤ 0 */ private void setNumberOfElementsInternal(final int n) throws IllegalArgumentException { if (n <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INSUFFICIENT_DIMENSION, n, 0); } this.numberOfElements = n; } /** * Get the exponent characterising the distribution. * * @return the exponent */ public double getExponent() { return exponent; } /** * Set the exponent characterising the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param s the exponent * @exception IllegalArgumentException if s ≤ 0.0 * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setExponent(final double s) { setExponentInternal(s); } /** * Set the exponent characterising the distribution. * The parameter value must be positive; otherwise an * IllegalArgumentException is thrown. * * @param s the exponent * @exception IllegalArgumentException if s ≤ 0.0 */ private void setExponentInternal(final double s) throws IllegalArgumentException { if (s <= 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_EXPONENT, s); } this.exponent = s; } /** * The probability mass function P(X = x) for a Zipf distribution. * * @param x the value at which the probability density function is evaluated. * @return the value of the probability mass function at x */ public double probability(final int x) { if (x <= 0 || x > numberOfElements) { return 0.0; } return (1.0 / FastMath.pow(x, exponent)) / generalizedHarmonic(numberOfElements, exponent); } /** * The probability distribution function P(X <= x) for a Zipf distribution. * * @param x the value at which the PDF is evaluated. * @return Zipf distribution function evaluated at x */ @Override public double cumulativeProbability(final int x) { if (x <= 0) { return 0.0; } else if (x >= numberOfElements) { return 1.0; } return generalizedHarmonic(x, exponent) / generalizedHarmonic(numberOfElements, exponent); } /** * Access the domain value lower bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value lower bound, i.e. * P(X < lower bound) < p */ @Override protected int getDomainLowerBound(final double p) { return 0; } /** * Access the domain value upper bound, based on p, used to * bracket a PDF root. * * @param p the desired probability for the critical value * @return domain value upper bound, i.e. * P(X < upper bound) > p */ @Override protected int getDomainUpperBound(final double p) { return numberOfElements; } /** * Calculates the Nth generalized harmonic number. See * Harmonic * Series. * * @param n the term in the series to calculate (must be ≥ 1) * @param m the exponent; special case m == 1.0 is the harmonic series * @return the nth generalized harmonic number */ private double generalizedHarmonic(final int n, final double m) { double value = 0; for (int k = n; k > 0; --k) { value += 1.0 / FastMath.pow(k, m); } return value; } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 1 no matter the parameters. * * @return lower bound of the support (always 1) * @since 2.2 */ public int getSupportLowerBound() { return 1; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is the number of elements * * @return upper bound of the support * @since 2.2 */ public int getSupportUpperBound() { return getNumberOfElements(); } /** * Returns the mean. * * For number of elements N and exponent s, the mean is * Hs1 / Hs where *
                          *
                        • Hs1 = generalizedHarmonic(N, s - 1)
                        • *
                        • Hs = generalizedHarmonic(N, s)
                        • *
                        * * @return the mean * @since 2.2 */ protected double getNumericalMean() { final int N = getNumberOfElements(); final double s = getExponent(); final double Hs1 = generalizedHarmonic(N, s - 1); final double Hs = generalizedHarmonic(N, s); return Hs1 / Hs; } /** * Returns the variance. * * For number of elements N and exponent s, the mean is * (Hs2 / Hs) - (Hs1^2 / Hs^2) where *
                          *
                        • Hs2 = generalizedHarmonic(N, s - 2)
                        • *
                        • Hs1 = generalizedHarmonic(N, s - 1)
                        • *
                        • Hs = generalizedHarmonic(N, s)
                        • *
                        * * @return the variance * @since 2.2 */ protected double getNumericalVariance() { final int N = getNumberOfElements(); final double s = getExponent(); final double Hs2 = generalizedHarmonic(N, s - 2); final double Hs1 = generalizedHarmonic(N, s - 1); final double Hs = generalizedHarmonic(N, s); return (Hs2 / Hs) - ((Hs1 * Hs1) / (Hs * Hs)); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/WeibullDistribution.java100644 1750 1750 3723 11532241245 31736 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * Weibull Distribution. This interface defines the two parameter form of the * distribution as defined by * * Weibull Distribution, equations (1) and (2). * *

                        * References: *

                        *

                        * * @since 1.1 * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface WeibullDistribution extends ContinuousDistribution { /** * Access the shape parameter. * @return the shape parameter. */ double getShape(); /** * Access the scale parameter. * @return the scale parameter. */ double getScale(); /** * Modify the shape parameter. * @param alpha The new shape parameter value. * @deprecated as of v2.1 */ @Deprecated void setShape(double alpha); /** * Modify the scale parameter. * @param beta The new scale parameter value. * @deprecated as of v2.1 */ @Deprecated void setScale(double beta); } ././@LongLink100644 0 0 145 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ExponentialDistribution.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ExponentialDistribution.java100644 1750 1750 3233 11532241245 32615 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Exponential Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface ExponentialDistribution extends ContinuousDistribution, HasDensity { /** * Modify the mean. * @param mean the new mean. * @deprecated as of v2.1 */ @Deprecated void setMean(double mean); /** * Access the mean. * @return the mean. */ double getMean(); /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. */ double density(Double x); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistribution.java100644 1750 1750 3402 11532241245 32355 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * The Chi-Squared Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface ChiSquaredDistribution extends ContinuousDistribution, HasDensity { /** * Modify the degrees of freedom. * @param degreesOfFreedom the new degrees of freedom. * @deprecated as of v2.1 */ @Deprecated void setDegreesOfFreedom(double degreesOfFreedom); /** * Access the degrees of freedom. * @return the degrees of freedom. */ double getDegreesOfFreedom(); /** * Return the probability density for a particular point. * @param x The point at which the density should be computed. * @return The pdf at point x. */ double density(Double x); } commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/FDistribution.java100644 1750 1750 3706 11532241245 30521 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; /** * F-Distribution. * *

                        * References: *

                        *

                        * * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $ */ public interface FDistribution extends ContinuousDistribution { /** * Modify the numerator degrees of freedom. * @param degreesOfFreedom the new numerator degrees of freedom. * @deprecated as of v2.1 */ @Deprecated void setNumeratorDegreesOfFreedom(double degreesOfFreedom); /** * Access the numerator degrees of freedom. * @return the numerator degrees of freedom. */ double getNumeratorDegreesOfFreedom(); /** * Modify the denominator degrees of freedom. * @param degreesOfFreedom the new denominator degrees of freedom. * @deprecated as of v2.1 */ @Deprecated void setDenominatorDegreesOfFreedom(double degreesOfFreedom); /** * Access the denominator degrees of freedom. * @return the denominator degrees of freedom. */ double getDenominatorDegreesOfFreedom(); } ././@LongLink100644 0 0 145 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java100644 1750 1750 26776 11532241245 32644 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.distribution; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.special.Gamma; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Implementation for the {@link PoissonDistribution}. * * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ */ public class PoissonDistributionImpl extends AbstractIntegerDistribution implements PoissonDistribution, Serializable { /** * Default maximum number of iterations for cumulative probability calculations. * @since 2.1 */ public static final int DEFAULT_MAX_ITERATIONS = 10000000; /** * Default convergence criterion. * @since 2.1 */ public static final double DEFAULT_EPSILON = 1E-12; /** Serializable version identifier */ private static final long serialVersionUID = -3349935121172596109L; /** Distribution used to compute normal approximation. */ private NormalDistribution normal; /** * Holds the Poisson mean for the distribution. */ private double mean; /** * Maximum number of iterations for cumulative probability. * * Cumulative probabilities are estimated using either Lanczos series approximation of * Gamma#regularizedGammaP or continued fraction approximation of Gamma#regularizedGammaQ. */ private int maxIterations = DEFAULT_MAX_ITERATIONS; /** * Convergence criterion for cumulative probability. */ private double epsilon = DEFAULT_EPSILON; /** * Create a new Poisson distribution with the given the mean. The mean value * must be positive; otherwise an IllegalArgument is thrown. * * @param p the Poisson mean * @throws IllegalArgumentException if p ≤ 0 */ public PoissonDistributionImpl(double p) { this(p, new NormalDistributionImpl()); } /** * Create a new Poisson distribution with the given mean, convergence criterion * and maximum number of iterations. * * @param p the Poisson mean * @param epsilon the convergence criteria for cumulative probabilites * @param maxIterations the maximum number of iterations for cumulative probabilites * @since 2.1 */ public PoissonDistributionImpl(double p, double epsilon, int maxIterations) { setMean(p); this.epsilon = epsilon; this.maxIterations = maxIterations; } /** * Create a new Poisson distribution with the given mean and convergence criterion. * * @param p the Poisson mean * @param epsilon the convergence criteria for cumulative probabilites * @since 2.1 */ public PoissonDistributionImpl(double p, double epsilon) { setMean(p); this.epsilon = epsilon; } /** * Create a new Poisson distribution with the given mean and maximum number of iterations. * * @param p the Poisson mean * @param maxIterations the maximum number of iterations for cumulative probabilites * @since 2.1 */ public PoissonDistributionImpl(double p, int maxIterations) { setMean(p); this.maxIterations = maxIterations; } /** * Create a new Poisson distribution with the given the mean. The mean value * must be positive; otherwise an IllegalArgument is thrown. * * @param p the Poisson mean * @param z a normal distribution used to compute normal approximations. * @throws IllegalArgumentException if p ≤ 0 * @since 1.2 * @deprecated as of 2.1 (to avoid possibly inconsistent state, the * "NormalDistribution" will be instantiated internally) */ @Deprecated public PoissonDistributionImpl(double p, NormalDistribution z) { super(); setNormalAndMeanInternal(z, p); } /** * Get the Poisson mean for the distribution. * * @return the Poisson mean for the distribution. */ public double getMean() { return mean; } /** * Set the Poisson mean for the distribution. The mean value must be * positive; otherwise an IllegalArgument is thrown. * * @param p the Poisson mean value * @throws IllegalArgumentException if p ≤ 0 * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setMean(double p) { setNormalAndMeanInternal(normal, p); } /** * Set the Poisson mean for the distribution. The mean value must be * positive; otherwise an IllegalArgument is thrown. * * @param z the new distribution * @param p the Poisson mean value * @throws IllegalArgumentException if p ≤ 0 */ private void setNormalAndMeanInternal(NormalDistribution z, double p) { if (p <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_POISSON_MEAN, p); } mean = p; normal = z; normal.setMean(p); normal.setStandardDeviation(FastMath.sqrt(p)); } /** * The probability mass function P(X = x) for a Poisson distribution. * * @param x the value at which the probability density function is * evaluated. * @return the value of the probability mass function at x */ public double probability(int x) { double ret; if (x < 0 || x == Integer.MAX_VALUE) { ret = 0.0; } else if (x == 0) { ret = FastMath.exp(-mean); } else { ret = FastMath.exp(-SaddlePointExpansion.getStirlingError(x) - SaddlePointExpansion.getDeviancePart(x, mean)) / FastMath.sqrt(MathUtils.TWO_PI * x); } return ret; } /** * The probability distribution function P(X <= x) for a Poisson * distribution. * * @param x the value at which the PDF is evaluated. * @return Poisson distribution function evaluated at x * @throws MathException if the cumulative probability can not be computed * due to convergence or other numerical errors. */ @Override public double cumulativeProbability(int x) throws MathException { if (x < 0) { return 0; } if (x == Integer.MAX_VALUE) { return 1; } return Gamma.regularizedGammaQ((double) x + 1, mean, epsilon, maxIterations); } /** * Calculates the Poisson distribution function using a normal * approximation. The N(mean, sqrt(mean)) distribution is used * to approximate the Poisson distribution. *

                        * The computation uses "half-correction" -- evaluating the normal * distribution function at x + 0.5 *

                        * * @param x the upper bound, inclusive * @return the distribution function value calculated using a normal * approximation * @throws MathException if an error occurs computing the normal * approximation */ public double normalApproximateProbability(int x) throws MathException { // calculate the probability using half-correction return normal.cumulativeProbability(x + 0.5); } /** * Generates a random value sampled from this distribution. * *

                        Algorithm Description: *

                        • For small means, uses simulation of a Poisson process * using Uniform deviates, as described * here. * The Poisson process (and hence value returned) is bounded by 1000 * mean.
                        • < * *
                        • For large means, uses the rejection algorithm described in
                          * Devroye, Luc. (1981).The Computer Generation of Poisson Random Variables * Computing vol. 26 pp. 197-207.

                        * * @return random value * @since 2.2 * @throws MathException if an error occurs generating the random value */ @Override public int sample() throws MathException { return (int) FastMath.min(randomData.nextPoisson(mean), Integer.MAX_VALUE); } /** * Access the domain value lower bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain lower bound */ @Override protected int getDomainLowerBound(double p) { return 0; } /** * Access the domain value upper bound, based on p, used to * bracket a CDF root. This method is used by * {@link #inverseCumulativeProbability(double)} to find critical values. * * @param p the desired probability for the critical value * @return domain upper bound */ @Override protected int getDomainUpperBound(double p) { return Integer.MAX_VALUE; } /** * Modify the normal distribution used to compute normal approximations. The * caller is responsible for insuring the normal distribution has the proper * parameter settings. * * @param value the new distribution * @since 1.2 * @deprecated as of 2.1 (class will become immutable in 3.0) */ @Deprecated public void setNormal(NormalDistribution value) { setNormalAndMeanInternal(value, mean); } /** * Returns the lower bound of the support for the distribution. * * The lower bound of the support is always 0 no matter the mean parameter. * * @return lower bound of the support (always 0) * @since 2.2 */ public int getSupportLowerBound() { return 0; } /** * Returns the upper bound of the support for the distribution. * * The upper bound of the support is positive infinity, * regardless of the parameter values. There is no integer infinity, * so this method returns Integer.MAX_VALUE and * {@link #isSupportUpperBoundInclusive()} returns true. * * @return upper bound of the support (always Integer.MAX_VALUE for positive infinity) * @since 2.2 */ public int getSupportUpperBound() { return Integer.MAX_VALUE; } /** * Returns the variance of the distribution. * * For mean parameter p, the variance is p * * @return the variance * @since 2.2 */ public double getNumericalVariance() { return getMean(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/TrivariateRealFunction.java100644 1750 1750 3026 11532241246 31460 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a trivariate real function. * * @since 2.2 * @version $Revision$ $Date$ */ public interface TrivariateRealFunction { /** * Compute the value for the function. * * @param x x-coordinate for which the function value should be computed. * @param y y-coordinate for which the function value should be computed. * @param z z-coordinate for which the function value should be computed. * @return the value. * @throws FunctionEvaluationException if the function evaluation fails. */ double value(double x, double y, double z) throws FunctionEvaluationException; } ././@LongLink100644 0 0 164 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealIn100644 1750 1750 4106 11532241245 32543 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.MultivariateRealFunction; /** * Interface representing a univariate real interpolating function. * * @since 2.1 * @version $Revision: 924794 $ $Date: 2010-03-18 15:15:50 +0100 (jeu. 18 mars 2010) $ */ public interface MultivariateRealInterpolator { /** * Computes an interpolating function for the data set. * * @param xval the arguments for the interpolation points. * {@code xval[i][0]} is the first component of interpolation point * {@code i}, {@code xval[i][1]} is the second component, and so on * until {@code xval[i][d-1]}, the last component of that interpolation * point (where {@code d} is thus the dimension of the space). * @param yval the values for the interpolation points * @return a function which interpolates the data set * @throws MathException if arguments violate assumptions made by the * interpolation algorithm or some dimension mismatch occurs * @throws IllegalArgumentException if there are no data (xval null or zero length) */ MultivariateRealFunction interpolate(double[][] xval, double[] yval) throws MathException, IllegalArgumentException; } ././@LongLink100644 0 0 204 11532242444 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomialBicubicSplineInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomia100644 1750 1750 12325 11532241245 32663 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.MathException; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; import org.apache.commons.math.optimization.fitting.PolynomialFitter; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; /** * Generates a bicubic interpolation function. * Prior to generating the interpolating function, the input is smoothed using * polynomial fitting. * * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $ * @since 2.2 */ public class SmoothingPolynomialBicubicSplineInterpolator extends BicubicSplineInterpolator { /** Fitter for x. */ private final PolynomialFitter xFitter; /** Fitter for y. */ private final PolynomialFitter yFitter; /** * Default constructor. The degree of the fitting polynomials is set to 3. */ public SmoothingPolynomialBicubicSplineInterpolator() { this(3); } /** * @param degree Degree of the polynomial fitting functions. */ public SmoothingPolynomialBicubicSplineInterpolator(int degree) { this(degree, degree); } /** * @param xDegree Degree of the polynomial fitting functions along the * x-dimension. * @param yDegree Degree of the polynomial fitting functions along the * y-dimension. */ public SmoothingPolynomialBicubicSplineInterpolator(int xDegree, int yDegree) { xFitter = new PolynomialFitter(xDegree, new GaussNewtonOptimizer(false)); yFitter = new PolynomialFitter(yDegree, new GaussNewtonOptimizer(false)); } /** * {@inheritDoc} */ @Override public BicubicSplineInterpolatingFunction interpolate(final double[] xval, final double[] yval, final double[][] fval) throws MathException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); } if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } final int xLen = xval.length; final int yLen = yval.length; for (int i = 0; i < xLen; i++) { if (fval[i].length != yLen) { throw new DimensionMismatchException(fval[i].length, yLen); } } MathUtils.checkOrder(xval); MathUtils.checkOrder(yval); // For each line y[j] (0 <= j < yLen), construct a polynomial, with // respect to variable x, fitting array fval[][j] final PolynomialFunction[] yPolyX = new PolynomialFunction[yLen]; for (int j = 0; j < yLen; j++) { xFitter.clearObservations(); for (int i = 0; i < xLen; i++) { xFitter.addObservedPoint(1, xval[i], fval[i][j]); } yPolyX[j] = xFitter.fit(); } // For every knot (xval[i], yval[j]) of the grid, calculate corrected // values fval_1 final double[][] fval_1 = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final PolynomialFunction f = yPolyX[j]; for (int i = 0; i < xLen; i++) { fval_1[i][j] = f.value(xval[i]); } } // For each line x[i] (0 <= i < xLen), construct a polynomial, with // respect to variable y, fitting array fval_1[i][] final PolynomialFunction[] xPolyY = new PolynomialFunction[xLen]; for (int i = 0; i < xLen; i++) { yFitter.clearObservations(); for (int j = 0; j < yLen; j++) { yFitter.addObservedPoint(1, yval[j], fval_1[i][j]); } xPolyY[i] = yFitter.fit(); } // For every knot (xval[i], yval[j]) of the grid, calculate corrected // values fval_2 final double[][] fval_2 = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final PolynomialFunction f = xPolyY[i]; for (int j = 0; j < yLen; j++) { fval_2[i][j] = f.value(yval[j]); } } return super.interpolate(xval, yval, fval_2); } } ././@LongLink100644 0 0 172 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSp100644 1750 1750 16257 11532241245 32567 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MathException; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.MathUtils.OrderDirection; import org.apache.commons.math.analysis.BivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Generates a bicubic interpolation function. * Before interpolating, smoothing of the input data is performed using * splines. * See Handbook on splines for the user, ISBN 084939404X, * chapter 2. * * @version $Revision: 1059400 $ $Date: 2011-01-15 20:35:27 +0100 (sam. 15 janv. 2011) $ * @since 2.1 * @deprecated This class does not perform smoothing; the name is thus misleading. * Please use {@link org.apache.commons.math.analysis.interpolation.BicubicSplineInterpolator} * instead. If smoothing is desired, a tentative implementation is provided in class * {@link org.apache.commons.math.analysis.interpolation.SmoothingPolynomialBicubicSplineInterpolator}. * This class will be removed in math 3.0. */ @Deprecated public class SmoothingBicubicSplineInterpolator implements BivariateRealGridInterpolator { /** * {@inheritDoc} */ public BivariateRealFunction interpolate(final double[] xval, final double[] yval, final double[][] zval) throws MathException, IllegalArgumentException { if (xval.length == 0 || yval.length == 0 || zval.length == 0) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NO_DATA); } if (xval.length != zval.length) { throw new DimensionMismatchException(xval.length, zval.length); } MathUtils.checkOrder(xval, OrderDirection.INCREASING, true); MathUtils.checkOrder(yval, OrderDirection.INCREASING, true); final int xLen = xval.length; final int yLen = yval.length; // Samples (first index is y-coordinate, i.e. subarray variable is x) // 0 <= i < xval.length // 0 <= j < yval.length // zX[j][i] = f(xval[i], yval[j]) final double[][] zX = new double[yLen][xLen]; for (int i = 0; i < xLen; i++) { if (zval[i].length != yLen) { throw new DimensionMismatchException(zval[i].length, yLen); } for (int j = 0; j < yLen; j++) { zX[j][i] = zval[i][j]; } } final SplineInterpolator spInterpolator = new SplineInterpolator(); // For each line y[j] (0 <= j < yLen), construct a 1D spline with // respect to variable x final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen]; for (int j = 0; j < yLen; j++) { ySplineX[j] = spInterpolator.interpolate(xval, zX[j]); } // For every knot (xval[i], yval[j]) of the grid, calculate corrected // values zY_1 final double[][] zY_1 = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final PolynomialSplineFunction f = ySplineX[j]; for (int i = 0; i < xLen; i++) { zY_1[i][j] = f.value(xval[i]); } } // For each line x[i] (0 <= i < xLen), construct a 1D spline with // respect to variable y generated by array zY_1[i] final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen]; for (int i = 0; i < xLen; i++) { xSplineY[i] = spInterpolator.interpolate(yval, zY_1[i]); } // For every knot (xval[i], yval[j]) of the grid, calculate corrected // values zY_2 final double[][] zY_2 = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final PolynomialSplineFunction f = xSplineY[i]; for (int j = 0; j < yLen; j++) { zY_2[i][j] = f.value(yval[j]); } } // Partial derivatives with respect to x at the grid knots final double[][] dZdX = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final UnivariateRealFunction f = ySplineX[j].derivative(); for (int i = 0; i < xLen; i++) { dZdX[i][j] = f.value(xval[i]); } } // Partial derivatives with respect to y at the grid knots final double[][] dZdY = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final UnivariateRealFunction f = xSplineY[i].derivative(); for (int j = 0; j < yLen; j++) { dZdY[i][j] = f.value(yval[j]); } } // Cross partial derivatives final double[][] dZdXdY = new double[xLen][yLen]; for (int i = 0; i < xLen ; i++) { final int nI = nextIndex(i, xLen); final int pI = previousIndex(i); for (int j = 0; j < yLen; j++) { final int nJ = nextIndex(j, yLen); final int pJ = previousIndex(j); dZdXdY[i][j] = (zY_2[nI][nJ] - zY_2[nI][pJ] - zY_2[pI][nJ] + zY_2[pI][pJ]) / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])); } } // Create the interpolating splines return new BicubicSplineInterpolatingFunction(xval, yval, zY_2, dZdX, dZdY, dZdXdY); } /** * Compute the next index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is larger than or equal to 0}. * * @param i Index * @param max Upper limit of the array * @return the next index */ private int nextIndex(int i, int max) { final int index = i + 1; return index < max ? index : index - 1; } /** * Compute the previous index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is smaller than the size of the array. * * @param i Index * @return the previous index */ private int previousIndex(int i) { final int index = i - 1; return index >= 0 ? index : 0; } } ././@LongLink100644 0 0 165 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridI100644 1750 1750 3651 11532241245 32437 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.BivariateRealFunction; /** * Interface representing a bivariate real interpolating function where the * sample points must be specified on a regular grid. * * @version $Revision: 936391 $ $Date: 2010-04-21 19:00:56 +0200 (mer. 21 avril 2010) $ */ public interface BivariateRealGridInterpolator { /** * Computes an interpolating function for the data set. * * @param xval All the x-coordinates of the interpolation points, sorted * in increasing order. * @param yval All the y-coordinates of the interpolation points, sorted * in increasing order. * @param fval The values of the interpolation points on all the grid knots: * {@code fval[i][j] = f(xval[i], yval[j])}. * @return a function which interpolates the data set. * @throws MathException if arguments violate assumptions made by the * interpolation algorithm. */ BivariateRealFunction interpolate(double[] xval, double[] yval, double[][] fval) throws MathException; } ././@LongLink100644 0 0 151 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/LoessInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/LoessInterpolator.100644 1750 1750 44574 11532241245 32605 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Local Regression Algorithm (also Loess, Lowess) for interpolation of * real univariate functions. *

                        * For reference, see * * William S. Cleveland - Robust Locally Weighted Regression and Smoothing * Scatterplots *

                        * This class implements both the loess method and serves as an interpolation * adapter to it, allowing to build a spline on the obtained loess fit. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class LoessInterpolator implements UnivariateRealInterpolator, Serializable { /** Default value of the bandwidth parameter. */ public static final double DEFAULT_BANDWIDTH = 0.3; /** Default value of the number of robustness iterations. */ public static final int DEFAULT_ROBUSTNESS_ITERS = 2; /** * Default value for accuracy. * @since 2.1 */ public static final double DEFAULT_ACCURACY = 1e-12; /** serializable version identifier. */ private static final long serialVersionUID = 5204927143605193821L; /** * The bandwidth parameter: when computing the loess fit at * a particular point, this fraction of source points closest * to the current point is taken into account for computing * a least-squares regression. *

                        * A sensible value is usually 0.25 to 0.5. */ private final double bandwidth; /** * The number of robustness iterations parameter: this many * robustness iterations are done. *

                        * A sensible value is usually 0 (just the initial fit without any * robustness iterations) to 4. */ private final int robustnessIters; /** * If the median residual at a certain robustness iteration * is less than this amount, no more iterations are done. */ private final double accuracy; /** * Constructs a new {@link LoessInterpolator} * with a bandwidth of {@link #DEFAULT_BANDWIDTH}, * {@link #DEFAULT_ROBUSTNESS_ITERS} robustness iterations * and an accuracy of {#link #DEFAULT_ACCURACY}. * See {@link #LoessInterpolator(double, int, double)} for an explanation of * the parameters. */ public LoessInterpolator() { this.bandwidth = DEFAULT_BANDWIDTH; this.robustnessIters = DEFAULT_ROBUSTNESS_ITERS; this.accuracy = DEFAULT_ACCURACY; } /** * Constructs a new {@link LoessInterpolator} * with given bandwidth and number of robustness iterations. *

                        * Calling this constructor is equivalent to calling {link {@link * #LoessInterpolator(double, int, double) LoessInterpolator(bandwidth, * robustnessIters, LoessInterpolator.DEFAULT_ACCURACY)} *

                        * * @param bandwidth when computing the loess fit at * a particular point, this fraction of source points closest * to the current point is taken into account for computing * a least-squares regression.
                        * A sensible value is usually 0.25 to 0.5, the default value is * {@link #DEFAULT_BANDWIDTH}. * @param robustnessIters This many robustness iterations are done.
                        * A sensible value is usually 0 (just the initial fit without any * robustness iterations) to 4, the default value is * {@link #DEFAULT_ROBUSTNESS_ITERS}. * @throws MathException if bandwidth does not lie in the interval [0,1] * or if robustnessIters is negative. * @see #LoessInterpolator(double, int, double) */ public LoessInterpolator(double bandwidth, int robustnessIters) throws MathException { this(bandwidth, robustnessIters, DEFAULT_ACCURACY); } /** * Constructs a new {@link LoessInterpolator} * with given bandwidth, number of robustness iterations and accuracy. * * @param bandwidth when computing the loess fit at * a particular point, this fraction of source points closest * to the current point is taken into account for computing * a least-squares regression.
                        * A sensible value is usually 0.25 to 0.5, the default value is * {@link #DEFAULT_BANDWIDTH}. * @param robustnessIters This many robustness iterations are done.
                        * A sensible value is usually 0 (just the initial fit without any * robustness iterations) to 4, the default value is * {@link #DEFAULT_ROBUSTNESS_ITERS}. * @param accuracy If the median residual at a certain robustness iteration * is less than this amount, no more iterations are done. * @throws MathException if bandwidth does not lie in the interval [0,1] * or if robustnessIters is negative. * @see #LoessInterpolator(double, int) * @since 2.1 */ public LoessInterpolator(double bandwidth, int robustnessIters, double accuracy) throws MathException { if (bandwidth < 0 || bandwidth > 1) { throw new MathException(LocalizedFormats.BANDWIDTH_OUT_OF_INTERVAL, bandwidth); } this.bandwidth = bandwidth; if (robustnessIters < 0) { throw new MathException(LocalizedFormats.NEGATIVE_ROBUSTNESS_ITERATIONS, robustnessIters); } this.robustnessIters = robustnessIters; this.accuracy = accuracy; } /** * Compute an interpolating function by performing a loess fit * on the data at the original abscissae and then building a cubic spline * with a * {@link org.apache.commons.math.analysis.interpolation.SplineInterpolator} * on the resulting fit. * * @param xval the arguments for the interpolation points * @param yval the values for the interpolation points * @return A cubic spline built upon a loess fit to the data at the original abscissae * @throws MathException if some of the following conditions are false: *
                          *
                        • Arguments and values are of the same size that is greater than zero
                        • *
                        • The arguments are in a strictly increasing order
                        • *
                        • All arguments and values are finite real numbers
                        • *
                        */ public final PolynomialSplineFunction interpolate( final double[] xval, final double[] yval) throws MathException { return new SplineInterpolator().interpolate(xval, smooth(xval, yval)); } /** * Compute a weighted loess fit on the data at the original abscissae. * * @param xval the arguments for the interpolation points * @param yval the values for the interpolation points * @param weights point weights: coefficients by which the robustness weight of a point is multiplied * @return values of the loess fit at corresponding original abscissae * @throws MathException if some of the following conditions are false: *
                          *
                        • Arguments and values are of the same size that is greater than zero
                        • *
                        • The arguments are in a strictly increasing order
                        • *
                        • All arguments and values are finite real numbers
                        • *
                        * @since 2.1 */ public final double[] smooth(final double[] xval, final double[] yval, final double[] weights) throws MathException { if (xval.length != yval.length) { throw new MathException(LocalizedFormats.MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS, xval.length, yval.length); } final int n = xval.length; if (n == 0) { throw new MathException(LocalizedFormats.LOESS_EXPECTS_AT_LEAST_ONE_POINT); } checkAllFiniteReal(xval, LocalizedFormats.NON_REAL_FINITE_ABSCISSA); checkAllFiniteReal(yval, LocalizedFormats.NON_REAL_FINITE_ORDINATE); checkAllFiniteReal(weights, LocalizedFormats.NON_REAL_FINITE_WEIGHT); checkStrictlyIncreasing(xval); if (n == 1) { return new double[]{yval[0]}; } if (n == 2) { return new double[]{yval[0], yval[1]}; } int bandwidthInPoints = (int) (bandwidth * n); if (bandwidthInPoints < 2) { throw new MathException(LocalizedFormats.TOO_SMALL_BANDWIDTH, n, 2.0 / n, bandwidth); } final double[] res = new double[n]; final double[] residuals = new double[n]; final double[] sortedResiduals = new double[n]; final double[] robustnessWeights = new double[n]; // Do an initial fit and 'robustnessIters' robustness iterations. // This is equivalent to doing 'robustnessIters+1' robustness iterations // starting with all robustness weights set to 1. Arrays.fill(robustnessWeights, 1); for (int iter = 0; iter <= robustnessIters; ++iter) { final int[] bandwidthInterval = {0, bandwidthInPoints - 1}; // At each x, compute a local weighted linear regression for (int i = 0; i < n; ++i) { final double x = xval[i]; // Find out the interval of source points on which // a regression is to be made. if (i > 0) { updateBandwidthInterval(xval, weights, i, bandwidthInterval); } final int ileft = bandwidthInterval[0]; final int iright = bandwidthInterval[1]; // Compute the point of the bandwidth interval that is // farthest from x final int edge; if (xval[i] - xval[ileft] > xval[iright] - xval[i]) { edge = ileft; } else { edge = iright; } // Compute a least-squares linear fit weighted by // the product of robustness weights and the tricube // weight function. // See http://en.wikipedia.org/wiki/Linear_regression // (section "Univariate linear case") // and http://en.wikipedia.org/wiki/Weighted_least_squares // (section "Weighted least squares") double sumWeights = 0; double sumX = 0; double sumXSquared = 0; double sumY = 0; double sumXY = 0; double denom = FastMath.abs(1.0 / (xval[edge] - x)); for (int k = ileft; k <= iright; ++k) { final double xk = xval[k]; final double yk = yval[k]; final double dist = (k < i) ? x - xk : xk - x; final double w = tricube(dist * denom) * robustnessWeights[k] * weights[k]; final double xkw = xk * w; sumWeights += w; sumX += xkw; sumXSquared += xk * xkw; sumY += yk * w; sumXY += yk * xkw; } final double meanX = sumX / sumWeights; final double meanY = sumY / sumWeights; final double meanXY = sumXY / sumWeights; final double meanXSquared = sumXSquared / sumWeights; final double beta; if (FastMath.sqrt(FastMath.abs(meanXSquared - meanX * meanX)) < accuracy) { beta = 0; } else { beta = (meanXY - meanX * meanY) / (meanXSquared - meanX * meanX); } final double alpha = meanY - beta * meanX; res[i] = beta * x + alpha; residuals[i] = FastMath.abs(yval[i] - res[i]); } // No need to recompute the robustness weights at the last // iteration, they won't be needed anymore if (iter == robustnessIters) { break; } // Recompute the robustness weights. // Find the median residual. // An arraycopy and a sort are completely tractable here, // because the preceding loop is a lot more expensive System.arraycopy(residuals, 0, sortedResiduals, 0, n); Arrays.sort(sortedResiduals); final double medianResidual = sortedResiduals[n / 2]; if (FastMath.abs(medianResidual) < accuracy) { break; } for (int i = 0; i < n; ++i) { final double arg = residuals[i] / (6 * medianResidual); if (arg >= 1) { robustnessWeights[i] = 0; } else { final double w = 1 - arg * arg; robustnessWeights[i] = w * w; } } } return res; } /** * Compute a loess fit on the data at the original abscissae. * * @param xval the arguments for the interpolation points * @param yval the values for the interpolation points * @return values of the loess fit at corresponding original abscissae * @throws MathException if some of the following conditions are false: *
                          *
                        • Arguments and values are of the same size that is greater than zero
                        • *
                        • The arguments are in a strictly increasing order
                        • *
                        • All arguments and values are finite real numbers
                        • *
                        */ public final double[] smooth(final double[] xval, final double[] yval) throws MathException { if (xval.length != yval.length) { throw new MathException(LocalizedFormats.MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS, xval.length, yval.length); } final double[] unitWeights = new double[xval.length]; Arrays.fill(unitWeights, 1.0); return smooth(xval, yval, unitWeights); } /** * Given an index interval into xval that embraces a certain number of * points closest to xval[i-1], update the interval so that it embraces * the same number of points closest to xval[i], ignoring zero weights. * * @param xval arguments array * @param weights weights array * @param i the index around which the new interval should be computed * @param bandwidthInterval a two-element array {left, right} such that:

                        * (left==0 or xval[i] - xval[left-1] > xval[right] - xval[i]) *

                        and also

                        * (right==xval.length-1 or xval[right+1] - xval[i] > xval[i] - xval[left]). * The array will be updated. */ private static void updateBandwidthInterval(final double[] xval, final double[] weights, final int i, final int[] bandwidthInterval) { final int left = bandwidthInterval[0]; final int right = bandwidthInterval[1]; // The right edge should be adjusted if the next point to the right // is closer to xval[i] than the leftmost point of the current interval int nextRight = nextNonzero(weights, right); if (nextRight < xval.length && xval[nextRight] - xval[i] < xval[i] - xval[left]) { int nextLeft = nextNonzero(weights, bandwidthInterval[0]); bandwidthInterval[0] = nextLeft; bandwidthInterval[1] = nextRight; } } /** * Returns the smallest index j such that j > i && (j==weights.length || weights[j] != 0) * @param weights weights array * @param i the index from which to start search; must be < weights.length * @return the smallest index j such that j > i && (j==weights.length || weights[j] != 0) */ private static int nextNonzero(final double[] weights, final int i) { int j = i + 1; while(j < weights.length && weights[j] == 0) { j++; } return j; } /** * Compute the * tricube * weight function * * @param x the argument * @return (1-|x|^3)^3 */ private static double tricube(final double x) { final double tmp = 1 - x * x * x; return tmp * tmp * tmp; } /** * Check that all elements of an array are finite real numbers. * * @param values the values array * @param pattern pattern of the error message * @throws MathException if one of the values is not a finite real number */ private static void checkAllFiniteReal(final double[] values, final Localizable pattern) throws MathException { for (int i = 0; i < values.length; i++) { final double x = values[i]; if (Double.isInfinite(x) || Double.isNaN(x)) { throw new MathException(pattern, i, x); } } } /** * Check that elements of the abscissae array are in a strictly * increasing order. * * @param xval the abscissae array * @throws MathException if the abscissae array * is not in a strictly increasing order */ private static void checkStrictlyIncreasing(final double[] xval) throws MathException { for (int i = 0; i < xval.length; ++i) { if (i >= 1 && xval[i - 1] >= xval[i]) { throw new MathException(LocalizedFormats.OUT_OF_ORDER_ABSCISSA_ARRAY, i - 1, xval[i - 1], i, xval[i]); } } } } ././@LongLink100644 0 0 172 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInter100644 1750 1750 44432 11532241245 32545 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.BivariateRealFunction; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.util.MathUtils; /** * Function that implements the * * bicubic spline interpolation. * * @version $Revision$ $Date$ * @since 2.1 */ public class BicubicSplineInterpolatingFunction implements BivariateRealFunction { /** * Matrix to compute the spline coefficients from the function values * and function derivatives values */ private static final double[][] AINV = { { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }, { -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0 }, { 2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 }, { 0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0 }, { 0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0 }, { -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0 }, { 0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0 }, { 9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1 }, { -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1 }, { 2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0 }, { 0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0 }, { -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1 }, { 4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 } }; /** Samples x-coordinates */ private final double[] xval; /** Samples y-coordinates */ private final double[] yval; /** Set of cubic splines patching the whole data grid */ private final BicubicSplineFunction[][] splines; /** * Partial derivatives * The value of the first index determines the kind of derivatives: * 0 = first partial derivatives wrt x * 1 = first partial derivatives wrt y * 2 = second partial derivatives wrt x * 3 = second partial derivatives wrt y * 4 = cross partial derivatives */ private BivariateRealFunction[][][] partialDerivatives = null; /** * @param x Sample values of the x-coordinate, in increasing order. * @param y Sample values of the y-coordinate, in increasing order. * @param f Values of the function on every grid point. * @param dFdX Values of the partial derivative of function with respect * to x on every grid point. * @param dFdY Values of the partial derivative of function with respect * to y on every grid point. * @param d2FdXdY Values of the cross partial derivative of function on * every grid point. * @throws DimensionMismatchException if the various arrays do not contain * the expected number of elements. * @throws org.apache.commons.math.exception.NonMonotonousSequenceException * if {@code x} or {@code y} are not strictly increasing. * @throws NoDataException if any of the arrays has zero length. */ public BicubicSplineInterpolatingFunction(double[] x, double[] y, double[][] f, double[][] dFdX, double[][] dFdY, double[][] d2FdXdY) throws DimensionMismatchException { final int xLen = x.length; final int yLen = y.length; if (xLen == 0 || yLen == 0 || f.length == 0 || f[0].length == 0) { throw new NoDataException(); } if (xLen != f.length) { throw new DimensionMismatchException(xLen, f.length); } if (xLen != dFdX.length) { throw new DimensionMismatchException(xLen, dFdX.length); } if (xLen != dFdY.length) { throw new DimensionMismatchException(xLen, dFdY.length); } if (xLen != d2FdXdY.length) { throw new DimensionMismatchException(xLen, d2FdXdY.length); } MathUtils.checkOrder(x); MathUtils.checkOrder(y); xval = x.clone(); yval = y.clone(); final int lastI = xLen - 1; final int lastJ = yLen - 1; splines = new BicubicSplineFunction[lastI][lastJ]; for (int i = 0; i < lastI; i++) { if (f[i].length != yLen) { throw new DimensionMismatchException(f[i].length, yLen); } if (dFdX[i].length != yLen) { throw new DimensionMismatchException(dFdX[i].length, yLen); } if (dFdY[i].length != yLen) { throw new DimensionMismatchException(dFdY[i].length, yLen); } if (d2FdXdY[i].length != yLen) { throw new DimensionMismatchException(d2FdXdY[i].length, yLen); } final int ip1 = i + 1; for (int j = 0; j < lastJ; j++) { final int jp1 = j + 1; final double[] beta = new double[] { f[i][j], f[ip1][j], f[i][jp1], f[ip1][jp1], dFdX[i][j], dFdX[ip1][j], dFdX[i][jp1], dFdX[ip1][jp1], dFdY[i][j], dFdY[ip1][j], dFdY[i][jp1], dFdY[ip1][jp1], d2FdXdY[i][j], d2FdXdY[ip1][j], d2FdXdY[i][jp1], d2FdXdY[ip1][jp1] }; splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta)); } } } /** * {@inheritDoc} */ public double value(double x, double y) { final int i = searchIndex(x, xval); if (i == -1) { throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]); } final int j = searchIndex(y, yval); if (j == -1) { throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]); } final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]); final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]); return splines[i][j].value(xN, yN); } /** * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the first partial derivative with * respect to x. * @since 2.2 */ public double partialDerivativeX(double x, double y) { return partialDerivative(0, x, y); } /** * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the first partial derivative with * respect to y. * @since 2.2 */ public double partialDerivativeY(double x, double y) { return partialDerivative(1, x, y); } /** * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the second partial derivative with * respect to x. * @since 2.2 */ public double partialDerivativeXX(double x, double y) { return partialDerivative(2, x, y); } /** * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the second partial derivative with * respect to y. * @since 2.2 */ public double partialDerivativeYY(double x, double y) { return partialDerivative(3, x, y); } /** * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the second partial cross-derivative. * @since 2.2 */ public double partialDerivativeXY(double x, double y) { return partialDerivative(4, x, y); } /** * @param which First index in {@link #partialDerivatives}. * @param x x-coordinate. * @param y y-coordinate. * @return the value at point (x, y) of the selected partial derivative. * @throws FunctionEvaluationException */ private double partialDerivative(int which, double x, double y) { if (partialDerivatives == null) { computePartialDerivatives(); } final int i = searchIndex(x, xval); if (i == -1) { throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]); } final int j = searchIndex(y, yval); if (j == -1) { throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]); } final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]); final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]); try { return partialDerivatives[which][i][j].value(xN, yN); } catch (FunctionEvaluationException fee) { // this should never happen throw new RuntimeException(fee); } } /** * Compute all partial derivatives. */ private void computePartialDerivatives() { final int lastI = xval.length - 1; final int lastJ = yval.length - 1; partialDerivatives = new BivariateRealFunction[5][lastI][lastJ]; for (int i = 0; i < lastI; i++) { for (int j = 0; j < lastJ; j++) { final BicubicSplineFunction f = splines[i][j]; partialDerivatives[0][i][j] = f.partialDerivativeX(); partialDerivatives[1][i][j] = f.partialDerivativeY(); partialDerivatives[2][i][j] = f.partialDerivativeXX(); partialDerivatives[3][i][j] = f.partialDerivativeYY(); partialDerivatives[4][i][j] = f.partialDerivativeXY(); } } } /** * @param c Coordinate. * @param val Coordinate samples. * @return the index in {@code val} corresponding to the interval * containing {@code c}, or {@code -1} if {@code c} is out of the * range defined by the end values of {@code val}. */ private int searchIndex(double c, double[] val) { if (c < val[0]) { return -1; } final int max = val.length; for (int i = 1; i < max; i++) { if (c <= val[i]) { return i - 1; } } return -1; } /** * Compute the spline coefficients from the list of function values and * function partial derivatives values at the four corners of a grid * element. They must be specified in the following order: *

                          *
                        • f(0,0)
                        • *
                        • f(1,0)
                        • *
                        • f(0,1)
                        • *
                        • f(1,1)
                        • *
                        • fx(0,0)
                        • *
                        • fx(1,0)
                        • *
                        • fx(0,1)
                        • *
                        • fx(1,1)
                        • *
                        • fy(0,0)
                        • *
                        • fy(1,0)
                        • *
                        • fy(0,1)
                        • *
                        • fy(1,1)
                        • *
                        • fxy(0,0)
                        • *
                        • fxy(1,0)
                        • *
                        • fxy(0,1)
                        • *
                        • fxy(1,1)
                        • *
                        * where the subscripts indicate the partial derivative with respect to * the corresponding variable(s). * * @param beta List of function values and function partial derivatives * values. * @return the spline coefficients. */ private double[] computeSplineCoefficients(double[] beta) { final double[] a = new double[16]; for (int i = 0; i < 16; i++) { double result = 0; final double[] row = AINV[i]; for (int j = 0; j < 16; j++) { result += row[j] * beta[j]; } a[i] = result; } return a; } } /** * 2D-spline function. * * @version $Revision$ $Date$ */ class BicubicSplineFunction implements BivariateRealFunction { /** Number of points. */ private static final short N = 4; /** Coefficients */ private final double[][] a; /** First partial derivative along x. */ private BivariateRealFunction partialDerivativeX; /** First partial derivative along y. */ private BivariateRealFunction partialDerivativeY; /** Second partial derivative along x. */ private BivariateRealFunction partialDerivativeXX; /** Second partial derivative along y. */ private BivariateRealFunction partialDerivativeYY; /** Second crossed partial derivative. */ private BivariateRealFunction partialDerivativeXY; /** * Simple constructor. * @param a Spline coefficients */ public BicubicSplineFunction(double[] a) { this.a = new double[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { this.a[i][j] = a[i + N * j]; } } } /** * {@inheritDoc} */ public double value(double x, double y) { if (x < 0 || x > 1) { throw new OutOfRangeException(x, 0, 1); } if (y < 0 || y > 1) { throw new OutOfRangeException(y, 0, 1); } final double x2 = x * x; final double x3 = x2 * x; final double[] pX = {1, x, x2, x3}; final double y2 = y * y; final double y3 = y2 * y; final double[] pY = {1, y, y2, y3}; return apply(pX, pY, a); } /** * Compute the value of the bicubic polynomial. * * @param pX Powers of the x-coordinate. * @param pY Powers of the y-coordinate. * @param coeff Spline coefficients. * @return the interpolated value. */ private double apply(double[] pX, double[] pY, double[][] coeff) { double result = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { result += coeff[i][j] * pX[i] * pY[j]; } } return result; } /** * @return the partial derivative wrt {@code x}. */ public BivariateRealFunction partialDerivativeX() { if (partialDerivativeX == null) { computePartialDerivatives(); } return partialDerivativeX; } /** * @return the partial derivative wrt {@code y}. */ public BivariateRealFunction partialDerivativeY() { if (partialDerivativeY == null) { computePartialDerivatives(); } return partialDerivativeY; } /** * @return the second partial derivative wrt {@code x}. */ public BivariateRealFunction partialDerivativeXX() { if (partialDerivativeXX == null) { computePartialDerivatives(); } return partialDerivativeXX; } /** * @return the second partial derivative wrt {@code y}. */ public BivariateRealFunction partialDerivativeYY() { if (partialDerivativeYY == null) { computePartialDerivatives(); } return partialDerivativeYY; } /** * @return the second partial cross-derivative. */ public BivariateRealFunction partialDerivativeXY() { if (partialDerivativeXY == null) { computePartialDerivatives(); } return partialDerivativeXY; } /** * Compute all partial derivatives functions. */ private void computePartialDerivatives() { final double[][] aX = new double[N][N]; final double[][] aY = new double[N][N]; final double[][] aXX = new double[N][N]; final double[][] aYY = new double[N][N]; final double[][] aXY = new double[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { final double c = a[i][j]; aX[i][j] = i * c; aY[i][j] = j * c; aXX[i][j] = (i - 1) * aX[i][j]; aYY[i][j] = (j - 1) * aY[i][j]; aXY[i][j] = j * aX[i][j]; } } partialDerivativeX = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double[] pX = {0, 1, x, x2}; final double y2 = y * y; final double y3 = y2 * y; final double[] pY = {1, y, y2, y3}; return apply(pX, pY, aX); } }; partialDerivativeY = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double x3 = x2 * x; final double[] pX = {1, x, x2, x3}; final double y2 = y * y; final double[] pY = {0, 1, y, y2}; return apply(pX, pY, aY); } }; partialDerivativeXX = new BivariateRealFunction() { public double value(double x, double y) { final double[] pX = {0, 0, 1, x}; final double y2 = y * y; final double y3 = y2 * y; final double[] pY = {1, y, y2, y3}; return apply(pX, pY, aXX); } }; partialDerivativeYY = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double x3 = x2 * x; final double[] pX = {1, x, x2, x3}; final double[] pY = {0, 0, 1, y}; return apply(pX, pY, aYY); } }; partialDerivativeXY = new BivariateRealFunction() { public double value(double x, double y) { final double x2 = x * x; final double[] pX = {0, 1, x, x2}; final double y2 = y * y; final double[] pY = {0, 1, y, y2}; return apply(pX, pY, aXY); } }; } } ././@LongLink100644 0 0 162 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInte100644 1750 1750 3165 11532241245 32541 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface representing a univariate real interpolating function. * * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (dim. 04 oct. 2009) $ */ public interface UnivariateRealInterpolator { /** * Computes an interpolating function for the data set. * @param xval the arguments for the interpolation points * @param yval the values for the interpolation points * @return a function which interpolates the data set * @throws MathException if arguments violate assumptions made by the * interpolation algorithm */ UnivariateRealFunction interpolate(double xval[], double yval[]) throws MathException; } ././@LongLink100644 0 0 153 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolato100644 1750 1750 4222 11532241245 32620 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm; /** * Implements the * Neville's Algorithm for interpolation of real univariate functions. For * reference, see Introduction to Numerical Analysis, ISBN 038795452X, * chapter 2. *

                        * The actual code of Neville's evalution is in PolynomialFunctionLagrangeForm, * this class provides an easy-to-use interface to it.

                        * * @version $Revision: 799857 $ $Date: 2009-08-01 15:07:12 +0200 (sam. 01 août 2009) $ * @since 1.2 */ public class NevilleInterpolator implements UnivariateRealInterpolator, Serializable { /** serializable version identifier */ static final long serialVersionUID = 3003707660147873733L; /** * Computes an interpolating function for the data set. * * @param x the interpolating points array * @param y the interpolating values array * @return a function which interpolates the data set * @throws MathException if arguments are invalid */ public PolynomialFunctionLagrangeForm interpolate(double x[], double y[]) throws MathException { return new PolynomialFunctionLagrangeForm(x, y); } } ././@LongLink100644 0 0 152 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator100644 1750 1750 6114 11532241245 32620 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.commons.math.util.MathUtils; /** * Implements a linear function for interpolation of real univariate functions. * @version $Revision$ $Date$ * @since 2.2 */ public class LinearInterpolator implements UnivariateRealInterpolator { /** * Computes a linear interpolating function for the data set. * @param x the arguments for the interpolation points * @param y the values for the interpolation points * @return a function which interpolates the data set * @throws DimensionMismatchException if {@code x} and {@code y} * have different sizes. * @throws org.apache.commons.math.exception.NonMonotonousSequenceException * if {@code x} is not sorted in strict increasing order. * @throws NumberIsTooSmallException if the size of {@code x} is smaller * than 2. */ public PolynomialSplineFunction interpolate(double x[], double y[]) { if (x.length != y.length) { throw new DimensionMismatchException(x.length, y.length); } if (x.length < 2) { throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, x.length, 2, true); } // Number of intervals. The number of data points is n + 1. int n = x.length - 1; MathUtils.checkOrder(x); // Slope of the lines between the datapoints. final double m[] = new double[n]; for (int i = 0; i < n; i++) { m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]); } PolynomialFunction polynomials[] = new PolynomialFunction[n]; final double coefficients[] = new double[2]; for (int i = 0; i < n; i++) { coefficients[0] = y[i]; coefficients[1] = m[i]; polynomials[i] = new PolynomialFunction(coefficients); } return new PolynomialSplineFunction(x, polynomials); } } ././@LongLink100644 0 0 173 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatingFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInte100644 1750 1750 61526 11532241245 32572 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.analysis.TrivariateRealFunction; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.util.MathUtils; /** * Function that implements the * * tricubic spline interpolation, as proposed in * * Tricubic interpolation in three dimensions
                        * F. Lekien and J. Marsden
                        * Int. J. Numer. Meth. Engng 2005; 63:455-471 *
                        * * @version $Revision$ $Date$ * @since 2.2 */ public class TricubicSplineInterpolatingFunction implements TrivariateRealFunction { /** * Matrix to compute the spline coefficients from the function values * and function derivatives values */ private static final double[][] AINV = { { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -3,3,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 2,-2,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 9,-9,-9,9,0,0,0,0,6,3,-6,-3,0,0,0,0,6,-6,3,-3,0,0,0,0,0,0,0,0,0,0,0,0,4,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -6,6,6,-6,0,0,0,0,-3,-3,3,3,0,0,0,0,-4,4,-2,2,0,0,0,0,0,0,0,0,0,0,0,0,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -6,6,6,-6,0,0,0,0,-4,-2,4,2,0,0,0,0,-3,3,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 4,-4,-4,4,0,0,0,0,2,2,-2,-2,0,0,0,0,2,-2,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,1,1,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-9,-9,9,0,0,0,0,0,0,0,0,0,0,0,0,6,3,-6,-3,0,0,0,0,6,-6,3,-3,0,0,0,0,4,2,2,1,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,6,-6,0,0,0,0,0,0,0,0,0,0,0,0,-3,-3,3,3,0,0,0,0,-4,4,-2,2,0,0,0,0,-2,-2,-1,-1,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,6,-6,0,0,0,0,0,0,0,0,0,0,0,0,-4,-2,4,2,0,0,0,0,-3,3,-3,3,0,0,0,0,-2,-1,-2,-1,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,-4,-4,4,0,0,0,0,0,0,0,0,0,0,0,0,2,2,-2,-2,0,0,0,0,2,-2,2,-2,0,0,0,0,1,1,1,1,0,0,0,0 }, {-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 9,-9,0,0,-9,9,0,0,6,3,0,0,-6,-3,0,0,0,0,0,0,0,0,0,0,6,-6,0,0,3,-3,0,0,0,0,0,0,0,0,0,0,4,2,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -6,6,0,0,6,-6,0,0,-3,-3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,-4,4,0,0,-2,2,0,0,0,0,0,0,0,0,0,0,-2,-2,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-9,0,0,-9,9,0,0,0,0,0,0,0,0,0,0,6,3,0,0,-6,-3,0,0,0,0,0,0,0,0,0,0,6,-6,0,0,3,-3,0,0,4,2,0,0,2,1,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,0,0,6,-6,0,0,0,0,0,0,0,0,0,0,-3,-3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,-4,4,0,0,-2,2,0,0,-2,-2,0,0,-1,-1,0,0 }, { 9,0,-9,0,-9,0,9,0,0,0,0,0,0,0,0,0,6,0,3,0,-6,0,-3,0,6,0,-6,0,3,0,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,2,0,2,0,1,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,9,0,-9,0,-9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,3,0,-6,0,-3,0,6,0,-6,0,3,0,-3,0,0,0,0,0,0,0,0,0,4,0,2,0,2,0,1,0 }, { -27,27,27,-27,27,-27,-27,27,-18,-9,18,9,18,9,-18,-9,-18,18,-9,9,18,-18,9,-9,-18,18,18,-18,-9,9,9,-9,-12,-6,-6,-3,12,6,6,3,-12,-6,12,6,-6,-3,6,3,-12,12,-6,6,-6,6,-3,3,-8,-4,-4,-2,-4,-2,-2,-1 }, { 18,-18,-18,18,-18,18,18,-18,9,9,-9,-9,-9,-9,9,9,12,-12,6,-6,-12,12,-6,6,12,-12,-12,12,6,-6,-6,6,6,6,3,3,-6,-6,-3,-3,6,6,-6,-6,3,3,-3,-3,8,-8,4,-4,4,-4,2,-2,4,4,2,2,2,2,1,1 }, { -6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,-3,0,-3,0,3,0,3,0,-4,0,4,0,-2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-2,0,-1,0,-1,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,-6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,-3,0,3,0,3,0,-4,0,4,0,-2,0,2,0,0,0,0,0,0,0,0,0,-2,0,-2,0,-1,0,-1,0 }, { 18,-18,-18,18,-18,18,18,-18,12,6,-12,-6,-12,-6,12,6,9,-9,9,-9,-9,9,-9,9,12,-12,-12,12,6,-6,-6,6,6,3,6,3,-6,-3,-6,-3,8,4,-8,-4,4,2,-4,-2,6,-6,6,-6,3,-3,3,-3,4,2,4,2,2,1,2,1 }, { -12,12,12,-12,12,-12,-12,12,-6,-6,6,6,6,6,-6,-6,-6,6,-6,6,6,-6,6,-6,-8,8,8,-8,-4,4,4,-4,-3,-3,-3,-3,3,3,3,3,-4,-4,4,4,-2,-2,2,2,-4,4,-4,4,-2,2,-2,2,-2,-2,-2,-2,-1,-1,-1,-1 }, { 2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { -6,6,0,0,6,-6,0,0,-4,-2,0,0,4,2,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 4,-4,0,0,-4,4,0,0,2,2,0,0,-2,-2,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,0,0,6,-6,0,0,0,0,0,0,0,0,0,0,-4,-2,0,0,4,2,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,-3,3,0,0,-2,-1,0,0,-2,-1,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,-4,0,0,-4,4,0,0,0,0,0,0,0,0,0,0,2,2,0,0,-2,-2,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,2,-2,0,0,1,1,0,0,1,1,0,0 }, { -6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,-4,0,-2,0,4,0,2,0,-3,0,3,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,-2,0,-1,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,-6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,0,-2,0,4,0,2,0,-3,0,3,0,-3,0,3,0,0,0,0,0,0,0,0,0,-2,0,-1,0,-2,0,-1,0 }, { 18,-18,-18,18,-18,18,18,-18,12,6,-12,-6,-12,-6,12,6,12,-12,6,-6,-12,12,-6,6,9,-9,-9,9,9,-9,-9,9,8,4,4,2,-8,-4,-4,-2,6,3,-6,-3,6,3,-6,-3,6,-6,3,-3,6,-6,3,-3,4,2,2,1,4,2,2,1 }, { -12,12,12,-12,12,-12,-12,12,-6,-6,6,6,6,6,-6,-6,-8,8,-4,4,8,-8,4,-4,-6,6,6,-6,-6,6,6,-6,-4,-4,-2,-2,4,4,2,2,-3,-3,3,3,-3,-3,3,3,-4,4,-2,2,-4,4,-2,2,-2,-2,-1,-1,-2,-2,-1,-1 }, { 4,0,-4,0,-4,0,4,0,0,0,0,0,0,0,0,0,2,0,2,0,-2,0,-2,0,2,0,-2,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,4,0,-4,0,-4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,-2,0,-2,0,2,0,-2,0,2,0,-2,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0 }, { -12,12,12,-12,12,-12,-12,12,-8,-4,8,4,8,4,-8,-4,-6,6,-6,6,6,-6,6,-6,-6,6,6,-6,-6,6,6,-6,-4,-2,-4,-2,4,2,4,2,-4,-2,4,2,-4,-2,4,2,-3,3,-3,3,-3,3,-3,3,-2,-1,-2,-1,-2,-1,-2,-1 }, { 8,-8,-8,8,-8,8,8,-8,4,4,-4,-4,-4,-4,4,4,4,-4,4,-4,-4,4,-4,4,4,-4,-4,4,4,-4,-4,4,2,2,2,2,-2,-2,-2,-2,2,2,-2,-2,2,2,-2,-2,2,-2,2,-2,2,-2,2,-2,1,1,1,1,1,1,1,1 } }; /** Samples x-coordinates */ private final double[] xval; /** Samples y-coordinates */ private final double[] yval; /** Samples z-coordinates */ private final double[] zval; /** Set of cubic splines pacthing the whole data grid */ private final TricubicSplineFunction[][][] splines; /** * @param x Sample values of the x-coordinate, in increasing order. * @param y Sample values of the y-coordinate, in increasing order. * @param z Sample values of the y-coordinate, in increasing order. * @param f Values of the function on every grid point. * @param dFdX Values of the partial derivative of function with respect * to x on every grid point. * @param dFdY Values of the partial derivative of function with respect * to y on every grid point. * @param dFdZ Values of the partial derivative of function with respect * to z on every grid point. * @param d2FdXdY Values of the cross partial derivative of function on * every grid point. * @param d2FdXdZ Values of the cross partial derivative of function on * every grid point. * @param d2FdYdZ Values of the cross partial derivative of function on * every grid point. * @param d3FdXdYdZ Values of the cross partial derivative of function on * every grid point. * @throws NoDataException if any of the arrays has zero length. * @throws DimensionMismatchException if the various arrays do not contain * the expected number of elements. * @throws IllegalArgumentException if {@code x}, {@code y} or {@code z} * are not strictly increasing. */ public TricubicSplineInterpolatingFunction(double[] x, double[] y, double[] z, double[][][] f, double[][][] dFdX, double[][][] dFdY, double[][][] dFdZ, double[][][] d2FdXdY, double[][][] d2FdXdZ, double[][][] d2FdYdZ, double[][][] d3FdXdYdZ) { final int xLen = x.length; final int yLen = y.length; final int zLen = z.length; if (xLen == 0 || yLen == 0 || z.length == 0 || f.length == 0 || f[0].length == 0) { throw new NoDataException(); } if (xLen != f.length) { throw new DimensionMismatchException(xLen, f.length); } if (xLen != dFdX.length) { throw new DimensionMismatchException(xLen, dFdX.length); } if (xLen != dFdY.length) { throw new DimensionMismatchException(xLen, dFdY.length); } if (xLen != dFdZ.length) { throw new DimensionMismatchException(xLen, dFdZ.length); } if (xLen != d2FdXdY.length) { throw new DimensionMismatchException(xLen, d2FdXdY.length); } if (xLen != d2FdXdZ.length) { throw new DimensionMismatchException(xLen, d2FdXdZ.length); } if (xLen != d2FdYdZ.length) { throw new DimensionMismatchException(xLen, d2FdYdZ.length); } if (xLen != d3FdXdYdZ.length) { throw new DimensionMismatchException(xLen, d3FdXdYdZ.length); } MathUtils.checkOrder(x); MathUtils.checkOrder(y); MathUtils.checkOrder(z); xval = x.clone(); yval = y.clone(); zval = z.clone(); final int lastI = xLen - 1; final int lastJ = yLen - 1; final int lastK = zLen - 1; splines = new TricubicSplineFunction[lastI][lastJ][lastK]; for (int i = 0; i < lastI; i++) { if (f[i].length != yLen) { throw new DimensionMismatchException(f[i].length, yLen); } if (dFdX[i].length != yLen) { throw new DimensionMismatchException(dFdX[i].length, yLen); } if (dFdY[i].length != yLen) { throw new DimensionMismatchException(dFdY[i].length, yLen); } if (dFdZ[i].length != yLen) { throw new DimensionMismatchException(dFdZ[i].length, yLen); } if (d2FdXdY[i].length != yLen) { throw new DimensionMismatchException(d2FdXdY[i].length, yLen); } if (d2FdXdZ[i].length != yLen) { throw new DimensionMismatchException(d2FdXdZ[i].length, yLen); } if (d2FdYdZ[i].length != yLen) { throw new DimensionMismatchException(d2FdYdZ[i].length, yLen); } if (d3FdXdYdZ[i].length != yLen) { throw new DimensionMismatchException(d3FdXdYdZ[i].length, yLen); } final int ip1 = i + 1; for (int j = 0; j < lastJ; j++) { if (f[i][j].length != zLen) { throw new DimensionMismatchException(f[i][j].length, zLen); } if (dFdX[i][j].length != zLen) { throw new DimensionMismatchException(dFdX[i][j].length, zLen); } if (dFdY[i][j].length != zLen) { throw new DimensionMismatchException(dFdY[i][j].length, zLen); } if (dFdZ[i][j].length != zLen) { throw new DimensionMismatchException(dFdZ[i][j].length, zLen); } if (d2FdXdY[i][j].length != zLen) { throw new DimensionMismatchException(d2FdXdY[i][j].length, zLen); } if (d2FdXdZ[i][j].length != zLen) { throw new DimensionMismatchException(d2FdXdZ[i][j].length, zLen); } if (d2FdYdZ[i][j].length != zLen) { throw new DimensionMismatchException(d2FdYdZ[i][j].length, zLen); } if (d3FdXdYdZ[i][j].length != zLen) { throw new DimensionMismatchException(d3FdXdYdZ[i][j].length, zLen); } final int jp1 = j + 1; for (int k = 0; k < lastK; k++) { final int kp1 = k + 1; final double[] beta = new double[] { f[i][j][k], f[ip1][j][k], f[i][jp1][k], f[ip1][jp1][k], f[i][j][kp1], f[ip1][j][kp1], f[i][jp1][kp1], f[ip1][jp1][kp1], dFdX[i][j][k], dFdX[ip1][j][k], dFdX[i][jp1][k], dFdX[ip1][jp1][k], dFdX[i][j][kp1], dFdX[ip1][j][kp1], dFdX[i][jp1][kp1], dFdX[ip1][jp1][kp1], dFdY[i][j][k], dFdY[ip1][j][k], dFdY[i][jp1][k], dFdY[ip1][jp1][k], dFdY[i][j][kp1], dFdY[ip1][j][kp1], dFdY[i][jp1][kp1], dFdY[ip1][jp1][kp1], dFdZ[i][j][k], dFdZ[ip1][j][k], dFdZ[i][jp1][k], dFdZ[ip1][jp1][k], dFdZ[i][j][kp1], dFdZ[ip1][j][kp1], dFdZ[i][jp1][kp1], dFdZ[ip1][jp1][kp1], d2FdXdY[i][j][k], d2FdXdY[ip1][j][k], d2FdXdY[i][jp1][k], d2FdXdY[ip1][jp1][k], d2FdXdY[i][j][kp1], d2FdXdY[ip1][j][kp1], d2FdXdY[i][jp1][kp1], d2FdXdY[ip1][jp1][kp1], d2FdXdZ[i][j][k], d2FdXdZ[ip1][j][k], d2FdXdZ[i][jp1][k], d2FdXdZ[ip1][jp1][k], d2FdXdZ[i][j][kp1], d2FdXdZ[ip1][j][kp1], d2FdXdZ[i][jp1][kp1], d2FdXdZ[ip1][jp1][kp1], d2FdYdZ[i][j][k], d2FdYdZ[ip1][j][k], d2FdYdZ[i][jp1][k], d2FdYdZ[ip1][jp1][k], d2FdYdZ[i][j][kp1], d2FdYdZ[ip1][j][kp1], d2FdYdZ[i][jp1][kp1], d2FdYdZ[ip1][jp1][kp1], d3FdXdYdZ[i][j][k], d3FdXdYdZ[ip1][j][k], d3FdXdYdZ[i][jp1][k], d3FdXdYdZ[ip1][jp1][k], d3FdXdYdZ[i][j][kp1], d3FdXdYdZ[ip1][j][kp1], d3FdXdYdZ[i][jp1][kp1], d3FdXdYdZ[ip1][jp1][kp1], }; splines[i][j][k] = new TricubicSplineFunction(computeSplineCoefficients(beta)); } } } } /** * {@inheritDoc} */ public double value(double x, double y, double z) { final int i = searchIndex(x, xval); if (i == -1) { throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]); } final int j = searchIndex(y, yval); if (j == -1) { throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]); } final int k = searchIndex(z, zval); if (k == -1) { throw new OutOfRangeException(z, zval[0], zval[zval.length - 1]); } final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]); final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]); final double zN = (z - zval[k]) / (zval[k + 1] - zval[k]); return splines[i][j][k].value(xN, yN, zN); } /** * @param c Coordinate. * @param val Coordinate samples. * @return the index in {@code val} corresponding to the interval * containing {@code c}, or {@code -1} if {@code c} is out of the * range defined by the end values of {@code val}. */ private int searchIndex(double c, double[] val) { if (c < val[0]) { return -1; } final int max = val.length; for (int i = 1; i < max; i++) { if (c <= val[i]) { return i - 1; } } return -1; } /** * Compute the spline coefficients from the list of function values and * function partial derivatives values at the four corners of a grid * element. They must be specified in the following order: *
                          *
                        • f(0,0,0)
                        • *
                        • f(1,0,0)
                        • *
                        • f(0,1,0)
                        • *
                        • f(1,1,0)
                        • *
                        • f(0,0,1)
                        • *
                        • f(1,0,1)
                        • *
                        • f(0,1,1)
                        • *
                        • f(1,1,1)
                        • * *
                        • fx(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fx(1,1,1)
                        • * *
                        • fy(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fy(1,1,1)
                        • * *
                        • fz(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fz(1,1,1)
                        • * *
                        • fxy(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fxy(1,1,1)
                        • * *
                        • fxz(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fxz(1,1,1)
                        • * *
                        • fyz(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fyz(1,1,1)
                        • * *
                        • fxyz(0,0,0)
                        • *
                        • ... (same order as above)
                        • *
                        • fxyz(1,1,1)
                        • *
                        * where the subscripts indicate the partial derivative with respect to * the corresponding variable(s). * * @param beta List of function values and function partial derivatives * values. * @return the spline coefficients. */ private double[] computeSplineCoefficients(double[] beta) { final int sz = 64; final double[] a = new double[sz]; for (int i = 0; i < sz; i++) { double result = 0; final double[] row = AINV[i]; for (int j = 0; j < sz; j++) { result += row[j] * beta[j]; } a[i] = result; } return a; } } /** * 3D-spline function. * * @version $Revision$ $Date$ */ class TricubicSplineFunction implements TrivariateRealFunction { /** Number of points. */ private static final short N = 4; /** Coefficients */ private final double[][][] a = new double[N][N][N]; /** * @param aV List of spline coefficients. */ public TricubicSplineFunction(double[] aV) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < N; k++) { a[i][j][k] = aV[i + N * (j + N * k)]; } } } } /** * @param x x-coordinate of the interpolation point. * @param y y-coordinate of the interpolation point. * @param z z-coordinate of the interpolation point. * @return the interpolated value. */ public double value(double x, double y, double z) { if (x < 0 || x > 1) { throw new OutOfRangeException(x, 0, 1); } if (y < 0 || y > 1) { throw new OutOfRangeException(y, 0, 1); } if (z < 0 || z > 1) { throw new OutOfRangeException(z, 0, 1); } final double x2 = x * x; final double x3 = x2 * x; final double[] pX = { 1, x, x2, x3 }; final double y2 = y * y; final double y3 = y2 * y; final double[] pY = { 1, y, y2, y3 }; final double z2 = z * z; final double z3 = z2 * z; final double[] pZ = { 1, z, z2, z3 }; double result = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < N; k++) { result += a[i][j][k] * pX[i] * pY[j] * pZ[k]; } } } return result; } } ././@LongLink100644 0 0 170 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpo100644 1750 1750 20775 11532241245 32655 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.linear.ArrayRealVector; import org.apache.commons.math.linear.RealVector; import org.apache.commons.math.random.UnitSphereRandomVectorGenerator; import org.apache.commons.math.util.FastMath; /** * Interpolating function that implements the * Microsphere Projection. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class MicrosphereInterpolatingFunction implements MultivariateRealFunction { /** * Space dimension. */ private final int dimension; /** * Internal accounting data for the interpolation algorithm. * Each element of the list corresponds to one surface element of * the microsphere. */ private final List microsphere; /** * Exponent used in the power law that computes the weights of the * sample data. */ private final double brightnessExponent; /** * Sample data. */ private final Map samples; /** * Class for storing the accounting data needed to perform the * microsphere projection. */ private static class MicrosphereSurfaceElement { /** Normal vector characterizing a surface element. */ private final RealVector normal; /** Illumination received from the brightest sample. */ private double brightestIllumination; /** Brightest sample. */ private Map.Entry brightestSample; /** * @param n Normal vector characterizing a surface element * of the microsphere. */ MicrosphereSurfaceElement(double[] n) { normal = new ArrayRealVector(n); } /** * Return the normal vector. * @return the normal vector */ RealVector normal() { return normal; } /** * Reset "illumination" and "sampleIndex". */ void reset() { brightestIllumination = 0; brightestSample = null; } /** * Store the illumination and index of the brightest sample. * @param illuminationFromSample illumination received from sample * @param sample current sample illuminating the element */ void store(final double illuminationFromSample, final Map.Entry sample) { if (illuminationFromSample > this.brightestIllumination) { this.brightestIllumination = illuminationFromSample; this.brightestSample = sample; } } /** * Get the illumination of the element. * @return the illumination. */ double illumination() { return brightestIllumination; } /** * Get the sample illuminating the element the most. * @return the sample. */ Map.Entry sample() { return brightestSample; } } /** * @param xval the arguments for the interpolation points. * {@code xval[i][0]} is the first component of interpolation point * {@code i}, {@code xval[i][1]} is the second component, and so on * until {@code xval[i][d-1]}, the last component of that interpolation * point (where {@code dimension} is thus the dimension of the sampled * space). * @param yval the values for the interpolation points * @param brightnessExponent Brightness dimming factor. * @param microsphereElements Number of surface elements of the * microsphere. * @param rand Unit vector generator for creating the microsphere. * @throws DimensionMismatchException if the lengths of {@code yval} and * {@code xval} (equal to {@code n}, the number of interpolation points) * do not match, or the the arrays {@code xval[0]} ... {@code xval[n]}, * have lengths different from {@code dimension}. * @throws NoDataException if there are no data (xval null or zero length) */ public MicrosphereInterpolatingFunction(double[][] xval, double[] yval, int brightnessExponent, int microsphereElements, UnitSphereRandomVectorGenerator rand) throws DimensionMismatchException, NoDataException { if (xval.length == 0 || xval[0] == null) { throw new NoDataException(); } if (xval.length != yval.length) { throw new DimensionMismatchException(xval.length, yval.length); } dimension = xval[0].length; this.brightnessExponent = brightnessExponent; // Copy data samples. samples = new HashMap(yval.length); for (int i = 0; i < xval.length; ++i) { final double[] xvalI = xval[i]; if ( xvalI.length != dimension) { throw new DimensionMismatchException(xvalI.length, dimension); } samples.put(new ArrayRealVector(xvalI), yval[i]); } microsphere = new ArrayList(microsphereElements); // Generate the microsphere, assuming that a fairly large number of // randomly generated normals will represent a sphere. for (int i = 0; i < microsphereElements; i++) { microsphere.add(new MicrosphereSurfaceElement(rand.nextVector())); } } /** * @param point Interpolation point. * @return the interpolated value. */ public double value(double[] point) { final RealVector p = new ArrayRealVector(point); // Reset. for (MicrosphereSurfaceElement md : microsphere) { md.reset(); } // Compute contribution of each sample points to the microsphere elements illumination for (Map.Entry sd : samples.entrySet()) { // Vector between interpolation point and current sample point. final RealVector diff = sd.getKey().subtract(p); final double diffNorm = diff.getNorm(); if (FastMath.abs(diffNorm) < FastMath.ulp(1d)) { // No need to interpolate, as the interpolation point is // actually (very close to) one of the sampled points. return sd.getValue(); } for (MicrosphereSurfaceElement md : microsphere) { final double w = FastMath.pow(diffNorm, -brightnessExponent); md.store(cosAngle(diff, md.normal()) * w, sd); } } // Interpolation calculation. double value = 0; double totalWeight = 0; for (MicrosphereSurfaceElement md : microsphere) { final double iV = md.illumination(); final Map.Entry sd = md.sample(); if (sd != null) { value += iV * sd.getValue(); totalWeight += iV; } } return value / totalWeight; } /** * Compute the cosine of the angle between 2 vectors. * * @param v Vector. * @param w Vector. * @return cosine of the angle */ private double cosAngle(final RealVector v, final RealVector w) { return v.dotProduct(w) / (v.getNorm() * w.getNorm()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/package.html100644 1750 1750 1725 11532241245 31344 0ustarlucluc 0 0 Univariate real functions interpolation algorithms. ././@LongLink100644 0 0 157 11532242444 10257 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpo100644 1750 1750 10717 11532241245 32650 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.MultivariateRealFunction; import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.random.UnitSphereRandomVectorGenerator; /** * Interpolator that implements the algorithm described in * William Dudziak's * MS thesis. * @since 2.1 * * @version $Revision: 980944 $ $Date: 2010-07-30 22:31:11 +0200 (ven. 30 juil. 2010) $ */ public class MicrosphereInterpolator implements MultivariateRealInterpolator { /** * Default number of surface elements that composes the microsphere. */ public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000; /** * Default exponent used the weights calculation. */ public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2; /** * Number of surface elements of the microsphere. */ private int microsphereElements; /** * Exponent used in the power law that computes the weights of the * sample data. */ private int brightnessExponent; /** Create a microsphere interpolator with default settings. *

                        Calling this constructor is equivalent to call {@link * #MicrosphereInterpolator(int, int) * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS, * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.

                        */ public MicrosphereInterpolator() { this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT); } /** Create a microsphere interpolator. * @param microsphereElements number of surface elements of the microsphere. * @param brightnessExponent exponent used in the power law that computes the * weights of the sample data. * @throws NotPositiveException if {@code microsphereElements <= 0} * or {@code brightnessExponent < 0}. */ public MicrosphereInterpolator(final int microsphereElements, final int brightnessExponent) { setMicropshereElements(microsphereElements); setBrightnessExponent(brightnessExponent); } /** * {@inheritDoc} */ public MultivariateRealFunction interpolate(final double[][] xval, final double[] yval) throws MathException, IllegalArgumentException { final UnitSphereRandomVectorGenerator rand = new UnitSphereRandomVectorGenerator(xval[0].length); return new MicrosphereInterpolatingFunction(xval, yval, brightnessExponent, microsphereElements, rand); } /** * Set the brightness exponent. * @param exponent Exponent for computing the distance dimming * factor. * @throws NotPositiveException if {@code exponent < 0}. */ public void setBrightnessExponent(final int exponent) { if (exponent < 0) { throw new NotPositiveException(exponent); } brightnessExponent = exponent; } /** * Set the number of microsphere elements. * @param elements Number of surface elements of the microsphere. * @throws NotStrictlyPositiveException if {@code elements <= 0}. */ public void setMicropshereElements(final int elements) { if (elements <= 0) { throw new NotStrictlyPositiveException(elements); } microsphereElements = elements; } } ././@LongLink100644 0 0 165 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceI100644 1750 1750 11100 11532241245 32446 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import java.io.Serializable; import org.apache.commons.math.DuplicateSampleAbscissaException; import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm; import org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm; /** * Implements the * Divided Difference Algorithm for interpolation of real univariate * functions. For reference, see Introduction to Numerical Analysis, * ISBN 038795452X, chapter 2. *

                        * The actual code of Neville's evaluation is in PolynomialFunctionLagrangeForm, * this class provides an easy-to-use interface to it.

                        * * @version $Revision: 825919 $ $Date: 2009-10-16 16:51:55 +0200 (ven. 16 oct. 2009) $ * @since 1.2 */ public class DividedDifferenceInterpolator implements UnivariateRealInterpolator, Serializable { /** serializable version identifier */ private static final long serialVersionUID = 107049519551235069L; /** * Computes an interpolating function for the data set. * * @param x the interpolating points array * @param y the interpolating values array * @return a function which interpolates the data set * @throws DuplicateSampleAbscissaException if arguments are invalid */ public PolynomialFunctionNewtonForm interpolate(double x[], double y[]) throws DuplicateSampleAbscissaException { /** * a[] and c[] are defined in the general formula of Newton form: * p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... + * a[n](x-c[0])(x-c[1])...(x-c[n-1]) */ PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y); /** * When used for interpolation, the Newton form formula becomes * p(x) = f[x0] + f[x0,x1](x-x0) + f[x0,x1,x2](x-x0)(x-x1) + ... + * f[x0,x1,...,x[n-1]](x-x0)(x-x1)...(x-x[n-2]) * Therefore, a[k] = f[x0,x1,...,xk], c[k] = x[k]. *

                        * Note x[], y[], a[] have the same length but c[]'s size is one less.

                        */ final double[] c = new double[x.length-1]; System.arraycopy(x, 0, c, 0, c.length); final double[] a = computeDividedDifference(x, y); return new PolynomialFunctionNewtonForm(a, c); } /** * Returns a copy of the divided difference array. *

                        * The divided difference array is defined recursively by

                             * f[x0] = f(x0)
                             * f[x0,x1,...,xk] = (f(x1,...,xk) - f(x0,...,x[k-1])) / (xk - x0)
                             * 

                        *

                        * The computational complexity is O(N^2).

                        * * @param x the interpolating points array * @param y the interpolating values array * @return a fresh copy of the divided difference array * @throws DuplicateSampleAbscissaException if any abscissas coincide */ protected static double[] computeDividedDifference(final double x[], final double y[]) throws DuplicateSampleAbscissaException { PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y); final double[] divdiff = y.clone(); // initialization final int n = x.length; final double[] a = new double [n]; a[0] = divdiff[0]; for (int i = 1; i < n; i++) { for (int j = 0; j < n-i; j++) { final double denominator = x[j+i] - x[j]; if (denominator == 0.0) { // This happens only when two abscissas are identical. throw new DuplicateSampleAbscissaException(x[j], j, j+i); } divdiff[j] = (divdiff[j+1] - divdiff[j]) / denominator; } a[i] = divdiff[0]; } return a; } } ././@LongLink100644 0 0 161 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInter100644 1750 1750 13115 11532241245 32537 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.DimensionMismatchException; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.util.MathUtils; /** * Generates a bicubic interpolating function. * * @version $Revision: 980944 $ $Date: 2010-07-30 22:31:11 +0200 (ven. 30 juil. 2010) $ * @since 2.2 */ public class BicubicSplineInterpolator implements BivariateRealGridInterpolator { /** * {@inheritDoc} */ public BicubicSplineInterpolatingFunction interpolate(final double[] xval, final double[] yval, final double[][] fval) throws MathException, IllegalArgumentException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); } if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } MathUtils.checkOrder(xval); MathUtils.checkOrder(yval); final int xLen = xval.length; final int yLen = yval.length; // Samples (first index is y-coordinate, i.e. subarray variable is x) // 0 <= i < xval.length // 0 <= j < yval.length // fX[j][i] = f(xval[i], yval[j]) final double[][] fX = new double[yLen][xLen]; for (int i = 0; i < xLen; i++) { if (fval[i].length != yLen) { throw new DimensionMismatchException(fval[i].length, yLen); } for (int j = 0; j < yLen; j++) { fX[j][i] = fval[i][j]; } } final SplineInterpolator spInterpolator = new SplineInterpolator(); // For each line y[j] (0 <= j < yLen), construct a 1D spline with // respect to variable x final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen]; for (int j = 0; j < yLen; j++) { ySplineX[j] = spInterpolator.interpolate(xval, fX[j]); } // For each line x[i] (0 <= i < xLen), construct a 1D spline with // respect to variable y generated by array fY_1[i] final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen]; for (int i = 0; i < xLen; i++) { xSplineY[i] = spInterpolator.interpolate(yval, fval[i]); } // Partial derivatives with respect to x at the grid knots final double[][] dFdX = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final UnivariateRealFunction f = ySplineX[j].derivative(); for (int i = 0; i < xLen; i++) { dFdX[i][j] = f.value(xval[i]); } } // Partial derivatives with respect to y at the grid knots final double[][] dFdY = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final UnivariateRealFunction f = xSplineY[i].derivative(); for (int j = 0; j < yLen; j++) { dFdY[i][j] = f.value(yval[j]); } } // Cross partial derivatives final double[][] d2FdXdY = new double[xLen][yLen]; for (int i = 0; i < xLen ; i++) { final int nI = nextIndex(i, xLen); final int pI = previousIndex(i); for (int j = 0; j < yLen; j++) { final int nJ = nextIndex(j, yLen); final int pJ = previousIndex(j); d2FdXdY[i][j] = (fval[nI][nJ] - fval[nI][pJ] - fval[pI][nJ] + fval[pI][pJ]) / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])); } } // Create the interpolating splines return new BicubicSplineInterpolatingFunction(xval, yval, fval, dFdX, dFdY, d2FdXdY); } /** * Compute the next index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is larger than or equal to 0}. * * @param i Index * @param max Upper limit of the array * @return the next index */ private int nextIndex(int i, int max) { final int index = i + 1; return index < max ? index : index - 1; } /** * Compute the previous index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is smaller than the size of the array. * * @param i Index * @return the previous index */ private int previousIndex(int i) { final int index = i - 1; return index >= 0 ? index : 0; } } ././@LongLink100644 0 0 152 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator100644 1750 1750 12545 11532241245 32665 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.commons.math.util.MathUtils; /** * Computes a natural (also known as "free", "unclamped") cubic spline interpolation for the data set. *

                        * The {@link #interpolate(double[], double[])} method returns a {@link PolynomialSplineFunction} * consisting of n cubic polynomials, defined over the subintervals determined by the x values, * x[0] < x[i] ... < x[n]. The x values are referred to as "knot points."

                        *

                        * The value of the PolynomialSplineFunction at a point x that is greater than or equal to the smallest * knot point and strictly less than the largest knot point is computed by finding the subinterval to which * x belongs and computing the value of the corresponding polynomial at x - x[i] where * i is the index of the subinterval. See {@link PolynomialSplineFunction} for more details. *

                        *

                        * The interpolating polynomials satisfy:

                          *
                        1. The value of the PolynomialSplineFunction at each of the input x values equals the * corresponding y value.
                        2. *
                        3. Adjacent polynomials are equal through two derivatives at the knot points (i.e., adjacent polynomials * "match up" at the knot points, as do their first and second derivatives).
                        4. *

                        *

                        * The cubic spline interpolation algorithm implemented is as described in R.L. Burden, J.D. Faires, * Numerical Analysis, 4th Ed., 1989, PWS-Kent, ISBN 0-53491-585-X, pp 126-131. *

                        * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * */ public class SplineInterpolator implements UnivariateRealInterpolator { /** * Computes an interpolating function for the data set. * @param x the arguments for the interpolation points * @param y the values for the interpolation points * @return a function which interpolates the data set * @throws DimensionMismatchException if {@code x} and {@code y} * have different sizes. * @throws org.apache.commons.math.exception.NonMonotonousSequenceException * if {@code x} is not sorted in strict increasing order. * @throws NumberIsTooSmallException if the size of {@code x} is smaller * than 3. */ public PolynomialSplineFunction interpolate(double x[], double y[]) { if (x.length != y.length) { throw new DimensionMismatchException(x.length, y.length); } if (x.length < 3) { throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, x.length, 3, true); } // Number of intervals. The number of data points is n + 1. int n = x.length - 1; MathUtils.checkOrder(x); // Differences between knot points double h[] = new double[n]; for (int i = 0; i < n; i++) { h[i] = x[i + 1] - x[i]; } double mu[] = new double[n]; double z[] = new double[n + 1]; mu[0] = 0d; z[0] = 0d; double g = 0; for (int i = 1; i < n; i++) { g = 2d * (x[i+1] - x[i - 1]) - h[i - 1] * mu[i -1]; mu[i] = h[i] / g; z[i] = (3d * (y[i + 1] * h[i - 1] - y[i] * (x[i + 1] - x[i - 1])+ y[i - 1] * h[i]) / (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g; } // cubic spline coefficients -- b is linear, c quadratic, d is cubic (original y's are constants) double b[] = new double[n]; double c[] = new double[n + 1]; double d[] = new double[n]; z[n] = 0d; c[n] = 0d; for (int j = n -1; j >=0; j--) { c[j] = z[j] - mu[j] * c[j + 1]; b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2d * c[j]) / 3d; d[j] = (c[j + 1] - c[j]) / (3d * h[j]); } PolynomialFunction polynomials[] = new PolynomialFunction[n]; double coefficients[] = new double[4]; for (int i = 0; i < n; i++) { coefficients[0] = y[i]; coefficients[1] = b[i]; coefficients[2] = c[i]; coefficients[3] = d[i]; polynomials[i] = new PolynomialFunction(coefficients); } return new PolynomialSplineFunction(x, polynomials); } } ././@LongLink100644 0 0 162 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInte100644 1750 1750 20044 11532241245 32560 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.MathException; import org.apache.commons.math.util.MathUtils; /** * Generates a tricubic interpolating function. * * @version $Revision$ $Date$ * @since 2.2 */ public class TricubicSplineInterpolator implements TrivariateRealGridInterpolator { /** * {@inheritDoc} */ public TricubicSplineInterpolatingFunction interpolate(final double[] xval, final double[] yval, final double[] zval, final double[][][] fval) throws MathException { if (xval.length == 0 || yval.length == 0 || zval.length == 0 || fval.length == 0) { throw new NoDataException(); } if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } MathUtils.checkOrder(xval); MathUtils.checkOrder(yval); MathUtils.checkOrder(zval); final int xLen = xval.length; final int yLen = yval.length; final int zLen = zval.length; // Samples, re-ordered as (z, x, y) and (y, z, x) tuplets // fvalXY[k][i][j] = f(xval[i], yval[j], zval[k]) // fvalZX[j][k][i] = f(xval[i], yval[j], zval[k]) final double[][][] fvalXY = new double[zLen][xLen][yLen]; final double[][][] fvalZX = new double[yLen][zLen][xLen]; for (int i = 0; i < xLen; i++) { if (fval[i].length != yLen) { throw new DimensionMismatchException(fval[i].length, yLen); } for (int j = 0; j < yLen; j++) { if (fval[i][j].length != zLen) { throw new DimensionMismatchException(fval[i][j].length, zLen); } for (int k = 0; k < zLen; k++) { final double v = fval[i][j][k]; fvalXY[k][i][j] = v; fvalZX[j][k][i] = v; } } } final BicubicSplineInterpolator bsi = new BicubicSplineInterpolator(); // For each line x[i] (0 <= i < xLen), construct a 2D spline in y and z final BicubicSplineInterpolatingFunction[] xSplineYZ = new BicubicSplineInterpolatingFunction[xLen]; for (int i = 0; i < xLen; i++) { xSplineYZ[i] = bsi.interpolate(yval, zval, fval[i]); } // For each line y[j] (0 <= j < yLen), construct a 2D spline in z and x final BicubicSplineInterpolatingFunction[] ySplineZX = new BicubicSplineInterpolatingFunction[yLen]; for (int j = 0; j < yLen; j++) { ySplineZX[j] = bsi.interpolate(zval, xval, fvalZX[j]); } // For each line z[k] (0 <= k < zLen), construct a 2D spline in x and y final BicubicSplineInterpolatingFunction[] zSplineXY = new BicubicSplineInterpolatingFunction[zLen]; for (int k = 0; k < zLen; k++) { zSplineXY[k] = bsi.interpolate(xval, yval, fvalXY[k]); } // Partial derivatives wrt x and wrt y final double[][][] dFdX = new double[xLen][yLen][zLen]; final double[][][] dFdY = new double[xLen][yLen][zLen]; final double[][][] d2FdXdY = new double[xLen][yLen][zLen]; for (int k = 0; k < zLen; k++) { final BicubicSplineInterpolatingFunction f = zSplineXY[k]; for (int i = 0; i < xLen; i++) { final double x = xval[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; dFdX[i][j][k] = f.partialDerivativeX(x, y); dFdY[i][j][k] = f.partialDerivativeY(x, y); d2FdXdY[i][j][k] = f.partialDerivativeXY(x, y); } } } // Partial derivatives wrt y and wrt z final double[][][] dFdZ = new double[xLen][yLen][zLen]; final double[][][] d2FdYdZ = new double[xLen][yLen][zLen]; for (int i = 0; i < xLen; i++) { final BicubicSplineInterpolatingFunction f = xSplineYZ[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; for (int k = 0; k < zLen; k++) { final double z = zval[k]; dFdZ[i][j][k] = f.partialDerivativeY(y, z); d2FdYdZ[i][j][k] = f.partialDerivativeXY(y, z); } } } // Partial derivatives wrt x and wrt z final double[][][] d2FdZdX = new double[xLen][yLen][zLen]; for (int j = 0; j < yLen; j++) { final BicubicSplineInterpolatingFunction f = ySplineZX[j]; for (int k = 0; k < zLen; k++) { final double z = zval[k]; for (int i = 0; i < xLen; i++) { final double x = xval[i]; d2FdZdX[i][j][k] = f.partialDerivativeXY(z, x); } } } // Third partial cross-derivatives final double[][][] d3FdXdYdZ = new double[xLen][yLen][zLen]; for (int i = 0; i < xLen ; i++) { final int nI = nextIndex(i, xLen); final int pI = previousIndex(i); for (int j = 0; j < yLen; j++) { final int nJ = nextIndex(j, yLen); final int pJ = previousIndex(j); for (int k = 0; k < zLen; k++) { final int nK = nextIndex(k, zLen); final int pK = previousIndex(k); // XXX Not sure about this formula d3FdXdYdZ[i][j][k] = (fval[nI][nJ][nK] - fval[nI][pJ][nK] - fval[pI][nJ][nK] + fval[pI][pJ][nK] - fval[nI][nJ][pK] + fval[nI][pJ][pK] + fval[pI][nJ][pK] - fval[pI][pJ][pK]) / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ]) * (zval[nK] - zval[pK])) ; } } } // Create the interpolating splines return new TricubicSplineInterpolatingFunction(xval, yval, zval, fval, dFdX, dFdY, dFdZ, d2FdXdY, d2FdZdX, d2FdYdZ, d3FdXdYdZ); } /** * Compute the next index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is larger than or equal to 0}. * * @param i Index * @param max Upper limit of the array * @return the next index */ private int nextIndex(int i, int max) { final int index = i + 1; return index < max ? index : index - 1; } /** * Compute the previous index of an array, clipping if necessary. * It is assumed (but not checked) that {@code i} is smaller than the size of the array. * * @param i Index * @return the previous index */ private int previousIndex(int i) { final int index = i - 1; return index >= 0 ? index : 0; } } ././@LongLink100644 0 0 166 11532242444 10257 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TrivariateRealGridInterpolator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/interpolation/TrivariateRealGrid100644 1750 1750 4340 11532241245 32526 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.interpolation; import org.apache.commons.math.MathException; import org.apache.commons.math.analysis.TrivariateRealFunction; /** * Interface representing a trivariate real interpolating function where the * sample points must be specified on a regular grid. * * @version $Revision$ $Date$ * @since 2.2 */ public interface TrivariateRealGridInterpolator { /** * Computes an interpolating function for the data set. * * @param xval All the x-coordinates of the interpolation points, sorted * in increasing order. * @param yval All the y-coordinates of the interpolation points, sorted * in increasing order. * @param zval All the z-coordinates of the interpolation points, sorted * in increasing order. * @param fval the values of the interpolation points on all the grid knots: * {@code fval[i][j][k] = f(xval[i], yval[j], zval[k])}. * @return a function that interpolates the data set. * @throws org.apache.commons.math.exception.NoDataException if any of the arrays has zero length. * @throws org.apache.commons.math.exception.DimensionMismatchException if the array lengths are inconsistent. * @throws MathException if arguments violate assumptions made by the * interpolation algorithm. */ TrivariateRealFunction interpolate(double[] xval, double[] yval, double[] zval, double[][][] fval) throws MathException; } ././@LongLink100644 0 0 156 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunc100644 1750 1750 2415 11532241246 32470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Extension of {@link UnivariateRealFunction} representing a differentiable univariate real function. * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ */ public interface DifferentiableUnivariateRealFunction extends UnivariateRealFunction { /** * Returns the derivative of the function * * @return the derivative function */ UnivariateRealFunction derivative(); } ././@LongLink100644 0 0 145 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/UnivariateVectorialFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/UnivariateVectorialFunction.java100644 1750 1750 2632 11532241246 32524 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a univariate vectorial function. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public interface UnivariateVectorialFunction { /** * Compute the value for the function. * @param x the point for which the function value should be computed * @return the value * @throws FunctionEvaluationException if the function evaluation fails */ double[] value(double x) throws FunctionEvaluationException; } ././@LongLink100644 0 0 147 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/MultivariateVectorialFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/MultivariateVectorialFunction.ja100644 1750 1750 3063 11532241246 32533 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a multivariate vectorial function. * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public interface MultivariateVectorialFunction { /** * Compute the value for the function at the given point. * @param point point at which the function must be evaluated * @return function value for the given point * @exception FunctionEvaluationException if the function evaluation fails * @exception IllegalArgumentException if points dimension is wrong */ double[] value(double[] point) throws FunctionEvaluationException, IllegalArgumentException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/MultivariateRealFunction.java100644 1750 1750 3047 11532241246 32017 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a multivariate real function. * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public interface MultivariateRealFunction { /** * Compute the value for the function at the given point. * @param point point at which the function must be evaluated * @return function value for the given point * @exception FunctionEvaluationException if the function evaluation fails * @exception IllegalArgumentException if points dimension is wrong */ double value(double[] point) throws FunctionEvaluationException, IllegalArgumentException; } ././@LongLink100644 0 0 160 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateRealFu100644 1750 1750 4224 11532241246 32506 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Extension of {@link MultivariateRealFunction} representing a differentiable * multivariate real function. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface DifferentiableMultivariateRealFunction extends MultivariateRealFunction { /** * Returns the partial derivative of the function with respect to a point coordinate. *

                        * The partial derivative is defined with respect to point coordinate * xk. If the partial derivatives with respect to all coordinates are * needed, it may be more efficient to use the {@link #gradient()} method which will * compute them all at once. *

                        * @param k index of the coordinate with respect to which the partial * derivative is computed * @return the partial derivative function with respect to kth point coordinate */ MultivariateRealFunction partialDerivative(int k); /** * Returns the gradient function. *

                        If only one partial derivative with respect to a specific coordinate is * needed, it may be more efficient to use the {@link #partialDerivative(int)} method * which will compute only the specified component.

                        * @return the gradient function */ MultivariateVectorialFunction gradient(); } ././@LongLink100644 0 0 161 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFact100644 1750 1750 3721 11532241246 32517 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; /** * A concrete {@link UnivariateRealSolverFactory}. This is the default solver factory * used by commons-math. *

                        * The default solver returned by this factory is a {@link BrentSolver}.

                        * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public class UnivariateRealSolverFactoryImpl extends UnivariateRealSolverFactory { /** * Default constructor. */ public UnivariateRealSolverFactoryImpl() { } /** {@inheritDoc} */ @Override public UnivariateRealSolver newDefaultSolver() { return newBrentSolver(); } /** {@inheritDoc} */ @Override public UnivariateRealSolver newBisectionSolver() { return new BisectionSolver(); } /** {@inheritDoc} */ @Override public UnivariateRealSolver newBrentSolver() { return new BrentSolver(); } /** {@inheritDoc} */ @Override public UnivariateRealSolver newNewtonSolver() { return new NewtonSolver(); } /** {@inheritDoc} */ @Override public UnivariateRealSolver newSecantSolver() { return new SecantSolver(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/LaguerreSolver.java100644 1750 1750 42262 11532241246 31517 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.polynomials.PolynomialFunction; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Laguerre's Method for root finding of real coefficient polynomials. * For reference, see A First Course in Numerical Analysis, * ISBN 048641454X, chapter 8. *

                        * Laguerre's method is global in the sense that it can start with any initial * approximation and be able to solve all roots from that point.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class LaguerreSolver extends UnivariateRealSolverImpl { /** polynomial function to solve. * @deprecated as of 2.0 the function is not stored anymore in the instance */ @Deprecated private final PolynomialFunction p; /** * Construct a solver for the given function. * * @param f function to solve * @throws IllegalArgumentException if function is not polynomial * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public LaguerreSolver(UnivariateRealFunction f) throws IllegalArgumentException { super(f, 100, 1E-6); if (f instanceof PolynomialFunction) { p = (PolynomialFunction) f; } else { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_POLYNOMIAL); } } /** * Construct a solver. * @deprecated in 2.2 (to be removed in 3.0) */ @Deprecated public LaguerreSolver() { super(100, 1E-6); p = null; } /** * Returns a copy of the polynomial function. * * @return a fresh copy of the polynomial function * @deprecated as of 2.0 the function is not stored anymore within the instance. */ @Deprecated public PolynomialFunction getPolynomialFunction() { return new PolynomialFunction(p.getCoefficients()); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max) throws ConvergenceException, FunctionEvaluationException { return solve(p, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { return solve(p, min, max, initial); } /** * Find a real root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f function to solve (must be polynomial) * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, initial); } /** * Find a real root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f function to solve (must be polynomial) * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @return the point at which the function value is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { // check for zeros before verifying bracketing if (f.value(min) == 0.0) { return min; } if (f.value(max) == 0.0) { return max; } if (f.value(initial) == 0.0) { return initial; } verifyBracketing(min, max, f); verifySequence(min, initial, max); if (isBracketing(min, initial, f)) { return solve(f, min, initial); } else { return solve(f, initial, max); } } /** * Find a real root in the given interval. *

                        * Despite the bracketing condition, the root returned by solve(Complex[], * Complex) may not be a real zero inside [min, max]. For example, * p(x) = x^3 + 1, min = -2, max = 2, initial = 0. We can either try * another initial value, or, as we did here, call solveAll() to obtain * all roots and pick up the one that we're looking for.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws ConvergenceException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a real root in the given interval. *

                        * Despite the bracketing condition, the root returned by solve(Complex[], * Complex) may not be a real zero inside [min, max]. For example, * p(x) = x^3 + 1, min = -2, max = 2, initial = 0. We can either try * another initial value, or, as we did here, call solveAll() to obtain * all roots and pick up the one that we're looking for.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the point at which the function value is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws ConvergenceException, FunctionEvaluationException { // check function type if (!(f instanceof PolynomialFunction)) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_POLYNOMIAL); } // check for zeros before verifying bracketing if (f.value(min) == 0.0) { return min; } if (f.value(max) == 0.0) { return max; } verifyBracketing(min, max, f); double coefficients[] = ((PolynomialFunction) f).getCoefficients(); Complex c[] = new Complex[coefficients.length]; for (int i = 0; i < coefficients.length; i++) { c[i] = new Complex(coefficients[i], 0.0); } Complex initial = new Complex(0.5 * (min + max), 0.0); Complex z = solve(c, initial); if (isRootOK(min, max, z)) { setResult(z.getReal(), iterationCount); return result; } // solve all roots and select the one we're seeking Complex[] root = solveAll(c, initial); for (int i = 0; i < root.length; i++) { if (isRootOK(min, max, root[i])) { setResult(root[i].getReal(), iterationCount); return result; } } // should never happen throw new ConvergenceException(); } /** * Returns true iff the given complex root is actually a real zero * in the given interval, within the solver tolerance level. * * @param min the lower bound for the interval * @param max the upper bound for the interval * @param z the complex root * @return true iff z is the sought-after real zero */ protected boolean isRootOK(double min, double max, Complex z) { double tolerance = FastMath.max(relativeAccuracy * z.abs(), absoluteAccuracy); return (isSequence(min, z.getReal(), max)) && (FastMath.abs(z.getImaginary()) <= tolerance || z.abs() <= functionValueAccuracy); } /** * Find all complex roots for the polynomial with the given coefficients, * starting from the given initial value. * * @param coefficients the polynomial coefficients array * @param initial the start value to use * @return the point at which the function value is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2. */ @Deprecated public Complex[] solveAll(double coefficients[], double initial) throws ConvergenceException, FunctionEvaluationException { Complex c[] = new Complex[coefficients.length]; Complex z = new Complex(initial, 0.0); for (int i = 0; i < c.length; i++) { c[i] = new Complex(coefficients[i], 0.0); } return solveAll(c, z); } /** * Find all complex roots for the polynomial with the given coefficients, * starting from the given initial value. * * @param coefficients the polynomial coefficients array * @param initial the start value to use * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2. */ @Deprecated public Complex[] solveAll(Complex coefficients[], Complex initial) throws MaxIterationsExceededException, FunctionEvaluationException { int n = coefficients.length - 1; int iterationCount = 0; if (n < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NON_POSITIVE_POLYNOMIAL_DEGREE, n); } Complex c[] = new Complex[n+1]; // coefficients for deflated polynomial for (int i = 0; i <= n; i++) { c[i] = coefficients[i]; } // solve individual root successively Complex root[] = new Complex[n]; for (int i = 0; i < n; i++) { Complex subarray[] = new Complex[n-i+1]; System.arraycopy(c, 0, subarray, 0, subarray.length); root[i] = solve(subarray, initial); // polynomial deflation using synthetic division Complex newc = c[n-i]; Complex oldc = null; for (int j = n-i-1; j >= 0; j--) { oldc = c[j]; c[j] = newc; newc = oldc.add(newc.multiply(root[i])); } iterationCount += this.iterationCount; } resultComputed = true; this.iterationCount = iterationCount; return root; } /** * Find a complex root for the polynomial with the given coefficients, * starting from the given initial value. * * @param coefficients the polynomial coefficients array * @param initial the start value to use * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2. */ @Deprecated public Complex solve(Complex coefficients[], Complex initial) throws MaxIterationsExceededException, FunctionEvaluationException { int n = coefficients.length - 1; if (n < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NON_POSITIVE_POLYNOMIAL_DEGREE, n); } Complex N = new Complex(n, 0.0); Complex N1 = new Complex(n - 1, 0.0); int i = 1; Complex pv = null; Complex dv = null; Complex d2v = null; Complex G = null; Complex G2 = null; Complex H = null; Complex delta = null; Complex denominator = null; Complex z = initial; Complex oldz = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); while (i <= maximalIterationCount) { // Compute pv (polynomial value), dv (derivative value), and // d2v (second derivative value) simultaneously. pv = coefficients[n]; dv = Complex.ZERO; d2v = Complex.ZERO; for (int j = n-1; j >= 0; j--) { d2v = dv.add(z.multiply(d2v)); dv = pv.add(z.multiply(dv)); pv = coefficients[j].add(z.multiply(pv)); } d2v = d2v.multiply(new Complex(2.0, 0.0)); // check for convergence double tolerance = FastMath.max(relativeAccuracy * z.abs(), absoluteAccuracy); if ((z.subtract(oldz)).abs() <= tolerance) { resultComputed = true; iterationCount = i; return z; } if (pv.abs() <= functionValueAccuracy) { resultComputed = true; iterationCount = i; return z; } // now pv != 0, calculate the new approximation G = dv.divide(pv); G2 = G.multiply(G); H = G2.subtract(d2v.divide(pv)); delta = N1.multiply((N.multiply(H)).subtract(G2)); // choose a denominator larger in magnitude Complex deltaSqrt = delta.sqrt(); Complex dplus = G.add(deltaSqrt); Complex dminus = G.subtract(deltaSqrt); denominator = dplus.abs() > dminus.abs() ? dplus : dminus; // Perturb z if denominator is zero, for instance, // p(x) = x^3 + 1, z = 0. if (denominator.equals(new Complex(0.0, 0.0))) { z = z.add(new Complex(absoluteAccuracy, absoluteAccuracy)); oldz = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); } else { oldz = z; z = z.subtract(N.divide(denominator)); } i++; } throw new MaxIterationsExceededException(maximalIterationCount); } } ././@LongLink100644 0 0 146 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.jav100644 1750 1750 16064 11532241246 32524 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ConvergingAlgorithm; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface for (univariate real) rootfinding algorithms. *

                        * Implementations will search for only one zero in the given interval.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public interface UnivariateRealSolver extends ConvergingAlgorithm { /** * Set the function value accuracy. *

                        * This is used to determine when an evaluated function value or some other * value which is used as divisor is zero.

                        *

                        * This is a safety guard and it shouldn't be necessary to change this in * general.

                        * * @param accuracy the accuracy. * @throws IllegalArgumentException if the accuracy can't be achieved by * the solver or is otherwise deemed unreasonable. */ void setFunctionValueAccuracy(double accuracy); /** * Get the actual function value accuracy. * @return the accuracy */ double getFunctionValueAccuracy(); /** * Reset the actual function accuracy to the default. * The default value is provided by the solver implementation. */ void resetFunctionValueAccuracy(); /** * Solve for a zero root in the given interval. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the solver * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double)} * since 2.0 */ @Deprecated double solve(double min, double max) throws ConvergenceException, FunctionEvaluationException; /** * Solve for a zero root in the given interval. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param f the function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the solver * @since 2.0 * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated double solve(UnivariateRealFunction f, double min, double max) throws ConvergenceException, FunctionEvaluationException; /** * Solve for a zero in the given interval, start at startValue. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param startValue the start value to use * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the arguments do not * satisfy the requirements specified by the solver * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double, double)} * since 2.0 */ @Deprecated double solve(double min, double max, double startValue) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; /** * Solve for a zero in the given interval, start at startValue. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param f the function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param startValue the start value to use * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the arguments do not * satisfy the requirements specified by the solver * @since 2.0 * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated double solve(UnivariateRealFunction f, double min, double max, double startValue) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; /** * Get the result of the last run of the solver. * * @return the last result. * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed. */ double getResult(); /** * Get the result of the last run of the solver. * * @return the value of the function at the last result. * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed. */ double getFunctionValue(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/BisectionSolver.java100644 1750 1750 10570 11532241246 31665 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; /** * Implements the * bisection algorithm for finding zeros of univariate real functions. *

                        * The function should be continuous but not necessarily smooth.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class BisectionSolver extends UnivariateRealSolverImpl { /** * Construct a solver for the given function. * * @param f function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public BisectionSolver(UnivariateRealFunction f) { super(f, 100, 1E-6); } /** * Construct a solver. * */ public BisectionSolver() { super(100, 1E-6); } /** {@inheritDoc} */ @Deprecated public double solve(double min, double max, double initial) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(double min, double max) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** * {@inheritDoc} * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, double min, double max, double initial) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Override public double solve(int maxEval, final UnivariateRealFunction f, double min, double max, double initial) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(maxEval, f, min, max); } /** {@inheritDoc} */ @Override public double solve(int maxEval, final UnivariateRealFunction f, double min, double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * {@inheritDoc} * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, double min, double max) throws MaxIterationsExceededException, FunctionEvaluationException { clearResult(); verifyInterval(min,max); double m; double fm; double fmin; int i = 0; while (i < maximalIterationCount) { m = UnivariateRealSolverUtils.midpoint(min, max); fmin = f.value(min); fm = f.value(m); if (fm * fmin > 0.0) { // max and m bracket the root. min = m; } else { // min and m bracket the root. max = m; } if (FastMath.abs(max - min) <= absoluteAccuracy) { m = UnivariateRealSolverUtils.midpoint(min, max); setResult(m, i); return m; } ++i; } throw new MaxIterationsExceededException(maximalIterationCount); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/package.html100644 1750 1750 1731 11532241246 30150 0ustarlucluc 0 0 Root finding algorithms, for univariate real functions. commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/BrentSolver.java100644 1750 1750 36600 11532241246 31022 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Brent algorithm for finding zeros of real univariate functions. *

                        * The function should be continuous but not necessarily smooth.

                        * * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $ */ public class BrentSolver extends UnivariateRealSolverImpl { /** * Default absolute accuracy * @since 2.1 */ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1E-6; /** Default maximum number of iterations * @since 2.1 */ public static final int DEFAULT_MAXIMUM_ITERATIONS = 100; /** Serializable version identifier */ private static final long serialVersionUID = 7694577816772532779L; /** * Construct a solver for the given function. * * @param f function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public BrentSolver(UnivariateRealFunction f) { super(f, DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY); } /** * Construct a solver with default properties. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public BrentSolver() { super(DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY); } /** * Construct a solver with the given absolute accuracy. * * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver * @since 2.1 */ public BrentSolver(double absoluteAccuracy) { super(DEFAULT_MAXIMUM_ITERATIONS, absoluteAccuracy); } /** * Contstruct a solver with the given maximum iterations and absolute accuracy. * * @param maximumIterations maximum number of iterations * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver * @since 2.1 */ public BrentSolver(int maximumIterations, double absoluteAccuracy) { super(maximumIterations, absoluteAccuracy); } /** {@inheritDoc} */ @Deprecated public double solve(double min, double max) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(double min, double max, double initial) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max, initial); } /** * Find a zero in the given interval with an initial guess. *

                        Throws IllegalArgumentException if the values of the * function at the three points have the same sign (note that it is * allowed to have endpoints with the same sign if the initial point has * opposite sign function-wise).

                        * * @param f function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param initial the start value to use (must be set to min if no * initial point is known). * @return the value where the function is zero * @throws MaxIterationsExceededException the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if initial is not between min and max * (even if it is a root) * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { clearResult(); if ((initial < min) || (initial > max)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS, min, initial, max); } // return the initial guess if it is good enough double yInitial = f.value(initial); if (FastMath.abs(yInitial) <= functionValueAccuracy) { setResult(initial, 0); return result; } // return the first endpoint if it is good enough double yMin = f.value(min); if (FastMath.abs(yMin) <= functionValueAccuracy) { setResult(min, 0); return result; } // reduce interval if min and initial bracket the root if (yInitial * yMin < 0) { return solve(f, min, yMin, initial, yInitial, min, yMin); } // return the second endpoint if it is good enough double yMax = f.value(max); if (FastMath.abs(yMax) <= functionValueAccuracy) { setResult(max, 0); return result; } // reduce interval if initial and max bracket the root if (yInitial * yMax < 0) { return solve(f, initial, yInitial, max, yMax, initial, yInitial); } throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, yMin, yMax); } /** * Find a zero in the given interval with an initial guess. *

                        Throws IllegalArgumentException if the values of the * function at the three points have the same sign (note that it is * allowed to have endpoints with the same sign if the initial point has * opposite sign function-wise).

                        * * @param f function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param initial the start value to use (must be set to min if no * initial point is known). * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if initial is not between min and max * (even if it is a root) */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, initial); } /** * Find a zero in the given interval. *

                        * Requires that the values of the function at the endpoints have opposite * signs. An IllegalArgumentException is thrown if this is not * the case.

                        * * @param f the function to solve * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { clearResult(); verifyInterval(min, max); double ret = Double.NaN; double yMin = f.value(min); double yMax = f.value(max); // Verify bracketing double sign = yMin * yMax; if (sign > 0) { // check if either value is close to a zero if (FastMath.abs(yMin) <= functionValueAccuracy) { setResult(min, 0); ret = min; } else if (FastMath.abs(yMax) <= functionValueAccuracy) { setResult(max, 0); ret = max; } else { // neither value is close to zero and min and max do not bracket root. throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, yMin, yMax); } } else if (sign < 0){ // solve using only the first endpoint as initial guess ret = solve(f, min, yMin, max, yMax, min, yMin); } else { // either min or max is a root if (yMin == 0.0) { ret = min; } else { ret = max; } } return ret; } /** * Find a zero in the given interval. *

                        * Requires that the values of the function at the endpoints have opposite * signs. An IllegalArgumentException is thrown if this is not * the case.

                        * * @param f the function to solve * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a zero starting search according to the three provided points. * @param f the function to solve * @param x0 old approximation for the root * @param y0 function value at the approximation for the root * @param x1 last calculated approximation for the root * @param y1 function value at the last calculated approximation * for the root * @param x2 bracket point (must be set to x0 if no bracket point is * known, this will force starting with linear interpolation) * @param y2 function value at the bracket point. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function */ private double solve(final UnivariateRealFunction f, double x0, double y0, double x1, double y1, double x2, double y2) throws MaxIterationsExceededException, FunctionEvaluationException { double delta = x1 - x0; double oldDelta = delta; int i = 0; while (i < maximalIterationCount) { if (FastMath.abs(y2) < FastMath.abs(y1)) { // use the bracket point if is better than last approximation x0 = x1; x1 = x2; x2 = x0; y0 = y1; y1 = y2; y2 = y0; } if (FastMath.abs(y1) <= functionValueAccuracy) { // Avoid division by very small values. Assume // the iteration has converged (the problem may // still be ill conditioned) setResult(x1, i); return result; } double dx = x2 - x1; double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x1), absoluteAccuracy); if (FastMath.abs(dx) <= tolerance) { setResult(x1, i); return result; } if ((FastMath.abs(oldDelta) < tolerance) || (FastMath.abs(y0) <= FastMath.abs(y1))) { // Force bisection. delta = 0.5 * dx; oldDelta = delta; } else { double r3 = y1 / y0; double p; double p1; // the equality test (x0 == x2) is intentional, // it is part of the original Brent's method, // it should NOT be replaced by proximity test if (x0 == x2) { // Linear interpolation. p = dx * r3; p1 = 1.0 - r3; } else { // Inverse quadratic interpolation. double r1 = y0 / y2; double r2 = y1 / y2; p = r3 * (dx * r1 * (r1 - r2) - (x1 - x0) * (r2 - 1.0)); p1 = (r1 - 1.0) * (r2 - 1.0) * (r3 - 1.0); } if (p > 0.0) { p1 = -p1; } else { p = -p; } if (2.0 * p >= 1.5 * dx * p1 - FastMath.abs(tolerance * p1) || p >= FastMath.abs(0.5 * oldDelta * p1)) { // Inverse quadratic interpolation gives a value // in the wrong direction, or progress is slow. // Fall back to bisection. delta = 0.5 * dx; oldDelta = delta; } else { oldDelta = delta; delta = p / p1; } } // Save old X1, Y1 x0 = x1; y0 = y1; // Compute new X1, Y1 if (FastMath.abs(delta) > tolerance) { x1 = x1 + delta; } else if (dx > 0.0) { x1 = x1 + 0.5 * tolerance; } else if (dx <= 0.0) { x1 = x1 - 0.5 * tolerance; } y1 = f.value(x1); if ((y1 > 0) == (y2 > 0)) { x2 = x0; y2 = y0; delta = x1 - x0; oldDelta = delta; } i++; } throw new MaxIterationsExceededException(maximalIterationCount); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java100644 1750 1750 22616 11532241246 31346 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Implements the * Ridders' Method for root finding of real univariate functions. For * reference, see C. Ridders, A new algorithm for computing a single root * of a real continuous function , IEEE Transactions on Circuits and * Systems, 26 (1979), 979 - 980. *

                        * The function should be continuous but not necessarily smooth.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class RiddersSolver extends UnivariateRealSolverImpl { /** * Construct a solver for the given function. * * @param f function to solve * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public RiddersSolver(UnivariateRealFunction f) { super(f, 100, 1E-6); } /** * Construct a solver. * @deprecated in 2.2 */ @Deprecated public RiddersSolver() { super(100, 1E-6); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max, initial); } /** * Find a root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, initial); } /** * Find a root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { // check for zeros before verifying bracketing if (f.value(min) == 0.0) { return min; } if (f.value(max) == 0.0) { return max; } if (f.value(initial) == 0.0) { return initial; } verifyBracketing(min, max, f); verifySequence(min, initial, max); if (isBracketing(min, initial, f)) { return solve(f, min, initial); } else { return solve(f, initial, max); } } /** * Find a root in the given interval. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a root in the given interval. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { // [x1, x2] is the bracketing interval in each iteration // x3 is the midpoint of [x1, x2] // x is the new root approximation and an endpoint of the new interval double x1 = min; double y1 = f.value(x1); double x2 = max; double y2 = f.value(x2); // check for zeros before verifying bracketing if (y1 == 0.0) { return min; } if (y2 == 0.0) { return max; } verifyBracketing(min, max, f); int i = 1; double oldx = Double.POSITIVE_INFINITY; while (i <= maximalIterationCount) { // calculate the new root approximation final double x3 = 0.5 * (x1 + x2); final double y3 = f.value(x3); if (FastMath.abs(y3) <= functionValueAccuracy) { setResult(x3, i); return result; } final double delta = 1 - (y1 * y2) / (y3 * y3); // delta > 1 due to bracketing final double correction = (MathUtils.sign(y2) * MathUtils.sign(y3)) * (x3 - x1) / FastMath.sqrt(delta); final double x = x3 - correction; // correction != 0 final double y = f.value(x); // check for convergence final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy); if (FastMath.abs(x - oldx) <= tolerance) { setResult(x, i); return result; } if (FastMath.abs(y) <= functionValueAccuracy) { setResult(x, i); return result; } // prepare the new interval for next iteration // Ridders' method guarantees x1 < x < x2 if (correction > 0.0) { // x1 < x < x3 if (MathUtils.sign(y1) + MathUtils.sign(y) == 0.0) { x2 = x; y2 = y; } else { x1 = x; x2 = x3; y1 = y; y2 = y3; } } else { // x3 < x < x2 if (MathUtils.sign(y2) + MathUtils.sign(y) == 0.0) { x1 = x; y1 = y; } else { x1 = x3; x2 = x; y1 = y3; y2 = y; } } oldx = x; i++; } throw new MaxIterationsExceededException(maximalIterationCount); } } ././@LongLink100644 0 0 153 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtil100644 1750 1750 23753 11532241246 32606 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.util.FastMath; /** * Utility routines for {@link UnivariateRealSolver} objects. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class UnivariateRealSolverUtils { /** * Default constructor. */ private UnivariateRealSolverUtils() { super(); } /** * Convenience method to find a zero of a univariate real function. A default * solver is used. * * @param f the function. * @param x0 the lower bound for the interval. * @param x1 the upper bound for the interval. * @return a value where the function is zero. * @throws ConvergenceException if the iteration count was exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if f is null or the endpoints do not * specify a valid interval */ public static double solve(UnivariateRealFunction f, double x0, double x1) throws ConvergenceException, FunctionEvaluationException { setup(f); return LazyHolder.FACTORY.newDefaultSolver().solve(f, x0, x1); } /** * Convenience method to find a zero of a univariate real function. A default * solver is used. * * @param f the function * @param x0 the lower bound for the interval * @param x1 the upper bound for the interval * @param absoluteAccuracy the accuracy to be used by the solver * @return a value where the function is zero * @throws ConvergenceException if the iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if f is null, the endpoints do not * specify a valid interval, or the absoluteAccuracy is not valid for the * default solver */ public static double solve(UnivariateRealFunction f, double x0, double x1, double absoluteAccuracy) throws ConvergenceException, FunctionEvaluationException { setup(f); UnivariateRealSolver solver = LazyHolder.FACTORY.newDefaultSolver(); solver.setAbsoluteAccuracy(absoluteAccuracy); return solver.solve(f, x0, x1); } /** * This method attempts to find two values a and b satisfying
                          *
                        • lowerBound <= a < initial < b <= upperBound
                        • *
                        • f(a) * f(b) < 0
                        • *
                        * If f is continuous on [a,b], this means that a * and b bracket a root of f. *

                        * The algorithm starts by setting * a := initial -1; b := initial +1, examines the value of the * function at a and b and keeps moving * the endpoints out by one unit each time through a loop that terminates * when one of the following happens:

                          *
                        • f(a) * f(b) < 0 -- success!
                        • *
                        • a = lower and b = upper * -- ConvergenceException
                        • *
                        • Integer.MAX_VALUE iterations elapse * -- ConvergenceException
                        • *

                        *

                        * Note: this method can take * Integer.MAX_VALUE iterations to throw a * ConvergenceException. Unless you are confident that there * is a root between lowerBound and upperBound * near initial, it is better to use * {@link #bracket(UnivariateRealFunction, double, double, double, int)}, * explicitly specifying the maximum number of iterations.

                        * * @param function the function * @param initial initial midpoint of interval being expanded to * bracket a root * @param lowerBound lower bound (a is never lower than this value) * @param upperBound upper bound (b never is greater than this * value) * @return a two element array holding {a, b} * @throws ConvergenceException if a root can not be bracketted * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if function is null, maximumIterations * is not positive, or initial is not between lowerBound and upperBound */ public static double[] bracket(UnivariateRealFunction function, double initial, double lowerBound, double upperBound) throws ConvergenceException, FunctionEvaluationException { return bracket( function, initial, lowerBound, upperBound, Integer.MAX_VALUE ) ; } /** * This method attempts to find two values a and b satisfying
                          *
                        • lowerBound <= a < initial < b <= upperBound
                        • *
                        • f(a) * f(b) <= 0
                        • *
                        * If f is continuous on [a,b], this means that a * and b bracket a root of f. *

                        * The algorithm starts by setting * a := initial -1; b := initial +1, examines the value of the * function at a and b and keeps moving * the endpoints out by one unit each time through a loop that terminates * when one of the following happens:

                          *
                        • f(a) * f(b) <= 0 -- success!
                        • *
                        • a = lower and b = upper * -- ConvergenceException
                        • *
                        • maximumIterations iterations elapse * -- ConvergenceException

                        * * @param function the function * @param initial initial midpoint of interval being expanded to * bracket a root * @param lowerBound lower bound (a is never lower than this value) * @param upperBound upper bound (b never is greater than this * value) * @param maximumIterations maximum number of iterations to perform * @return a two element array holding {a, b}. * @throws ConvergenceException if the algorithm fails to find a and b * satisfying the desired conditions * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if function is null, maximumIterations * is not positive, or initial is not between lowerBound and upperBound */ public static double[] bracket(UnivariateRealFunction function, double initial, double lowerBound, double upperBound, int maximumIterations) throws ConvergenceException, FunctionEvaluationException { if (function == null) { throw new NullArgumentException(LocalizedFormats.FUNCTION); } if (maximumIterations <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_MAX_ITERATIONS, maximumIterations); } if (initial < lowerBound || initial > upperBound || lowerBound >= upperBound) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_BRACKETING_PARAMETERS, lowerBound, initial, upperBound); } double a = initial; double b = initial; double fa; double fb; int numIterations = 0 ; do { a = FastMath.max(a - 1.0, lowerBound); b = FastMath.min(b + 1.0, upperBound); fa = function.value(a); fb = function.value(b); numIterations++ ; } while ((fa * fb > 0.0) && (numIterations < maximumIterations) && ((a > lowerBound) || (b < upperBound))); if (fa * fb > 0.0 ) { throw new ConvergenceException( LocalizedFormats.FAILED_BRACKETING, numIterations, maximumIterations, initial, lowerBound, upperBound, a, b, fa, fb); } return new double[]{a, b}; } /** * Compute the midpoint of two values. * * @param a first value. * @param b second value. * @return the midpoint. */ public static double midpoint(double a, double b) { return (a + b) * .5; } /** * Checks to see if f is null, throwing IllegalArgumentException if so. * @param f input function * @throws IllegalArgumentException if f is null */ private static void setup(UnivariateRealFunction f) { if (f == null) { throw new NullArgumentException(LocalizedFormats.FUNCTION); } } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the factory. *

                        We use here the Initialization On Demand Holder Idiom.

                        */ private static class LazyHolder { /** Cached solver factory */ private static final UnivariateRealSolverFactory FACTORY = UnivariateRealSolverFactory.newInstance(); } // CHECKSTYLE: resume HideUtilityClassConstructor } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java100644 1750 1750 42773 11532241246 31220 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.MathUtils; /** * Implements the * Muller's Method for root finding of real univariate functions. For * reference, see Elementary Numerical Analysis, ISBN 0070124477, * chapter 3. *

                        * Muller's method applies to both real and complex functions, but here we * restrict ourselves to real functions. Methods solve() and solve2() find * real zeros, using different ways to bypass complex arithmetics.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class MullerSolver extends UnivariateRealSolverImpl { /** * Construct a solver for the given function. * * @param f function to solve * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public MullerSolver(UnivariateRealFunction f) { super(f, 100, 1E-6); } /** * Construct a solver. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public MullerSolver() { super(100, 1E-6); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max, initial); } /** * Find a real root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, initial); } /** * Find a real root in the given interval with initial value. *

                        * Requires bracketing condition.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { // check for zeros before verifying bracketing if (f.value(min) == 0.0) { return min; } if (f.value(max) == 0.0) { return max; } if (f.value(initial) == 0.0) { return initial; } verifyBracketing(min, max, f); verifySequence(min, initial, max); if (isBracketing(min, initial, f)) { return solve(f, min, initial); } else { return solve(f, initial, max); } } /** * Find a real root in the given interval. *

                        * Original Muller's method would have function evaluation at complex point. * Since our f(x) is real, we have to find ways to avoid that. Bracketing * condition is one way to go: by requiring bracketing in every iteration, * the newly computed approximation is guaranteed to be real.

                        *

                        * Normally Muller's method converges quadratically in the vicinity of a * zero, however it may be very slow in regions far away from zeros. For * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use * bisection as a safety backup if it performs very poorly.

                        *

                        * The formulas here use divided differences directly.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param maxEval Maximum number of evaluations. * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a real root in the given interval. *

                        * Original Muller's method would have function evaluation at complex point. * Since our f(x) is real, we have to find ways to avoid that. Bracketing * condition is one way to go: by requiring bracketing in every iteration, * the newly computed approximation is guaranteed to be real.

                        *

                        * Normally Muller's method converges quadratically in the vicinity of a * zero, however it may be very slow in regions far away from zeros. For * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use * bisection as a safety backup if it performs very poorly.

                        *

                        * The formulas here use divided differences directly.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { // [x0, x2] is the bracketing interval in each iteration // x1 is the last approximation and an interpolation point in (x0, x2) // x is the new root approximation and new x1 for next round // d01, d12, d012 are divided differences double x0 = min; double y0 = f.value(x0); double x2 = max; double y2 = f.value(x2); double x1 = 0.5 * (x0 + x2); double y1 = f.value(x1); // check for zeros before verifying bracketing if (y0 == 0.0) { return min; } if (y2 == 0.0) { return max; } verifyBracketing(min, max, f); double oldx = Double.POSITIVE_INFINITY; for (int i = 1; i <= maximalIterationCount; ++i) { // Muller's method employs quadratic interpolation through // x0, x1, x2 and x is the zero of the interpolating parabola. // Due to bracketing condition, this parabola must have two // real roots and we choose one in [x0, x2] to be x. final double d01 = (y1 - y0) / (x1 - x0); final double d12 = (y2 - y1) / (x2 - x1); final double d012 = (d12 - d01) / (x2 - x0); final double c1 = d01 + (x1 - x0) * d012; final double delta = c1 * c1 - 4 * y1 * d012; final double xplus = x1 + (-2.0 * y1) / (c1 + FastMath.sqrt(delta)); final double xminus = x1 + (-2.0 * y1) / (c1 - FastMath.sqrt(delta)); // xplus and xminus are two roots of parabola and at least // one of them should lie in (x0, x2) final double x = isSequence(x0, xplus, x2) ? xplus : xminus; final double y = f.value(x); // check for convergence final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy); if (FastMath.abs(x - oldx) <= tolerance) { setResult(x, i); return result; } if (FastMath.abs(y) <= functionValueAccuracy) { setResult(x, i); return result; } // Bisect if convergence is too slow. Bisection would waste // our calculation of x, hopefully it won't happen often. // the real number equality test x == x1 is intentional and // completes the proximity tests above it boolean bisect = (x < x1 && (x1 - x0) > 0.95 * (x2 - x0)) || (x > x1 && (x2 - x1) > 0.95 * (x2 - x0)) || (x == x1); // prepare the new bracketing interval for next iteration if (!bisect) { x0 = x < x1 ? x0 : x1; y0 = x < x1 ? y0 : y1; x2 = x > x1 ? x2 : x1; y2 = x > x1 ? y2 : y1; x1 = x; y1 = y; oldx = x; } else { double xm = 0.5 * (x0 + x2); double ym = f.value(xm); if (MathUtils.sign(y0) + MathUtils.sign(ym) == 0.0) { x2 = xm; y2 = ym; } else { x0 = xm; y0 = ym; } x1 = 0.5 * (x0 + x2); y1 = f.value(x1); oldx = Double.POSITIVE_INFINITY; } } throw new MaxIterationsExceededException(maximalIterationCount); } /** * Find a real root in the given interval. *

                        * solve2() differs from solve() in the way it avoids complex operations. * Except for the initial [min, max], solve2() does not require bracketing * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex * number arises in the computation, we simply use its modulus as real * approximation.

                        *

                        * Because the interval may not be bracketing, bisection alternative is * not applicable here. However in practice our treatment usually works * well, especially near real zeros where the imaginary part of complex * approximation is often negligible.

                        *

                        * The formulas here do not use divided differences directly.

                        * * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated replaced by {@link #solve2(UnivariateRealFunction, double, double)} * since 2.0 */ @Deprecated public double solve2(final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { return solve2(f, min, max); } /** * Find a real root in the given interval. *

                        * solve2() differs from solve() in the way it avoids complex operations. * Except for the initial [min, max], solve2() does not require bracketing * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex * number arises in the computation, we simply use its modulus as real * approximation.

                        *

                        * Because the interval may not be bracketing, bisection alternative is * not applicable here. However in practice our treatment usually works * well, especially near real zeros where the imaginary part of complex * approximation is often negligible.

                        *

                        * The formulas here do not use divided differences directly.

                        * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the point at which the function value is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if any parameters are invalid * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve2(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { // x2 is the last root approximation // x is the new approximation and new x2 for next round // x0 < x1 < x2 does not hold here double x0 = min; double y0 = f.value(x0); double x1 = max; double y1 = f.value(x1); double x2 = 0.5 * (x0 + x1); double y2 = f.value(x2); // check for zeros before verifying bracketing if (y0 == 0.0) { return min; } if (y1 == 0.0) { return max; } verifyBracketing(min, max, f); double oldx = Double.POSITIVE_INFINITY; for (int i = 1; i <= maximalIterationCount; ++i) { // quadratic interpolation through x0, x1, x2 final double q = (x2 - x1) / (x1 - x0); final double a = q * (y2 - (1 + q) * y1 + q * y0); final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0; final double c = (1 + q) * y2; final double delta = b * b - 4 * a * c; double x; final double denominator; if (delta >= 0.0) { // choose a denominator larger in magnitude double dplus = b + FastMath.sqrt(delta); double dminus = b - FastMath.sqrt(delta); denominator = FastMath.abs(dplus) > FastMath.abs(dminus) ? dplus : dminus; } else { // take the modulus of (B +/- FastMath.sqrt(delta)) denominator = FastMath.sqrt(b * b - delta); } if (denominator != 0) { x = x2 - 2.0 * c * (x2 - x1) / denominator; // perturb x if it exactly coincides with x1 or x2 // the equality tests here are intentional while (x == x1 || x == x2) { x += absoluteAccuracy; } } else { // extremely rare case, get a random number to skip it x = min + FastMath.random() * (max - min); oldx = Double.POSITIVE_INFINITY; } final double y = f.value(x); // check for convergence final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy); if (FastMath.abs(x - oldx) <= tolerance) { setResult(x, i); return result; } if (FastMath.abs(y) <= functionValueAccuracy) { setResult(x, i); return result; } // prepare the next iteration x0 = x1; y0 = y1; x1 = x2; y1 = y2; x2 = x; y2 = y; oldx = x; } throw new MaxIterationsExceededException(maximalIterationCount); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java100644 1750 1750 21747 11532241246 31173 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements a modified version of the * secant method * for approximating a zero of a real univariate function. *

                        * The algorithm is modified to maintain bracketing of a root by successive * approximations. Because of forced bracketing, convergence may be slower than * the unrestricted secant algorithm. However, this implementation should in * general outperform the * * regula falsi method.

                        *

                        * The function is assumed to be continuous but not necessarily smooth.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class SecantSolver extends UnivariateRealSolverImpl { /** * Construct a solver for the given function. * @param f function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public SecantSolver(UnivariateRealFunction f) { super(f, 100, 1E-6); } /** * Construct a solver. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public SecantSolver() { super(100, 1E-6); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max, final double initial) throws ConvergenceException, FunctionEvaluationException { return solve(f, min, max, initial); } /** * Find a zero in the given interval. * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use (ignored) * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, initial); } /** * Find a zero in the given interval. * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param initial the start value to use (ignored) * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** * Find a zero in the given interval. * @param f the function to solve * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a zero in the given interval. * @param f the function to solve * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min is not less than max or the * signs of the values of the function at the endpoints are not opposites * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { clearResult(); verifyInterval(min, max); // Index 0 is the old approximation for the root. // Index 1 is the last calculated approximation for the root. // Index 2 is a bracket for the root with respect to x0. // OldDelta is the length of the bracketing interval of the last // iteration. double x0 = min; double x1 = max; double y0 = f.value(x0); double y1 = f.value(x1); // Verify bracketing if (y0 * y1 >= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, y0, y1); } double x2 = x0; double y2 = y0; double oldDelta = x2 - x1; int i = 0; while (i < maximalIterationCount) { if (FastMath.abs(y2) < FastMath.abs(y1)) { x0 = x1; x1 = x2; x2 = x0; y0 = y1; y1 = y2; y2 = y0; } if (FastMath.abs(y1) <= functionValueAccuracy) { setResult(x1, i); return result; } if (FastMath.abs(oldDelta) < FastMath.max(relativeAccuracy * FastMath.abs(x1), absoluteAccuracy)) { setResult(x1, i); return result; } double delta; if (FastMath.abs(y1) > FastMath.abs(y0)) { // Function value increased in last iteration. Force bisection. delta = 0.5 * oldDelta; } else { delta = (x0 - x1) / (1 - y0 / y1); if (delta / oldDelta > 1) { // New approximation falls outside bracket. // Fall back to bisection. delta = 0.5 * oldDelta; } } x0 = x1; y0 = y1; x1 = x1 + delta; y1 = f.value(x1); if ((y1 > 0) == (y2 > 0)) { // New bracket is (x0,x1). x2 = x0; y2 = y0; } oldDelta = x2 - x1; i++; } throw new MaxIterationsExceededException(maximalIterationCount); } } ././@LongLink100644 0 0 155 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFact100644 1750 1750 5705 11532241246 32523 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; /** * Abstract factory class used to create {@link UnivariateRealSolver} instances. *

                        * Solvers implementing the following algorithms are supported: *

                          *
                        • Bisection
                        • *
                        • Brent's method
                        • *
                        • Secant method
                        • *
                        * Concrete factories extending this class also specify a default solver, instances of which * are returned by newDefaultSolver().

                        *

                        * Common usage:

                         * SolverFactory factory = UnivariateRealSolverFactory.newInstance();

                        * * // create a Brent solver to use * BrentSolver solver = factory.newBrentSolver(); *
                        * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public abstract class UnivariateRealSolverFactory { /** * Default constructor. */ protected UnivariateRealSolverFactory() { } /** * Create a new factory. * @return a new factory. */ public static UnivariateRealSolverFactory newInstance() { return new UnivariateRealSolverFactoryImpl(); } /** * Create a new {@link UnivariateRealSolver}. The * actual solver returned is determined by the underlying factory. * @return the new solver. */ public abstract UnivariateRealSolver newDefaultSolver(); /** * Create a new {@link UnivariateRealSolver}. The * solver is an implementation of the bisection method. * @return the new solver. */ public abstract UnivariateRealSolver newBisectionSolver(); /** * Create a new {@link UnivariateRealSolver}. The * solver is an implementation of the Brent method. * @return the new solver. */ public abstract UnivariateRealSolver newBrentSolver(); /** * Create a new {@link UnivariateRealSolver}. The * solver is an implementation of Newton's Method. * @return the new solver. */ public abstract UnivariateRealSolver newNewtonSolver(); /** * Create a new {@link UnivariateRealSolver}. The * solver is an implementation of the secant method. * @return the new solver. */ public abstract UnivariateRealSolver newSecantSolver(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java100644 1750 1750 16617 11532241246 31230 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements * Newton's Method for finding zeros of real univariate functions. *

                        * The function should be continuous but not necessarily smooth.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class NewtonSolver extends UnivariateRealSolverImpl { /** * Construct a solver for the given function. * @param f function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated public NewtonSolver(DifferentiableUnivariateRealFunction f) { super(f, 100, 1E-6); } /** * Construct a solver. * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public NewtonSolver() { super(100, 1E-6); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max); } /** {@inheritDoc} */ @Deprecated public double solve(final double min, final double max, final double startValue) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max, startValue); } /** * Find a zero near the midpoint of min and max. * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative * @throws IllegalArgumentException if min is not less than max */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max); } /** * Find a zero near the midpoint of min and max. * * @param f the function to solve * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative * @throws IllegalArgumentException if min is not less than max * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException { return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max)); } /** * Find a zero near the value startValue. * * @param f the function to solve * @param min the lower bound for the interval (ignored). * @param max the upper bound for the interval (ignored). * @param startValue the start value to use. * @param maxEval Maximum number of evaluations. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative * @throws IllegalArgumentException if startValue is not between min and max or * if function is not a {@link DifferentiableUnivariateRealFunction} instance */ @Override public double solve(int maxEval, final UnivariateRealFunction f, final double min, final double max, final double startValue) throws MaxIterationsExceededException, FunctionEvaluationException { setMaximalIterationCount(maxEval); return solve(f, min, max, startValue); } /** * Find a zero near the value startValue. * * @param f the function to solve * @param min the lower bound for the interval (ignored). * @param max the upper bound for the interval (ignored). * @param startValue the start value to use. * @return the value where the function is zero * @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative * @throws IllegalArgumentException if startValue is not between min and max or * if function is not a {@link DifferentiableUnivariateRealFunction} instance * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public double solve(final UnivariateRealFunction f, final double min, final double max, final double startValue) throws MaxIterationsExceededException, FunctionEvaluationException { try { final UnivariateRealFunction derivative = ((DifferentiableUnivariateRealFunction) f).derivative(); clearResult(); verifySequence(min, startValue, max); double x0 = startValue; double x1; int i = 0; while (i < maximalIterationCount) { x1 = x0 - (f.value(x0) / derivative.value(x0)); if (FastMath.abs(x1 - x0) <= absoluteAccuracy) { setResult(x1, i); return x1; } x0 = x1; ++i; } throw new MaxIterationsExceededException(maximalIterationCount); } catch (ClassCastException cce) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_DIFFERENTIABLE); } } } ././@LongLink100644 0 0 152 11532242444 10252 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl100644 1750 1750 27450 11532241246 32570 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergingAlgorithmImpl; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.exception.NullArgumentException; /** * Provide a default implementation for several functions useful to generic * solvers. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @deprecated in 2.2 (to be removed in 3.0). */ @Deprecated public abstract class UnivariateRealSolverImpl extends ConvergingAlgorithmImpl implements UnivariateRealSolver { /** Maximum error of function. */ protected double functionValueAccuracy; /** Default maximum error of function. */ protected double defaultFunctionValueAccuracy; /** Indicates where a root has been computed. */ protected boolean resultComputed = false; /** The last computed root. */ protected double result; /** Value of the function at the last computed result. */ protected double functionValue; /** The function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated protected UnivariateRealFunction f; /** * Construct a solver with given iteration count and accuracy. * * @param f the function to solve. * @param defaultAbsoluteAccuracy maximum absolute error * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the * defaultAbsoluteAccuracy is not valid * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} * method. */ @Deprecated protected UnivariateRealSolverImpl(final UnivariateRealFunction f, final int defaultMaximalIterationCount, final double defaultAbsoluteAccuracy) { super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); if (f == null) { throw new NullArgumentException(LocalizedFormats.FUNCTION); } this.f = f; this.defaultFunctionValueAccuracy = 1.0e-15; this.functionValueAccuracy = defaultFunctionValueAccuracy; } /** * Construct a solver with given iteration count and accuracy. * * @param defaultAbsoluteAccuracy maximum absolute error * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the * defaultAbsoluteAccuracy is not valid */ protected UnivariateRealSolverImpl(final int defaultMaximalIterationCount, final double defaultAbsoluteAccuracy) { super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); this.defaultFunctionValueAccuracy = 1.0e-15; this.functionValueAccuracy = defaultFunctionValueAccuracy; } /** Check if a result has been computed. * @exception IllegalStateException if no result has been computed */ protected void checkResultComputed() throws IllegalStateException { if (!resultComputed) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE); } } /** {@inheritDoc} */ public double getResult() { checkResultComputed(); return result; } /** {@inheritDoc} */ public double getFunctionValue() { checkResultComputed(); return functionValue; } /** {@inheritDoc} */ public void setFunctionValueAccuracy(final double accuracy) { functionValueAccuracy = accuracy; } /** {@inheritDoc} */ public double getFunctionValueAccuracy() { return functionValueAccuracy; } /** {@inheritDoc} */ public void resetFunctionValueAccuracy() { functionValueAccuracy = defaultFunctionValueAccuracy; } /** * Solve for a zero root in the given interval. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param function the function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param maxEval Maximum number of evaluations. * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the solver * @since 2.2 */ public double solve(int maxEval, UnivariateRealFunction function, double min, double max) throws ConvergenceException, FunctionEvaluationException { throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); } /** * Solve for a zero in the given interval, start at startValue. *

                        A solver may require that the interval brackets a single zero root. * Solvers that do require bracketing should be able to handle the case * where one of the endpoints is itself a root.

                        * * @param function the function to solve. * @param min the lower bound for the interval. * @param max the upper bound for the interval. * @param startValue the start value to use * @param maxEval Maximum number of evaluations. * @return a value where the function is zero * @throws ConvergenceException if the maximum iteration count is exceeded * or the solver detects convergence problems otherwise. * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the arguments do not * satisfy the requirements specified by the solver * @since 2.2 */ public double solve(int maxEval, UnivariateRealFunction function, double min, double max, double startValue) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); } /** * Convenience function for implementations. * * @param newResult the result to set * @param iterationCount the iteration count to set */ protected final void setResult(final double newResult, final int iterationCount) { this.result = newResult; this.iterationCount = iterationCount; this.resultComputed = true; } /** * Convenience function for implementations. * * @param x the result to set * @param fx the result to set * @param iterationCount the iteration count to set */ protected final void setResult(final double x, final double fx, final int iterationCount) { this.result = x; this.functionValue = fx; this.iterationCount = iterationCount; this.resultComputed = true; } /** * Convenience function for implementations. */ protected final void clearResult() { this.iterationCount = 0; this.resultComputed = false; } /** * Returns true iff the function takes opposite signs at the endpoints. * * @param lower the lower endpoint * @param upper the upper endpoint * @param function the function * @return true if f(lower) * f(upper) < 0 * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints */ protected boolean isBracketing(final double lower, final double upper, final UnivariateRealFunction function) throws FunctionEvaluationException { final double f1 = function.value(lower); final double f2 = function.value(upper); return (f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0); } /** * Returns true if the arguments form a (strictly) increasing sequence * * @param start first number * @param mid second number * @param end third number * @return true if the arguments form an increasing sequence */ protected boolean isSequence(final double start, final double mid, final double end) { return (start < mid) && (mid < end); } /** * Verifies that the endpoints specify an interval, * throws IllegalArgumentException if not * * @param lower lower endpoint * @param upper upper endpoint * @throws IllegalArgumentException */ protected void verifyInterval(final double lower, final double upper) { if (lower >= upper) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL, lower, upper); } } /** * Verifies that lower < initial < upper * throws IllegalArgumentException if not * * @param lower lower endpoint * @param initial initial value * @param upper upper endpoint * @throws IllegalArgumentException */ protected void verifySequence(final double lower, final double initial, final double upper) { if (!isSequence(lower, initial, upper)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS, lower, initial, upper); } } /** * Verifies that the endpoints specify an interval and the function takes * opposite signs at the endpoints, throws IllegalArgumentException if not * * @param lower lower endpoint * @param upper upper endpoint * @param function function * @throws IllegalArgumentException * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints */ protected void verifyBracketing(final double lower, final double upper, final UnivariateRealFunction function) throws FunctionEvaluationException { verifyInterval(lower, upper); if (!isBracketing(lower, upper, function)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, lower, upper, function.value(lower), function.value(upper)); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java100644 1750 1750 10215 11532241246 30004 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.util.FastMath; /** * Base class for {@link BivariateRealFunction} that can be composed with other functions. * * @since 2.1 * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ * @deprecated in 2.2 */ @Deprecated public abstract class BinaryFunction implements BivariateRealFunction { /** The + operator method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction ADD = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return x + y; } }; /** The - operator method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction SUBTRACT = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return x - y; } }; /** The * operator method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction MULTIPLY = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return x * y; } }; /** The / operator method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction DIVIDE = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return x / y; } }; /** The {@code FastMath.pow} method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction POW = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return FastMath.pow(x, y); } }; /** The {@code FastMath.atan2} method wrapped as a {@link BinaryFunction}. */ public static final BinaryFunction ATAN2 = new BinaryFunction() { /** {@inheritDoc} */ @Override public double value(double x, double y) { return FastMath.atan2(x, y); } }; /** {@inheritDoc} */ public abstract double value(double x, double y) throws FunctionEvaluationException; /** Get a composable function by fixing the first argument of the instance. * @param fixedX fixed value of the first argument * @return a function such that {@code f.value(y) == value(fixedX, y)} */ public ComposableFunction fix1stArgument(final double fixedX) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return BinaryFunction.this.value(fixedX, x); } }; } /** Get a composable function by fixing the second argument of the instance. * @param fixedY fixed value of the second argument * @return a function such that {@code f.value(x) == value(x, fixedY)} */ public ComposableFunction fix2ndArgument(final double fixedY) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return BinaryFunction.this.value(x, fixedY); } }; } } ././@LongLink100644 0 0 150 11532242444 10250 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.j100644 1750 1750 27074 11532241246 32574 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.util.FastMath; /** * Immutable representation of a real polynomial function with real coefficients. *

                        * Horner's Method * is used to evaluate the function.

                        * * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable { /** * Serialization identifier */ private static final long serialVersionUID = -7726511984200295583L; /** * The coefficients of the polynomial, ordered by degree -- i.e., * coefficients[0] is the constant term and coefficients[n] is the * coefficient of x^n where n is the degree of the polynomial. */ private final double coefficients[]; /** * Construct a polynomial with the given coefficients. The first element * of the coefficients array is the constant term. Higher degree * coefficients follow in sequence. The degree of the resulting polynomial * is the index of the last non-null element of the array, or 0 if all elements * are null. *

                        * The constructor makes a copy of the input array and assigns the copy to * the coefficients property.

                        * * @param c polynomial coefficients * @throws NullPointerException if c is null * @throws NoDataException if c is empty */ public PolynomialFunction(double c[]) { super(); int n = c.length; if (n == 0) { throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); } while ((n > 1) && (c[n - 1] == 0)) { --n; } this.coefficients = new double[n]; System.arraycopy(c, 0, this.coefficients, 0, n); } /** * Compute the value of the function for the given argument. *

                        * The value returned is
                        * coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0] *

                        * * @param x the argument for which the function value should be computed * @return the value of the polynomial at the given point * @see UnivariateRealFunction#value(double) */ public double value(double x) { return evaluate(coefficients, x); } /** * Returns the degree of the polynomial * * @return the degree of the polynomial */ public int degree() { return coefficients.length - 1; } /** * Returns a copy of the coefficients array. *

                        * Changes made to the returned copy will not affect the coefficients of * the polynomial.

                        * * @return a fresh copy of the coefficients array */ public double[] getCoefficients() { return coefficients.clone(); } /** * Uses Horner's Method to evaluate the polynomial with the given coefficients at * the argument. * * @param coefficients the coefficients of the polynomial to evaluate * @param argument the input value * @return the value of the polynomial * @throws NoDataException if coefficients is empty * @throws NullPointerException if coefficients is null */ protected static double evaluate(double[] coefficients, double argument) { int n = coefficients.length; if (n == 0) { throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); } double result = coefficients[n - 1]; for (int j = n -2; j >=0; j--) { result = argument * result + coefficients[j]; } return result; } /** * Add a polynomial to the instance. * @param p polynomial to add * @return a new polynomial which is the sum of the instance and p */ public PolynomialFunction add(final PolynomialFunction p) { // identify the lowest degree polynomial final int lowLength = FastMath.min(coefficients.length, p.coefficients.length); final int highLength = FastMath.max(coefficients.length, p.coefficients.length); // build the coefficients array double[] newCoefficients = new double[highLength]; for (int i = 0; i < lowLength; ++i) { newCoefficients[i] = coefficients[i] + p.coefficients[i]; } System.arraycopy((coefficients.length < p.coefficients.length) ? p.coefficients : coefficients, lowLength, newCoefficients, lowLength, highLength - lowLength); return new PolynomialFunction(newCoefficients); } /** * Subtract a polynomial from the instance. * @param p polynomial to subtract * @return a new polynomial which is the difference the instance minus p */ public PolynomialFunction subtract(final PolynomialFunction p) { // identify the lowest degree polynomial int lowLength = FastMath.min(coefficients.length, p.coefficients.length); int highLength = FastMath.max(coefficients.length, p.coefficients.length); // build the coefficients array double[] newCoefficients = new double[highLength]; for (int i = 0; i < lowLength; ++i) { newCoefficients[i] = coefficients[i] - p.coefficients[i]; } if (coefficients.length < p.coefficients.length) { for (int i = lowLength; i < highLength; ++i) { newCoefficients[i] = -p.coefficients[i]; } } else { System.arraycopy(coefficients, lowLength, newCoefficients, lowLength, highLength - lowLength); } return new PolynomialFunction(newCoefficients); } /** * Negate the instance. * @return a new polynomial */ public PolynomialFunction negate() { double[] newCoefficients = new double[coefficients.length]; for (int i = 0; i < coefficients.length; ++i) { newCoefficients[i] = -coefficients[i]; } return new PolynomialFunction(newCoefficients); } /** * Multiply the instance by a polynomial. * @param p polynomial to multiply by * @return a new polynomial */ public PolynomialFunction multiply(final PolynomialFunction p) { double[] newCoefficients = new double[coefficients.length + p.coefficients.length - 1]; for (int i = 0; i < newCoefficients.length; ++i) { newCoefficients[i] = 0.0; for (int j = FastMath.max(0, i + 1 - p.coefficients.length); j < FastMath.min(coefficients.length, i + 1); ++j) { newCoefficients[i] += coefficients[j] * p.coefficients[i-j]; } } return new PolynomialFunction(newCoefficients); } /** * Returns the coefficients of the derivative of the polynomial with the given coefficients. * * @param coefficients the coefficients of the polynomial to differentiate * @return the coefficients of the derivative or null if coefficients has length 1. * @throws NoDataException if coefficients is empty * @throws NullPointerException if coefficients is null */ protected static double[] differentiate(double[] coefficients) { int n = coefficients.length; if (n == 0) { throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); } if (n == 1) { return new double[]{0}; } double[] result = new double[n - 1]; for (int i = n - 1; i > 0; i--) { result[i - 1] = i * coefficients[i]; } return result; } /** * Returns the derivative as a PolynomialRealFunction * * @return the derivative polynomial */ public PolynomialFunction polynomialDerivative() { return new PolynomialFunction(differentiate(coefficients)); } /** * Returns the derivative as a UnivariateRealFunction * * @return the derivative function */ public UnivariateRealFunction derivative() { return polynomialDerivative(); } /** Returns a string representation of the polynomial. *

                        The representation is user oriented. Terms are displayed lowest * degrees first. The multiplications signs, coefficients equals to * one and null terms are not displayed (except if the polynomial is 0, * in which case the 0 constant term is displayed). Addition of terms * with negative coefficients are replaced by subtraction of terms * with positive coefficients except for the first displayed term * (i.e. we display -3 for a constant negative polynomial, * but 1 - 3 x + x^2 if the negative coefficient is not * the first one displayed).

                        * @return a string representation of the polynomial */ @Override public String toString() { StringBuilder s = new StringBuilder(); if (coefficients[0] == 0.0) { if (coefficients.length == 1) { return "0"; } } else { s.append(Double.toString(coefficients[0])); } for (int i = 1; i < coefficients.length; ++i) { if (coefficients[i] != 0) { if (s.length() > 0) { if (coefficients[i] < 0) { s.append(" - "); } else { s.append(" + "); } } else { if (coefficients[i] < 0) { s.append("-"); } } double absAi = FastMath.abs(coefficients[i]); if ((absAi - 1) != 0) { s.append(Double.toString(absAi)); s.append(' '); } s.append("x"); if (i > 1) { s.append('^'); s.append(Integer.toString(i)); } } } return s.toString(); } /** {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(coefficients); return result; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PolynomialFunction)) return false; PolynomialFunction other = (PolynomialFunction) obj; if (!Arrays.equals(coefficients, other.coefficients)) return false; return true; } } ././@LongLink100644 0 0 162 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNe100644 1750 1750 16717 11532241246 32631 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implements the representation of a real polynomial function in * Newton Form. For reference, see Elementary Numerical Analysis, * ISBN 0070124477, chapter 2. *

                        * The formula of polynomial in Newton form is * p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... + * a[n](x-c[0])(x-c[1])...(x-c[n-1]) * Note that the length of a[] is one more than the length of c[]

                        * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ * @since 1.2 */ public class PolynomialFunctionNewtonForm implements UnivariateRealFunction { /** * The coefficients of the polynomial, ordered by degree -- i.e. * coefficients[0] is the constant term and coefficients[n] is the * coefficient of x^n where n is the degree of the polynomial. */ private double coefficients[]; /** * Centers of the Newton polynomial. */ private final double c[]; /** * When all c[i] = 0, a[] becomes normal polynomial coefficients, * i.e. a[i] = coefficients[i]. */ private final double a[]; /** * Whether the polynomial coefficients are available. */ private boolean coefficientsComputed; /** * Construct a Newton polynomial with the given a[] and c[]. The order of * centers are important in that if c[] shuffle, then values of a[] would * completely change, not just a permutation of old a[]. *

                        * The constructor makes copy of the input arrays and assigns them.

                        * * @param a the coefficients in Newton form formula * @param c the centers * @throws IllegalArgumentException if input arrays are not valid */ public PolynomialFunctionNewtonForm(double a[], double c[]) throws IllegalArgumentException { verifyInputArray(a, c); this.a = new double[a.length]; this.c = new double[c.length]; System.arraycopy(a, 0, this.a, 0, a.length); System.arraycopy(c, 0, this.c, 0, c.length); coefficientsComputed = false; } /** * Calculate the function value at the given point. * * @param z the point at which the function value is to be computed * @return the function value * @throws FunctionEvaluationException if a runtime error occurs * @see UnivariateRealFunction#value(double) */ public double value(double z) throws FunctionEvaluationException { return evaluate(a, c, z); } /** * Returns the degree of the polynomial. * * @return the degree of the polynomial */ public int degree() { return c.length; } /** * Returns a copy of coefficients in Newton form formula. *

                        * Changes made to the returned copy will not affect the polynomial.

                        * * @return a fresh copy of coefficients in Newton form formula */ public double[] getNewtonCoefficients() { double[] out = new double[a.length]; System.arraycopy(a, 0, out, 0, a.length); return out; } /** * Returns a copy of the centers array. *

                        * Changes made to the returned copy will not affect the polynomial.

                        * * @return a fresh copy of the centers array */ public double[] getCenters() { double[] out = new double[c.length]; System.arraycopy(c, 0, out, 0, c.length); return out; } /** * Returns a copy of the coefficients array. *

                        * Changes made to the returned copy will not affect the polynomial.

                        * * @return a fresh copy of the coefficients array */ public double[] getCoefficients() { if (!coefficientsComputed) { computeCoefficients(); } double[] out = new double[coefficients.length]; System.arraycopy(coefficients, 0, out, 0, coefficients.length); return out; } /** * Evaluate the Newton polynomial using nested multiplication. It is * also called * Horner's Rule and takes O(N) time. * * @param a the coefficients in Newton form formula * @param c the centers * @param z the point at which the function value is to be computed * @return the function value * @throws FunctionEvaluationException if a runtime error occurs * @throws IllegalArgumentException if inputs are not valid */ public static double evaluate(double a[], double c[], double z) throws FunctionEvaluationException, IllegalArgumentException { verifyInputArray(a, c); int n = c.length; double value = a[n]; for (int i = n-1; i >= 0; i--) { value = a[i] + (z - c[i]) * value; } return value; } /** * Calculate the normal polynomial coefficients given the Newton form. * It also uses nested multiplication but takes O(N^2) time. */ protected void computeCoefficients() { final int n = degree(); coefficients = new double[n+1]; for (int i = 0; i <= n; i++) { coefficients[i] = 0.0; } coefficients[0] = a[n]; for (int i = n-1; i >= 0; i--) { for (int j = n-i; j > 0; j--) { coefficients[j] = coefficients[j-1] - c[i] * coefficients[j]; } coefficients[0] = a[i] - c[i] * coefficients[0]; } coefficientsComputed = true; } /** * Verifies that the input arrays are valid. *

                        * The centers must be distinct for interpolation purposes, but not * for general use. Thus it is not verified here.

                        * * @param a the coefficients in Newton form formula * @param c the centers * @throws IllegalArgumentException if not valid * @see org.apache.commons.math.analysis.interpolation.DividedDifferenceInterpolator#computeDividedDifference(double[], * double[]) */ protected static void verifyInputArray(double a[], double c[]) throws IllegalArgumentException { if (a.length < 1 || c.length < 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); } if (a.length != c.length + 1) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1, a.length, c.length); } } } ././@LongLink100644 0 0 164 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLa100644 1750 1750 25347 11532241246 32622 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import org.apache.commons.math.DuplicateSampleAbscissaException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the representation of a real polynomial function in * * Lagrange Form. For reference, see Introduction to Numerical * Analysis, ISBN 038795452X, chapter 2. *

                        * The approximated function should be smooth enough for Lagrange polynomial * to work well. Otherwise, consider using splines instead.

                        * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ * @since 1.2 */ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction { /** * The coefficients of the polynomial, ordered by degree -- i.e. * coefficients[0] is the constant term and coefficients[n] is the * coefficient of x^n where n is the degree of the polynomial. */ private double coefficients[]; /** * Interpolating points (abscissas). */ private final double x[]; /** * Function values at interpolating points. */ private final double y[]; /** * Whether the polynomial coefficients are available. */ private boolean coefficientsComputed; /** * Construct a Lagrange polynomial with the given abscissas and function * values. The order of interpolating points are not important. *

                        * The constructor makes copy of the input arrays and assigns them.

                        * * @param x interpolating points * @param y function values at interpolating points * @throws IllegalArgumentException if input arrays are not valid */ public PolynomialFunctionLagrangeForm(double x[], double y[]) throws IllegalArgumentException { verifyInterpolationArray(x, y); this.x = new double[x.length]; this.y = new double[y.length]; System.arraycopy(x, 0, this.x, 0, x.length); System.arraycopy(y, 0, this.y, 0, y.length); coefficientsComputed = false; } /** {@inheritDoc} */ public double value(double z) throws FunctionEvaluationException { try { return evaluate(x, y, z); } catch (DuplicateSampleAbscissaException e) { throw new FunctionEvaluationException(z, e.getSpecificPattern(), e.getGeneralPattern(), e.getArguments()); } } /** * Returns the degree of the polynomial. * * @return the degree of the polynomial */ public int degree() { return x.length - 1; } /** * Returns a copy of the interpolating points array. *

                        * Changes made to the returned copy will not affect the polynomial.

                        * * @return a fresh copy of the interpolating points array */ public double[] getInterpolatingPoints() { double[] out = new double[x.length]; System.arraycopy(x, 0, out, 0, x.length); return out; } /** * Returns a copy of the interpolating values array. *

                        * Changes made to the returned copy will not affect the polynomial.

                        * * @return a fresh copy of the interpolating values array */ public double[] getInterpolatingValues() { double[] out = new double[y.length]; System.arraycopy(y, 0, out, 0, y.length); return out; } /** * Returns a copy of the coefficients array. *

                        * Changes made to the returned copy will not affect the polynomial.

                        *

                        * Note that coefficients computation can be ill-conditioned. Use with caution * and only when it is necessary.

                        * * @return a fresh copy of the coefficients array */ public double[] getCoefficients() { if (!coefficientsComputed) { computeCoefficients(); } double[] out = new double[coefficients.length]; System.arraycopy(coefficients, 0, out, 0, coefficients.length); return out; } /** * Evaluate the Lagrange polynomial using * * Neville's Algorithm. It takes O(N^2) time. *

                        * This function is made public static so that users can call it directly * without instantiating PolynomialFunctionLagrangeForm object.

                        * * @param x the interpolating points array * @param y the interpolating values array * @param z the point at which the function value is to be computed * @return the function value * @throws DuplicateSampleAbscissaException if the sample has duplicate abscissas * @throws IllegalArgumentException if inputs are not valid */ public static double evaluate(double x[], double y[], double z) throws DuplicateSampleAbscissaException, IllegalArgumentException { verifyInterpolationArray(x, y); int nearest = 0; final int n = x.length; final double[] c = new double[n]; final double[] d = new double[n]; double min_dist = Double.POSITIVE_INFINITY; for (int i = 0; i < n; i++) { // initialize the difference arrays c[i] = y[i]; d[i] = y[i]; // find out the abscissa closest to z final double dist = FastMath.abs(z - x[i]); if (dist < min_dist) { nearest = i; min_dist = dist; } } // initial approximation to the function value at z double value = y[nearest]; for (int i = 1; i < n; i++) { for (int j = 0; j < n-i; j++) { final double tc = x[j] - z; final double td = x[i+j] - z; final double divider = x[j] - x[i+j]; if (divider == 0.0) { // This happens only when two abscissas are identical. throw new DuplicateSampleAbscissaException(x[i], i, i+j); } // update the difference arrays final double w = (c[j+1] - d[j]) / divider; c[j] = tc * w; d[j] = td * w; } // sum up the difference terms to get the final value if (nearest < 0.5*(n-i+1)) { value += c[nearest]; // fork down } else { nearest--; value += d[nearest]; // fork up } } return value; } /** * Calculate the coefficients of Lagrange polynomial from the * interpolation data. It takes O(N^2) time. *

                        * Note this computation can be ill-conditioned. Use with caution * and only when it is necessary.

                        * * @throws ArithmeticException if any abscissas coincide */ protected void computeCoefficients() throws ArithmeticException { final int n = degree() + 1; coefficients = new double[n]; for (int i = 0; i < n; i++) { coefficients[i] = 0.0; } // c[] are the coefficients of P(x) = (x-x[0])(x-x[1])...(x-x[n-1]) final double[] c = new double[n+1]; c[0] = 1.0; for (int i = 0; i < n; i++) { for (int j = i; j > 0; j--) { c[j] = c[j-1] - c[j] * x[i]; } c[0] *= -x[i]; c[i+1] = 1; } final double[] tc = new double[n]; for (int i = 0; i < n; i++) { // d = (x[i]-x[0])...(x[i]-x[i-1])(x[i]-x[i+1])...(x[i]-x[n-1]) double d = 1; for (int j = 0; j < n; j++) { if (i != j) { d *= x[i] - x[j]; } } if (d == 0.0) { // This happens only when two abscissas are identical. for (int k = 0; k < n; ++k) { if ((i != k) && (x[i] == x[k])) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO, i, k, x[i]); } } } final double t = y[i] / d; // Lagrange polynomial is the sum of n terms, each of which is a // polynomial of degree n-1. tc[] are the coefficients of the i-th // numerator Pi(x) = (x-x[0])...(x-x[i-1])(x-x[i+1])...(x-x[n-1]). tc[n-1] = c[n]; // actually c[n] = 1 coefficients[n-1] += t * tc[n-1]; for (int j = n-2; j >= 0; j--) { tc[j] = c[j+1] + tc[j+1] * x[i]; coefficients[j] += t * tc[j]; } } coefficientsComputed = true; } /** * Verifies that the interpolation arrays are valid. *

                        * The arrays features checked by this method are that both arrays have the * same length and this length is at least 2. *

                        *

                        * The interpolating points must be distinct. However it is not * verified here, it is checked in evaluate() and computeCoefficients(). *

                        * * @param x the interpolating points array * @param y the interpolating values array * @throws IllegalArgumentException if not valid * @see #evaluate(double[], double[], double) * @see #computeCoefficients() */ public static void verifyInterpolationArray(double x[], double y[]) throws IllegalArgumentException { if (x.length != y.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, y.length); } if (x.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2, x.length); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/package.html100644 1750 1750 2005 11532241246 31014 0ustarlucluc 0 0 Univariate real polynomials implementations, seen as differentiable univariate real functions. ././@LongLink100644 0 0 146 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.jav100644 1750 1750 26111 11532241246 32610 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import java.util.ArrayList; import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.util.FastMath; /** * A collection of static methods that operate on or return polynomials. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class PolynomialsUtils { /** Coefficients for Chebyshev polynomials. */ private static final ArrayList CHEBYSHEV_COEFFICIENTS; /** Coefficients for Hermite polynomials. */ private static final ArrayList HERMITE_COEFFICIENTS; /** Coefficients for Laguerre polynomials. */ private static final ArrayList LAGUERRE_COEFFICIENTS; /** Coefficients for Legendre polynomials. */ private static final ArrayList LEGENDRE_COEFFICIENTS; static { // initialize recurrence for Chebyshev polynomials // T0(X) = 1, T1(X) = 0 + 1 * X CHEBYSHEV_COEFFICIENTS = new ArrayList(); CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE); CHEBYSHEV_COEFFICIENTS.add(BigFraction.ZERO); CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE); // initialize recurrence for Hermite polynomials // H0(X) = 1, H1(X) = 0 + 2 * X HERMITE_COEFFICIENTS = new ArrayList(); HERMITE_COEFFICIENTS.add(BigFraction.ONE); HERMITE_COEFFICIENTS.add(BigFraction.ZERO); HERMITE_COEFFICIENTS.add(BigFraction.TWO); // initialize recurrence for Laguerre polynomials // L0(X) = 1, L1(X) = 1 - 1 * X LAGUERRE_COEFFICIENTS = new ArrayList(); LAGUERRE_COEFFICIENTS.add(BigFraction.ONE); LAGUERRE_COEFFICIENTS.add(BigFraction.ONE); LAGUERRE_COEFFICIENTS.add(BigFraction.MINUS_ONE); // initialize recurrence for Legendre polynomials // P0(X) = 1, P1(X) = 0 + 1 * X LEGENDRE_COEFFICIENTS = new ArrayList(); LEGENDRE_COEFFICIENTS.add(BigFraction.ONE); LEGENDRE_COEFFICIENTS.add(BigFraction.ZERO); LEGENDRE_COEFFICIENTS.add(BigFraction.ONE); } /** * Private constructor, to prevent instantiation. */ private PolynomialsUtils() { } /** * Create a Chebyshev polynomial of the first kind. *

                        Chebyshev * polynomials of the first kind are orthogonal polynomials. * They can be defined by the following recurrence relations: *

                             *  T0(X)   = 1
                             *  T1(X)   = X
                             *  Tk+1(X) = 2X Tk(X) - Tk-1(X)
                             * 

                        * @param degree degree of the polynomial * @return Chebyshev polynomial of specified degree */ public static PolynomialFunction createChebyshevPolynomial(final int degree) { return buildPolynomial(degree, CHEBYSHEV_COEFFICIENTS, new RecurrenceCoefficientsGenerator() { private final BigFraction[] coeffs = { BigFraction.ZERO, BigFraction.TWO, BigFraction.ONE }; /** {@inheritDoc} */ public BigFraction[] generate(int k) { return coeffs; } }); } /** * Create a Hermite polynomial. *

                        Hermite * polynomials are orthogonal polynomials. * They can be defined by the following recurrence relations: *

                             *  H0(X)   = 1
                             *  H1(X)   = 2X
                             *  Hk+1(X) = 2X Hk(X) - 2k Hk-1(X)
                             * 

                        * @param degree degree of the polynomial * @return Hermite polynomial of specified degree */ public static PolynomialFunction createHermitePolynomial(final int degree) { return buildPolynomial(degree, HERMITE_COEFFICIENTS, new RecurrenceCoefficientsGenerator() { /** {@inheritDoc} */ public BigFraction[] generate(int k) { return new BigFraction[] { BigFraction.ZERO, BigFraction.TWO, new BigFraction(2 * k)}; } }); } /** * Create a Laguerre polynomial. *

                        Laguerre * polynomials are orthogonal polynomials. * They can be defined by the following recurrence relations: *

                             *        L0(X)   = 1
                             *        L1(X)   = 1 - X
                             *  (k+1) Lk+1(X) = (2k + 1 - X) Lk(X) - k Lk-1(X)
                             * 

                        * @param degree degree of the polynomial * @return Laguerre polynomial of specified degree */ public static PolynomialFunction createLaguerrePolynomial(final int degree) { return buildPolynomial(degree, LAGUERRE_COEFFICIENTS, new RecurrenceCoefficientsGenerator() { /** {@inheritDoc} */ public BigFraction[] generate(int k) { final int kP1 = k + 1; return new BigFraction[] { new BigFraction(2 * k + 1, kP1), new BigFraction(-1, kP1), new BigFraction(k, kP1)}; } }); } /** * Create a Legendre polynomial. *

                        Legendre * polynomials are orthogonal polynomials. * They can be defined by the following recurrence relations: *

                             *        P0(X)   = 1
                             *        P1(X)   = X
                             *  (k+1) Pk+1(X) = (2k+1) X Pk(X) - k Pk-1(X)
                             * 

                        * @param degree degree of the polynomial * @return Legendre polynomial of specified degree */ public static PolynomialFunction createLegendrePolynomial(final int degree) { return buildPolynomial(degree, LEGENDRE_COEFFICIENTS, new RecurrenceCoefficientsGenerator() { /** {@inheritDoc} */ public BigFraction[] generate(int k) { final int kP1 = k + 1; return new BigFraction[] { BigFraction.ZERO, new BigFraction(k + kP1, kP1), new BigFraction(k, kP1)}; } }); } /** Get the coefficients array for a given degree. * @param degree degree of the polynomial * @param coefficients list where the computed coefficients are stored * @param generator recurrence coefficients generator * @return coefficients array */ private static PolynomialFunction buildPolynomial(final int degree, final ArrayList coefficients, final RecurrenceCoefficientsGenerator generator) { final int maxDegree = (int) FastMath.floor(FastMath.sqrt(2 * coefficients.size())) - 1; synchronized (PolynomialsUtils.class) { if (degree > maxDegree) { computeUpToDegree(degree, maxDegree, generator, coefficients); } } // coefficient for polynomial 0 is l [0] // coefficients for polynomial 1 are l [1] ... l [2] (degrees 0 ... 1) // coefficients for polynomial 2 are l [3] ... l [5] (degrees 0 ... 2) // coefficients for polynomial 3 are l [6] ... l [9] (degrees 0 ... 3) // coefficients for polynomial 4 are l[10] ... l[14] (degrees 0 ... 4) // coefficients for polynomial 5 are l[15] ... l[20] (degrees 0 ... 5) // coefficients for polynomial 6 are l[21] ... l[27] (degrees 0 ... 6) // ... final int start = degree * (degree + 1) / 2; final double[] a = new double[degree + 1]; for (int i = 0; i <= degree; ++i) { a[i] = coefficients.get(start + i).doubleValue(); } // build the polynomial return new PolynomialFunction(a); } /** Compute polynomial coefficients up to a given degree. * @param degree maximal degree * @param maxDegree current maximal degree * @param generator recurrence coefficients generator * @param coefficients list where the computed coefficients should be appended */ private static void computeUpToDegree(final int degree, final int maxDegree, final RecurrenceCoefficientsGenerator generator, final ArrayList coefficients) { int startK = (maxDegree - 1) * maxDegree / 2; for (int k = maxDegree; k < degree; ++k) { // start indices of two previous polynomials Pk(X) and Pk-1(X) int startKm1 = startK; startK += k; // Pk+1(X) = (a[0] + a[1] X) Pk(X) - a[2] Pk-1(X) BigFraction[] ai = generator.generate(k); BigFraction ck = coefficients.get(startK); BigFraction ckm1 = coefficients.get(startKm1); // degree 0 coefficient coefficients.add(ck.multiply(ai[0]).subtract(ckm1.multiply(ai[2]))); // degree 1 to degree k-1 coefficients for (int i = 1; i < k; ++i) { final BigFraction ckPrev = ck; ck = coefficients.get(startK + i); ckm1 = coefficients.get(startKm1 + i); coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])).subtract(ckm1.multiply(ai[2]))); } // degree k coefficient final BigFraction ckPrev = ck; ck = coefficients.get(startK + k); coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1]))); // degree k+1 coefficient coefficients.add(ck.multiply(ai[1])); } } /** Interface for recurrence coefficients generation. */ private static interface RecurrenceCoefficientsGenerator { /** * Generate recurrence coefficients. * @param k highest degree of the polynomials used in the recurrence * @return an array of three coefficients such that * Pk+1(X) = (a[0] + a[1] X) Pk(X) - a[2] Pk-1(X) */ BigFraction[] generate(int k); } } ././@LongLink100644 0 0 156 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunc100644 1750 1750 21222 11532241246 32612 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.polynomials; import java.util.Arrays; import org.apache.commons.math.ArgumentOutsideDomainException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Represents a polynomial spline function. *

                        * A polynomial spline function consists of a set of * interpolating polynomials and an ascending array of domain * knot points, determining the intervals over which the spline function * is defined by the constituent polynomials. The polynomials are assumed to * have been computed to match the values of another function at the knot * points. The value consistency constraints are not currently enforced by * PolynomialSplineFunction itself, but are assumed to hold among * the polynomials and knot points passed to the constructor.

                        *

                        * N.B.: The polynomials in the polynomials property must be * centered on the knot points to compute the spline function values. * See below.

                        *

                        * The domain of the polynomial spline function is * [smallest knot, largest knot]. Attempts to evaluate the * function at values outside of this range generate IllegalArgumentExceptions. *

                        *

                        * The value of the polynomial spline function for an argument x * is computed as follows: *

                          *
                        1. The knot array is searched to find the segment to which x * belongs. If x is less than the smallest knot point or greater * than the largest one, an IllegalArgumentException * is thrown.
                        2. *
                        3. Let j be the index of the largest knot point that is less * than or equal to x. The value returned is
                          * polynomials[j](x - knot[j])

                        * * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $ */ public class PolynomialSplineFunction implements DifferentiableUnivariateRealFunction { /** Spline segment interval delimiters (knots). Size is n+1 for n segments. */ private final double knots[]; /** * The polynomial functions that make up the spline. The first element * determines the value of the spline over the first subinterval, the * second over the second, etc. Spline function values are determined by * evaluating these functions at (x - knot[i]) where i is the * knot segment to which x belongs. */ private final PolynomialFunction polynomials[]; /** * Number of spline segments = number of polynomials * = number of partition points - 1 */ private final int n; /** * Construct a polynomial spline function with the given segment delimiters * and interpolating polynomials. *

                        * The constructor copies both arrays and assigns the copies to the knots * and polynomials properties, respectively.

                        * * @param knots spline segment interval delimiters * @param polynomials polynomial functions that make up the spline * @throws NullPointerException if either of the input arrays is null * @throws IllegalArgumentException if knots has length less than 2, * polynomials.length != knots.length - 1 , or the knots array * is not strictly increasing. * */ public PolynomialSplineFunction(double knots[], PolynomialFunction polynomials[]) { if (knots.length < 2) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION, 2, knots.length); } if (knots.length - 1 != polynomials.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS, polynomials.length, knots.length); } if (!isStrictlyIncreasing(knots)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_STRICTLY_INCREASING_KNOT_VALUES); } this.n = knots.length -1; this.knots = new double[n + 1]; System.arraycopy(knots, 0, this.knots, 0, n + 1); this.polynomials = new PolynomialFunction[n]; System.arraycopy(polynomials, 0, this.polynomials, 0, n); } /** * Compute the value for the function. * See {@link PolynomialSplineFunction} for details on the algorithm for * computing the value of the function.

                        * * @param v the point for which the function value should be computed * @return the value * @throws ArgumentOutsideDomainException if v is outside of the domain of * of the spline function (less than the smallest knot point or greater * than the largest knot point) */ public double value(double v) throws ArgumentOutsideDomainException { if (v < knots[0] || v > knots[n]) { throw new ArgumentOutsideDomainException(v, knots[0], knots[n]); } int i = Arrays.binarySearch(knots, v); if (i < 0) { i = -i - 2; } //This will handle the case where v is the last knot value //There are only n-1 polynomials, so if v is the last knot //then we will use the last polynomial to calculate the value. if ( i >= polynomials.length ) { i--; } return polynomials[i].value(v - knots[i]); } /** * Returns the derivative of the polynomial spline function as a UnivariateRealFunction * @return the derivative function */ public UnivariateRealFunction derivative() { return polynomialSplineDerivative(); } /** * Returns the derivative of the polynomial spline function as a PolynomialSplineFunction * * @return the derivative function */ public PolynomialSplineFunction polynomialSplineDerivative() { PolynomialFunction derivativePolynomials[] = new PolynomialFunction[n]; for (int i = 0; i < n; i++) { derivativePolynomials[i] = polynomials[i].polynomialDerivative(); } return new PolynomialSplineFunction(knots, derivativePolynomials); } /** * Returns the number of spline segments = the number of polynomials * = the number of knot points - 1. * * @return the number of spline segments */ public int getN() { return n; } /** * Returns a copy of the interpolating polynomials array. *

                        * Returns a fresh copy of the array. Changes made to the copy will * not affect the polynomials property.

                        * * @return the interpolating polynomials */ public PolynomialFunction[] getPolynomials() { PolynomialFunction p[] = new PolynomialFunction[n]; System.arraycopy(polynomials, 0, p, 0, n); return p; } /** * Returns an array copy of the knot points. *

                        * Returns a fresh copy of the array. Changes made to the copy * will not affect the knots property.

                        * * @return the knot points */ public double[] getKnots() { double out[] = new double[n + 1]; System.arraycopy(knots, 0, out, 0, n + 1); return out; } /** * Determines if the given array is ordered in a strictly increasing * fashion. * * @param x the array to examine. * @return true if the elements in x are ordered * in a stricly increasing manner. false, otherwise. */ private static boolean isStrictlyIncreasing(double[] x) { for (int i = 1; i < x.length; ++i) { if (x[i - 1] >= x[i]) { return false; } } return true; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/package.html100644 1750 1750 3142 11532241246 26451 0ustarlucluc 0 0

                        Parent package for common numerical analysis procedures, including root finding, function interpolation and integration. Note that the optimization (i.e. minimization and maximization) is a huge separate top package, despite it also operate on functions as defined by this top-level package.

                        Functions interfaces are intended to be implemented by user code to represent their domain problems. The algorithms provided by the library will then operate on these function to find their roots, or integrate them, or ... Functions can be multivariate or univariate, real vectorial or matrix valued, and they can be differentiable or not.

                        ././@LongLink100644 0 0 160 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFu100644 1750 1750 2445 11532241246 32533 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Extension of {@link UnivariateMatrixFunction} representing a differentiable univariate matrix function. * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public interface DifferentiableUnivariateMatrixFunction extends UnivariateMatrixFunction { /** * Returns the derivative of the function * * @return the derivative function */ UnivariateMatrixFunction derivative(); } ././@LongLink100644 0 0 163 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateVectoria100644 1750 1750 2464 11532241246 32551 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Extension of {@link UnivariateVectorialFunction} representing a differentiable univariate vectorial function. * * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public interface DifferentiableUnivariateVectorialFunction extends UnivariateVectorialFunction { /** * Returns the derivative of the function * * @return the derivative function */ UnivariateVectorialFunction derivative(); } ././@LongLink100644 0 0 165 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateVector100644 1750 1750 2451 11532241246 32572 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; /** * Extension of {@link MultivariateVectorialFunction} representing a differentiable * multivariate vectorial function. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * @since 2.0 */ public interface DifferentiableMultivariateVectorialFunction extends MultivariateVectorialFunction { /** * Returns the jacobian function. * @return the jacobian function */ MultivariateMatrixFunction jacobian(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java100644 1750 1750 2761 11532241246 31261 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a bivariate real function. * * @since 2.1 * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ */ public interface BivariateRealFunction { /** * Compute the value for the function. * * @param x Abscissa for which the function value should be computed. * @param y Ordinate for which the function value should be computed. * @return the value. * @throws FunctionEvaluationException if the function evaluation fails. */ double value(double x, double y) throws FunctionEvaluationException; } ././@LongLink100644 0 0 155 11532242444 10255 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegra100644 1750 1750 20516 11532241245 32523 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Legendre-Gauss quadrature formula. *

                        * Legendre-Gauss integrators are efficient integrators that can * accurately integrate functions with few functions evaluations. A * Legendre-Gauss integrator using an n-points quadrature formula can * integrate exactly 2n-1 degree polynomials. *

                        *

                        * These integrators evaluate the function on n carefully chosen * abscissas in each step interval (mapped to the canonical [-1 1] interval). * The evaluation abscissas are not evenly spaced and none of them are * at the interval endpoints. This implies the function integrated can be * undefined at integration interval endpoints. *

                        *

                        * The evaluation abscissas xi are the roots of the degree n * Legendre polynomial. The weights ai of the quadrature formula * integrals from -1 to +1 ∫ Li2 where Li (x) = * ∏ (x-xk)/(xi-xk) for k != i. *

                        *

                        * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class LegendreGaussIntegrator extends UnivariateRealIntegratorImpl { /** Abscissas for the 2 points method. */ private static final double[] ABSCISSAS_2 = { -1.0 / FastMath.sqrt(3.0), 1.0 / FastMath.sqrt(3.0) }; /** Weights for the 2 points method. */ private static final double[] WEIGHTS_2 = { 1.0, 1.0 }; /** Abscissas for the 3 points method. */ private static final double[] ABSCISSAS_3 = { -FastMath.sqrt(0.6), 0.0, FastMath.sqrt(0.6) }; /** Weights for the 3 points method. */ private static final double[] WEIGHTS_3 = { 5.0 / 9.0, 8.0 / 9.0, 5.0 / 9.0 }; /** Abscissas for the 4 points method. */ private static final double[] ABSCISSAS_4 = { -FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0), -FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0), FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0), FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0) }; /** Weights for the 4 points method. */ private static final double[] WEIGHTS_4 = { (90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0, (90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0, (90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0, (90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0 }; /** Abscissas for the 5 points method. */ private static final double[] ABSCISSAS_5 = { -FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0), -FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0), 0.0, FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0), FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0) }; /** Weights for the 5 points method. */ private static final double[] WEIGHTS_5 = { (322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0, (322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0, 128.0 / 225.0, (322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0, (322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0 }; /** Abscissas for the current method. */ private final double[] abscissas; /** Weights for the current method. */ private final double[] weights; /** * Build a Legendre-Gauss integrator. * @param n number of points desired (must be between 2 and 5 inclusive) * @param defaultMaximalIterationCount maximum number of iterations * @exception IllegalArgumentException if the number of points is not * in the supported range */ public LegendreGaussIntegrator(final int n, final int defaultMaximalIterationCount) throws IllegalArgumentException { super(defaultMaximalIterationCount); switch(n) { case 2 : abscissas = ABSCISSAS_2; weights = WEIGHTS_2; break; case 3 : abscissas = ABSCISSAS_3; weights = WEIGHTS_3; break; case 4 : abscissas = ABSCISSAS_4; weights = WEIGHTS_4; break; case 5 : abscissas = ABSCISSAS_5; weights = WEIGHTS_5; break; default : throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED, n, 2, 5); } } /** {@inheritDoc} */ @Deprecated public double integrate(final double min, final double max) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { return integrate(f, min, max); } /** {@inheritDoc} */ public double integrate(final UnivariateRealFunction f, final double min, final double max) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { clearResult(); verifyInterval(min, max); verifyIterationCount(); // compute first estimate with a single step double oldt = stage(f, min, max, 1); int n = 2; for (int i = 0; i < maximalIterationCount; ++i) { // improve integral with a larger number of steps final double t = stage(f, min, max, n); // estimate error final double delta = FastMath.abs(t - oldt); final double limit = FastMath.max(absoluteAccuracy, relativeAccuracy * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5); // check convergence if ((i + 1 >= minimalIterationCount) && (delta <= limit)) { setResult(t, i); return result; } // prepare next iteration double ratio = FastMath.min(4, FastMath.pow(delta / limit, 0.5 / abscissas.length)); n = FastMath.max((int) (ratio * n), n + 1); oldt = t; } throw new MaxIterationsExceededException(maximalIterationCount); } /** * Compute the n-th stage integral. * @param f the integrand function * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n number of steps * @return the value of n-th stage integral * @throws FunctionEvaluationException if an error occurs evaluating the * function */ private double stage(final UnivariateRealFunction f, final double min, final double max, final int n) throws FunctionEvaluationException { // set up the step for the current stage final double step = (max - min) / n; final double halfStep = step / 2.0; // integrate over all elementary steps double midPoint = min + halfStep; double sum = 0.0; for (int i = 0; i < n; ++i) { for (int j = 0; j < abscissas.length; ++j) { sum += weights[j] * f.value(midPoint + halfStep * abscissas[j]); } midPoint += step; } return halfStep * sum; } } ././@LongLink100644 0 0 162 11532242444 10253 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegr100644 1750 1750 14434 11532241245 32547 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.ConvergingAlgorithmImpl; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; /** * Provide a default implementation for several generic functions. * * @version $Revision: 1072409 $ $Date: 2011-02-19 19:50:36 +0100 (sam. 19 févr. 2011) $ * @since 1.2 */ public abstract class UnivariateRealIntegratorImpl extends ConvergingAlgorithmImpl implements UnivariateRealIntegrator { /** Serializable version identifier. */ private static final long serialVersionUID = 6248808456637441533L; /** minimum number of iterations */ protected int minimalIterationCount; /** default minimum number of iterations */ protected int defaultMinimalIterationCount; /** indicates whether an integral has been computed */ protected boolean resultComputed = false; /** the last computed integral */ protected double result; /** * The integrand function. * * @deprecated as of 2.0 the integrand function is passed as an argument * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ @Deprecated protected UnivariateRealFunction f; /** * Construct an integrator with given iteration count and accuracy. * * @param f the integrand function * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the iteration * limits are not valid * @deprecated as of 2.0 the integrand function is passed as an argument * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ @Deprecated protected UnivariateRealIntegratorImpl(final UnivariateRealFunction f, final int defaultMaximalIterationCount) throws IllegalArgumentException { super(defaultMaximalIterationCount, 1.0e-15); if (f == null) { throw new NullArgumentException(LocalizedFormats.FUNCTION); } this.f = f; // parameters that are problem specific setRelativeAccuracy(1.0e-6); this.defaultMinimalIterationCount = 3; this.minimalIterationCount = defaultMinimalIterationCount; verifyIterationCount(); } /** * Construct an integrator with given iteration count and accuracy. * * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the iteration * limits are not valid */ protected UnivariateRealIntegratorImpl(final int defaultMaximalIterationCount) throws IllegalArgumentException { super(defaultMaximalIterationCount, 1.0e-15); // parameters that are problem specific setRelativeAccuracy(1.0e-6); this.defaultMinimalIterationCount = 3; this.minimalIterationCount = defaultMinimalIterationCount; verifyIterationCount(); } /** * Access the last computed integral. * * @return the last computed integral * @throws IllegalStateException if no integral has been computed */ public double getResult() throws IllegalStateException { if (resultComputed) { return result; } else { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE); } } /** * Convenience function for implementations. * * @param newResult the result to set * @param iterationCount the iteration count to set */ protected final void setResult(double newResult, int iterationCount) { this.result = newResult; this.iterationCount = iterationCount; this.resultComputed = true; } /** * Convenience function for implementations. */ protected final void clearResult() { this.iterationCount = 0; this.resultComputed = false; } /** {@inheritDoc} */ public void setMinimalIterationCount(int count) { minimalIterationCount = count; } /** {@inheritDoc} */ public int getMinimalIterationCount() { return minimalIterationCount; } /** {@inheritDoc} */ public void resetMinimalIterationCount() { minimalIterationCount = defaultMinimalIterationCount; } /** * Verifies that the endpoints specify an interval. * * @param lower lower endpoint * @param upper upper endpoint * @throws IllegalArgumentException if not interval */ protected void verifyInterval(double lower, double upper) throws IllegalArgumentException { if (lower >= upper) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL, lower, upper); } } /** * Verifies that the upper and lower limits of iterations are valid. * * @throws IllegalArgumentException if not valid */ protected void verifyIterationCount() throws IllegalArgumentException { if ((minimalIterationCount <= 0) || (maximalIterationCount <= minimalIterationCount)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_ITERATIONS_LIMITS, minimalIterationCount, maximalIterationCount); } } } ././@LongLink100644 0 0 147 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/RombergIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/RombergIntegrator.ja100644 1750 1750 11173 11532241245 32505 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Romberg Algorithm for integration of real univariate functions. For * reference, see Introduction to Numerical Analysis, ISBN 038795452X, * chapter 3. *

                        * Romberg integration employs k successive refinements of the trapezoid * rule to remove error terms less than order O(N^(-2k)). Simpson's rule * is a special case of k = 2.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class RombergIntegrator extends UnivariateRealIntegratorImpl { /** * Construct an integrator for the given function. * * @param f function to integrate * @deprecated as of 2.0 the integrand function is passed as an argument * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ @Deprecated public RombergIntegrator(UnivariateRealFunction f) { super(f, 32); } /** * Construct an integrator. */ public RombergIntegrator() { super(32); } /** {@inheritDoc} */ @Deprecated public double integrate(final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { return integrate(f, min, max); } /** {@inheritDoc} */ public double integrate(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { final int m = maximalIterationCount + 1; double previousRow[] = new double[m]; double currentRow[] = new double[m]; clearResult(); verifyInterval(min, max); verifyIterationCount(); TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); currentRow[0] = qtrap.stage(f, min, max, 0); double olds = currentRow[0]; for (int i = 1; i <= maximalIterationCount; ++i) { // switch rows final double[] tmpRow = previousRow; previousRow = currentRow; currentRow = tmpRow; currentRow[0] = qtrap.stage(f, min, max, i); for (int j = 1; j <= i; j++) { // Richardson extrapolation coefficient final double r = (1L << (2 * j)) - 1; final double tIJm1 = currentRow[j - 1]; currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r; } final double s = currentRow[i]; if (i >= minimalIterationCount) { final double delta = FastMath.abs(s - olds); final double rLimit = relativeAccuracy * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5; if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { setResult(s, i); return result; } } olds = s; } throw new MaxIterationsExceededException(maximalIterationCount); } /** {@inheritDoc} */ @Override protected void verifyIterationCount() throws IllegalArgumentException { super.verifyIterationCount(); // at most 32 bisection refinements due to higher order divider if (maximalIterationCount > 32) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_ITERATIONS_LIMITS, 0, 32); } } } ././@LongLink100644 0 0 156 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegr100644 1750 1750 10155 11532241245 32543 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ConvergingAlgorithm; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface for univariate real integration algorithms. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public interface UnivariateRealIntegrator extends ConvergingAlgorithm { /** * Set the lower limit for the number of iterations. *

                        * Minimal iteration is needed to avoid false early convergence, e.g. * the sample points happen to be zeroes of the function. Users can * use the default value or choose one that they see as appropriate.

                        *

                        * A ConvergenceException will be thrown if this number * is not met.

                        * * @param count minimum number of iterations */ void setMinimalIterationCount(int count); /** * Get the lower limit for the number of iterations. * * @return the actual lower limit */ int getMinimalIterationCount(); /** * Reset the lower limit for the number of iterations to the default. *

                        * The default value is supplied by the implementation.

                        * * @see #setMinimalIterationCount(int) */ void resetMinimalIterationCount(); /** * Integrate the function in the given interval. * * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the value of integral * @throws ConvergenceException if the maximum iteration count is exceeded * or the integrator detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the * function * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the integrator * @deprecated replaced by {@link #integrate(UnivariateRealFunction, double, double)} * since 2.0 */ @Deprecated double integrate(double min, double max) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; /** * Integrate the function in the given interval. * * @param f the integrand function * @param min the lower bound for the interval * @param max the upper bound for the interval * @return the value of integral * @throws ConvergenceException if the maximum iteration count is exceeded * or the integrator detects convergence problems otherwise * @throws FunctionEvaluationException if an error occurs evaluating the function * @throws IllegalArgumentException if min > max or the endpoints do not * satisfy the requirements specified by the integrator */ double integrate(UnivariateRealFunction f, double min, double max) throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; /** * Get the result of the last run of the integrator. * * @return the last result * @throws IllegalStateException if there is no result available, either * because no result was yet computed or the last attempt failed */ double getResult() throws IllegalStateException; } ././@LongLink100644 0 0 147 11532242444 10256 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.ja100644 1750 1750 10424 11532241245 32536 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Simpson's Rule for integration of real univariate functions. For * reference, see Introduction to Numerical Analysis, ISBN 038795452X, * chapter 3. *

                        * This implementation employs basic trapezoid rule as building blocks to * calculate the Simpson's rule of alternating 2/3 and 4/3.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class SimpsonIntegrator extends UnivariateRealIntegratorImpl { /** * Construct an integrator for the given function. * * @param f function to integrate * @deprecated as of 2.0 the integrand function is passed as an argument * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ @Deprecated public SimpsonIntegrator(UnivariateRealFunction f) { super(f, 64); } /** * Construct an integrator. */ public SimpsonIntegrator() { super(64); } /** {@inheritDoc} */ @Deprecated public double integrate(final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { return integrate(f, min, max); } /** {@inheritDoc} */ public double integrate(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { clearResult(); verifyInterval(min, max); verifyIterationCount(); TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); if (minimalIterationCount == 1) { final double s = (4 * qtrap.stage(f, min, max, 1) - qtrap.stage(f, min, max, 0)) / 3.0; setResult(s, 1); return result; } // Simpson's rule requires at least two trapezoid stages. double olds = 0; double oldt = qtrap.stage(f, min, max, 0); for (int i = 1; i <= maximalIterationCount; ++i) { final double t = qtrap.stage(f, min, max, i); final double s = (4 * t - oldt) / 3.0; if (i >= minimalIterationCount) { final double delta = FastMath.abs(s - olds); final double rLimit = relativeAccuracy * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5; if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { setResult(s, i); return result; } } olds = s; oldt = t; } throw new MaxIterationsExceededException(maximalIterationCount); } /** {@inheritDoc} */ @Override protected void verifyIterationCount() throws IllegalArgumentException { super.verifyIterationCount(); // at most 64 bisection refinements if (maximalIterationCount > 64) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_ITERATIONS_LIMITS, 0, 64); } } } ././@LongLink100644 0 0 151 11532242444 10251 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.100644 1750 1750 12601 11532241245 32533 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis.integration; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Trapezoidal Rule for integration of real univariate functions. For * reference, see Introduction to Numerical Analysis, ISBN 038795452X, * chapter 3. *

                        * The function should be integrable.

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class TrapezoidIntegrator extends UnivariateRealIntegratorImpl { /** Intermediate result. */ private double s; /** * Construct an integrator for the given function. * * @param f function to integrate * @deprecated as of 2.0 the integrand function is passed as an argument * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ @Deprecated public TrapezoidIntegrator(UnivariateRealFunction f) { super(f, 64); } /** * Construct an integrator. */ public TrapezoidIntegrator() { super(64); } /** * Compute the n-th stage integral of trapezoid rule. This function * should only be called by API integrate() in the package. * To save time it does not verify arguments - caller does. *

                        * The interval is divided equally into 2^n sections rather than an * arbitrary m sections because this configuration can best utilize the * alrealy computed values.

                        * * @param f the integrand function * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the stage of 1/2 refinement, n = 0 is no refinement * @return the value of n-th stage integral * @throws FunctionEvaluationException if an error occurs evaluating the function */ double stage(final UnivariateRealFunction f, final double min, final double max, final int n) throws FunctionEvaluationException { if (n == 0) { s = 0.5 * (max - min) * (f.value(min) + f.value(max)); return s; } else { final long np = 1L << (n-1); // number of new points in this stage double sum = 0; final double spacing = (max - min) / np; // spacing between adjacent new points double x = min + 0.5 * spacing; // the first new point for (long i = 0; i < np; i++) { sum += f.value(x); x += spacing; } // add the new sum to previously calculated result s = 0.5 * (s + sum * spacing); return s; } } /** {@inheritDoc} */ @Deprecated public double integrate(final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { return integrate(f, min, max); } /** {@inheritDoc} */ public double integrate(final UnivariateRealFunction f, final double min, final double max) throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { clearResult(); verifyInterval(min, max); verifyIterationCount(); double oldt = stage(f, min, max, 0); for (int i = 1; i <= maximalIterationCount; ++i) { final double t = stage(f, min, max, i); if (i >= minimalIterationCount) { final double delta = FastMath.abs(t - oldt); final double rLimit = relativeAccuracy * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5; if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { setResult(t, i); return result; } } oldt = t; } throw new MaxIterationsExceededException(maximalIterationCount); } /** {@inheritDoc} */ @Override protected void verifyIterationCount() throws IllegalArgumentException { super.verifyIterationCount(); // at most 64 bisection refinements if (maximalIterationCount > 64) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_ITERATIONS_LIMITS, 0, 64); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/integration/package.html100644 1750 1750 1756 11532241245 31004 0ustarlucluc 0 0 Numerical integration (quadrature) algorithms for univariate real functions. commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/MultivariateMatrixFunction.java100644 1750 1750 3060 11532241246 32373 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a multivariate matrix function. * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $ * @since 2.0 */ public interface MultivariateMatrixFunction { /** * Compute the value for the function at the given point. * @param point point at which the function must be evaluated * @return function value for the given point * @exception FunctionEvaluationException if the function evaluation fails * @exception IllegalArgumentException if points dimension is wrong */ double[][] value(double[] point) throws FunctionEvaluationException, IllegalArgumentException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/UnivariateMatrixFunction.java100644 1750 1750 2626 11532241246 32043 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a univariate matrix function. * * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $ * @since 2.0 */ public interface UnivariateMatrixFunction { /** * Compute the value for the function. * @param x the point for which the function value should be computed * @return the value * @throws FunctionEvaluationException if the function evaluation fails */ double[][] value(double x) throws FunctionEvaluationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java100644 1750 1750 43537 11532241246 30661 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.util.FastMath; /** * Base class for {@link UnivariateRealFunction} that can be composed with other functions. * * @since 2.1 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public abstract class ComposableFunction implements UnivariateRealFunction { /** The constant function always returning 0. */ public static final ComposableFunction ZERO = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return 0; } }; /** The constant function always returning 1. */ public static final ComposableFunction ONE = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return 1; } }; /** The identity function. */ public static final ComposableFunction IDENTITY = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return d; } }; /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction ABS = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.abs(d); } }; /** The - operator wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction NEGATE = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return -d; } }; /** The invert operator wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction INVERT = new ComposableFunction () { /** {@inheritDoc} */ @Override public double value(double d){ return 1/d; } }; /** The {@code FastMath.sin} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction SIN = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.sin(d); } }; /** The {@code FastMath.sqrt} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction SQRT = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.sqrt(d); } }; /** The {@code FastMath.sinh} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction SINH = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.sinh(d); } }; /** The {@code FastMath.exp} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction EXP = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.exp(d); } }; /** The {@code FastMath.expm1} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction EXPM1 = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.expm1(d); } }; /** The {@code FastMath.asin} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction ASIN = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.asin(d); } }; /** The {@code FastMath.atan} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction ATAN = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.atan(d); } }; /** The {@code FastMath.tan} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction TAN = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.tan(d); } }; /** The {@code FastMath.tanh} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction TANH = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.tanh(d); } }; /** The {@code FastMath.cbrt} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction CBRT = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.cbrt(d); } }; /** The {@code FastMath.ceil} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction CEIL = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.ceil(d); } }; /** The {@code FastMath.floor} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction FLOOR = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.floor(d); } }; /** The {@code FastMath.log} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction LOG = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.log(d); } }; /** The {@code FastMath.log10} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction LOG10 = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.log10(d); } }; /** The {@code FastMath.log1p} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction LOG1P = new ComposableFunction () { @Override public double value(double d){ return FastMath.log1p(d); } }; /** The {@code FastMath.cos} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction COS = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.cos(d); } }; /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction ACOS = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.acos(d); } }; /** The {@code FastMath.cosh} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction COSH = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.cosh(d); } }; /** The {@code FastMath.rint} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction RINT = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.rint(d); } }; /** The {@code FastMath.signum} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction SIGNUM = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.signum(d); } }; /** The {@code FastMath.ulp} method wrapped as a {@link ComposableFunction}. */ public static final ComposableFunction ULP = new ComposableFunction() { /** {@inheritDoc} */ @Override public double value(double d) { return FastMath.ulp(d); } }; /** Precompose the instance with another function. *

                        * The composed function h created by {@code h = g.of(f)} is such * that {@code h.value(x) == g.value(f.value(x))} for all x. *

                        * @param f function to compose with * @return a new function which computes {@code this.value(f.value(x))} * @see #postCompose(UnivariateRealFunction) */ public ComposableFunction of(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(f.value(x)); } }; } /** Postcompose the instance with another function. *

                        * The composed function h created by {@code h = g.postCompose(f)} is such * that {@code h.value(x) == f.value(g.value(x))} for all x. *

                        * @param f function to compose with * @return a new function which computes {@code f.value(this.value(x))} * @see #of(UnivariateRealFunction) */ public ComposableFunction postCompose(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return f.value(ComposableFunction.this.value(x)); } }; } /** * Return a function combining the instance and another function. *

                        * The function h created by {@code h = g.combine(f, combiner)} is such that * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x. *

                        * @param f function to combine with the instance * @param combiner bivariate function used for combining * @return a new function which computes {@code combine.value(this.value(x), f.value(x))} */ public ComposableFunction combine(final UnivariateRealFunction f, final BivariateRealFunction combiner) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return combiner.value(ComposableFunction.this.value(x), f.value(x)); } }; } /** * Return a function adding the instance and another function. * @param f function to combine with the instance * @return a new function which computes {@code this.value(x) + f.value(x)} */ public ComposableFunction add(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) + f.value(x); } }; } /** * Return a function adding a constant term to the instance. * @param a term to add * @return a new function which computes {@code this.value(x) + a} */ public ComposableFunction add(final double a) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) + a; } }; } /** * Return a function subtracting another function from the instance. * @param f function to combine with the instance * @return a new function which computes {@code this.value(x) - f.value(x)} */ public ComposableFunction subtract(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) - f.value(x); } }; } /** * Return a function multiplying the instance and another function. * @param f function to combine with the instance * @return a new function which computes {@code this.value(x) * f.value(x)} */ public ComposableFunction multiply(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) * f.value(x); } }; } /** * Return a function scaling the instance by a constant factor. * @param scaleFactor constant scaling factor * @return a new function which computes {@code this.value(x) * scaleFactor} */ public ComposableFunction multiply(final double scaleFactor) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) * scaleFactor; } }; } /** * Return a function dividing the instance by another function. * @param f function to combine with the instance * @return a new function which computes {@code this.value(x) / f.value(x)} */ public ComposableFunction divide(final UnivariateRealFunction f) { return new ComposableFunction() { @Override /** {@inheritDoc} */ public double value(double x) throws FunctionEvaluationException { return ComposableFunction.this.value(x) / f.value(x); } }; } /** * Generates a function that iteratively apply instance function on all * elements of an array. *

                        * The generated function behaves as follows: *

                          *
                        • initialize result = initialValue
                        • *
                        • iterate: {@code result = combiner.value(result, * this.value(nextMultivariateEntry));}
                        • *
                        • return result
                        • *
                        *

                        * @param combiner combiner to use between entries * @param initialValue initial value to use before first entry * @return a new function that iteratively apply instance function on all * elements of an array. */ public MultivariateRealFunction asCollector(final BivariateRealFunction combiner, final double initialValue) { return new MultivariateRealFunction() { /** {@inheritDoc} */ public double value(double[] point) throws FunctionEvaluationException, IllegalArgumentException { double result = initialValue; for (final double entry : point) { result = combiner.value(result, ComposableFunction.this.value(entry)); } return result; } }; } /** * Generates a function that iteratively apply instance function on all * elements of an array. *

                        * Calling this method is equivalent to call {@link * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}. *

                        * @param combiner combiner to use between entries * @return a new function that iteratively apply instance function on all * elements of an array. * @see #asCollector(BivariateRealFunction, double) */ public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) { return asCollector(combiner, 0.0); } /** * Generates a function that iteratively apply instance function on all * elements of an array. *

                        * Calling this method is equivalent to call {@link * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}. *

                        * @param initialValue initial value to use before first entry * @return a new function that iteratively apply instance function on all * elements of an array. * @see #asCollector(BivariateRealFunction, double) * @see BinaryFunction#ADD */ public MultivariateRealFunction asCollector(final double initialValue) { return asCollector(BinaryFunction.ADD, initialValue); } /** * Generates a function that iteratively apply instance function on all * elements of an array. *

                        * Calling this method is equivalent to call {@link * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}. *

                        * @return a new function that iteratively apply instance function on all * elements of an array. * @see #asCollector(BivariateRealFunction, double) * @see BinaryFunction#ADD */ public MultivariateRealFunction asCollector() { return asCollector(BinaryFunction.ADD, 0.0); } /** {@inheritDoc} */ public abstract double value(double x) throws FunctionEvaluationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunction.java100644 1750 1750 2600 11532241246 31452 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.analysis; import org.apache.commons.math.FunctionEvaluationException; /** * An interface representing a univariate real function. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public interface UnivariateRealFunction { /** * Compute the value for the function. * @param x the point for which the function value should be computed * @return the value * @throws FunctionEvaluationException if the function evaluation fails */ double value(double x) throws FunctionEvaluationException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/MaxEvaluationsExceededException.java100644 1750 1750 6472 11532241247 31470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a numerical computation exceeds its allowed * number of functions evaluations. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public class MaxEvaluationsExceededException extends ConvergenceException { /** Serializable version identifier. */ private static final long serialVersionUID = -5921271447220129118L; /** Maximal number of evaluations allowed. */ private final int maxEvaluations; /** * Constructs an exception with a default detail message. * @param maxEvaluations maximal number of evaluations allowed */ public MaxEvaluationsExceededException(final int maxEvaluations) { super(LocalizedFormats.MAX_EVALUATIONS_EXCEEDED, maxEvaluations); this.maxEvaluations = maxEvaluations; } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param maxEvaluations the exceeded maximal number of evaluations * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MaxEvaluationsExceededException(int, Localizable, Object...)} */ @Deprecated public MaxEvaluationsExceededException(final int maxEvaluations, final String pattern, final Object ... arguments) { this(maxEvaluations, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param maxEvaluations the exceeded maximal number of evaluations * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MaxEvaluationsExceededException(final int maxEvaluations, final Localizable pattern, final Object ... arguments) { super(pattern, arguments); this.maxEvaluations = maxEvaluations; } /** Get the maximal number of evaluations allowed. * @return maximal number of evaluations allowed */ public int getMaxEvaluations() { return maxEvaluations; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/ComplexFormat.java100644 1750 1750 32130 11532241246 27456 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.CompositeFormat; import org.apache.commons.math.exception.NullArgumentException; /** * Formats a Complex number in cartesian format "Re(c) + Im(c)i". 'i' can * be replaced with 'j' (or anything else), and the number format for both real * and imaginary parts can be configured. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class ComplexFormat extends CompositeFormat { /** Serializable version identifier */ private static final long serialVersionUID = -3343698360149467646L; /** The default imaginary character. */ private static final String DEFAULT_IMAGINARY_CHARACTER = "i"; /** The notation used to signify the imaginary part of the complex number. */ private String imaginaryCharacter; /** The format used for the imaginary part. */ private NumberFormat imaginaryFormat; /** The format used for the real part. */ private NumberFormat realFormat; /** * Create an instance with the default imaginary character, 'i', and the * default number format for both real and imaginary parts. */ public ComplexFormat() { this(DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat()); } /** * Create an instance with a custom number format for both real and * imaginary parts. * @param format the custom format for both real and imaginary parts. */ public ComplexFormat(NumberFormat format) { this(DEFAULT_IMAGINARY_CHARACTER, format); } /** * Create an instance with a custom number format for the real part and a * custom number format for the imaginary part. * @param realFormat the custom format for the real part. * @param imaginaryFormat the custom format for the imaginary part. */ public ComplexFormat(NumberFormat realFormat, NumberFormat imaginaryFormat) { this(DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat); } /** * Create an instance with a custom imaginary character, and the default * number format for both real and imaginary parts. * @param imaginaryCharacter The custom imaginary character. */ public ComplexFormat(String imaginaryCharacter) { this(imaginaryCharacter, getDefaultNumberFormat()); } /** * Create an instance with a custom imaginary character, and a custom number * format for both real and imaginary parts. * @param imaginaryCharacter The custom imaginary character. * @param format the custom format for both real and imaginary parts. */ public ComplexFormat(String imaginaryCharacter, NumberFormat format) { this(imaginaryCharacter, format, (NumberFormat)format.clone()); } /** * Create an instance with a custom imaginary character, a custom number * format for the real part, and a custom number format for the imaginary * part. * @param imaginaryCharacter The custom imaginary character. * @param realFormat the custom format for the real part. * @param imaginaryFormat the custom format for the imaginary part. */ public ComplexFormat(String imaginaryCharacter, NumberFormat realFormat, NumberFormat imaginaryFormat) { super(); setImaginaryCharacter(imaginaryCharacter); setImaginaryFormat(imaginaryFormat); setRealFormat(realFormat); } /** * Get the set of locales for which complex formats are available. *

                        This is the same set as the {@link NumberFormat} set.

                        * @return available complex format locales. */ public static Locale[] getAvailableLocales() { return NumberFormat.getAvailableLocales(); } /** * This static method calls {@link #format(Object)} on a default instance of * ComplexFormat. * * @param c Complex object to format * @return A formatted number in the form "Re(c) + Im(c)i" */ public static String formatComplex(Complex c) { return getInstance().format(c); } /** * Formats a {@link Complex} object to produce a string. * * @param complex the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ public StringBuffer format(Complex complex, StringBuffer toAppendTo, FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); // format real double re = complex.getReal(); formatDouble(re, getRealFormat(), toAppendTo, pos); // format sign and imaginary double im = complex.getImaginary(); if (im < 0.0) { toAppendTo.append(" - "); formatDouble(-im, getImaginaryFormat(), toAppendTo, pos); toAppendTo.append(getImaginaryCharacter()); } else if (im > 0.0 || Double.isNaN(im)) { toAppendTo.append(" + "); formatDouble(im, getImaginaryFormat(), toAppendTo, pos); toAppendTo.append(getImaginaryCharacter()); } return toAppendTo; } /** * Formats a object to produce a string. obj must be either a * {@link Complex} object or a {@link Number} object. Any other type of * object will result in an {@link IllegalArgumentException} being thrown. * * @param obj the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) * @throws IllegalArgumentException is obj is not a valid type. */ @Override public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { StringBuffer ret = null; if (obj instanceof Complex) { ret = format( (Complex)obj, toAppendTo, pos); } else if (obj instanceof Number) { ret = format( new Complex(((Number)obj).doubleValue(), 0.0), toAppendTo, pos); } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_COMPLEX, obj.getClass().getName()); } return ret; } /** * Access the imaginaryCharacter. * @return the imaginaryCharacter. */ public String getImaginaryCharacter() { return imaginaryCharacter; } /** * Access the imaginaryFormat. * @return the imaginaryFormat. */ public NumberFormat getImaginaryFormat() { return imaginaryFormat; } /** * Returns the default complex format for the current locale. * @return the default complex format. */ public static ComplexFormat getInstance() { return getInstance(Locale.getDefault()); } /** * Returns the default complex format for the given locale. * @param locale the specific locale used by the format. * @return the complex format specific to the given locale. */ public static ComplexFormat getInstance(Locale locale) { NumberFormat f = getDefaultNumberFormat(locale); return new ComplexFormat(f); } /** * Access the realFormat. * @return the realFormat. */ public NumberFormat getRealFormat() { return realFormat; } /** * Parses a string to produce a {@link Complex} object. * * @param source the string to parse * @return the parsed {@link Complex} object. * @exception ParseException if the beginning of the specified string * cannot be parsed. */ public Complex parse(String source) throws ParseException { ParsePosition parsePosition = new ParsePosition(0); Complex result = parse(source, parsePosition); if (parsePosition.getIndex() == 0) { throw MathRuntimeException.createParseException( parsePosition.getErrorIndex(), LocalizedFormats.UNPARSEABLE_COMPLEX_NUMBER, source); } return result; } /** * Parses a string to produce a {@link Complex} object. * * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link Complex} object. */ public Complex parse(String source, ParsePosition pos) { int initialIndex = pos.getIndex(); // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse real Number re = parseNumber(source, getRealFormat(), pos); if (re == null) { // invalid real number // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } // parse sign int startIndex = pos.getIndex(); char c = parseNextCharacter(source, pos); int sign = 0; switch (c) { case 0 : // no sign // return real only complex number return new Complex(re.doubleValue(), 0.0); case '-' : sign = -1; break; case '+' : sign = 1; break; default : // invalid sign // set index back to initial, error index should be the last // character examined. pos.setIndex(initialIndex); pos.setErrorIndex(startIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse imaginary Number im = parseNumber(source, getRealFormat(), pos); if (im == null) { // invalid imaginary number // set index back to initial, error index should already be set pos.setIndex(initialIndex); return null; } // parse imaginary character if (!parseFixedstring(source, getImaginaryCharacter(), pos)) { return null; } return new Complex(re.doubleValue(), im.doubleValue() * sign); } /** * Parses a string to produce a object. * * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed object. * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) */ @Override public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); } /** * Modify the imaginaryCharacter. * @param imaginaryCharacter The new imaginaryCharacter value. * @throws IllegalArgumentException if imaginaryCharacter is * null or an empty string. */ public void setImaginaryCharacter(String imaginaryCharacter) { if (imaginaryCharacter == null || imaginaryCharacter.length() == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.EMPTY_STRING_FOR_IMAGINARY_CHARACTER); } this.imaginaryCharacter = imaginaryCharacter; } /** * Modify the imaginaryFormat. * @param imaginaryFormat The new imaginaryFormat value. * @throws NullArgumentException if {@code imaginaryFormat} is {@code null}. */ public void setImaginaryFormat(NumberFormat imaginaryFormat) { if (imaginaryFormat == null) { throw new NullArgumentException(LocalizedFormats.IMAGINARY_FORMAT); } this.imaginaryFormat = imaginaryFormat; } /** * Modify the realFormat. * @param realFormat The new realFormat value. * @throws NullArgumentException if {@code realFormat} is {@code null}. */ public void setRealFormat(NumberFormat realFormat) { if (realFormat == null) { throw new NullArgumentException(LocalizedFormats.REAL_FORMAT); } this.realFormat = realFormat; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/ComplexField.java100644 1750 1750 4454 11532241246 27241 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.io.Serializable; import org.apache.commons.math.Field; /** * Representation of the complex numbers field. *

                        * This class is a singleton. *

                        * @see Complex * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public class ComplexField implements Field, Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -6130362688700788798L; /** Private constructor for the singleton. */ private ComplexField() { } /** Get the unique instance. * @return the unique instance */ public static ComplexField getInstance() { return LazyHolder.INSTANCE; } /** {@inheritDoc} */ public Complex getOne() { return Complex.ONE; } /** {@inheritDoc} */ public Complex getZero() { return Complex.ZERO; } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the instance. *

                        We use here the Initialization On Demand Holder Idiom.

                        */ private static class LazyHolder { /** Cached field instance. */ private static final ComplexField INSTANCE = new ComplexField(); } // CHECKSTYLE: resume HideUtilityClassConstructor /** Handle deserialization of the singleton. * @return the singleton instance */ private Object readResolve() { // return the singleton instance return LazyHolder.INSTANCE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/package.html100644 1750 1750 1763 11532241246 26304 0ustarlucluc 0 0 Complex number type and implementations of complex transcendental functions. commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/ComplexUtils.java100644 1750 1750 5432 11532241246 27313 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Static implementations of common * {@link org.apache.commons.math.complex.Complex} utilities functions. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class ComplexUtils { /** * Default constructor. */ private ComplexUtils() { super(); } /** * Creates a complex number from the given polar representation. *

                        * The value returned is r·ei·theta, * computed as r·cos(theta) + r·sin(theta)i

                        *

                        * If either r or theta is NaN, or * theta is infinite, {@link Complex#NaN} is returned.

                        *

                        * If r is infinite and theta is finite, * infinite or NaN values may be returned in parts of the result, following * the rules for double arithmetic.

                             * Examples:
                             * 
                             * polar2Complex(INFINITY, π/4) = INFINITY + INFINITY i
                             * polar2Complex(INFINITY, 0) = INFINITY + NaN i
                             * polar2Complex(INFINITY, -π/4) = INFINITY - INFINITY i
                             * polar2Complex(INFINITY, 5π/4) = -INFINITY - INFINITY i 

                        * * @param r the modulus of the complex number to create * @param theta the argument of the complex number to create * @return r·ei·theta * @throws IllegalArgumentException if r is negative * @since 1.1 */ public static Complex polar2Complex(double r, double theta) { if (r < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NEGATIVE_COMPLEX_MODULE, r); } return new Complex(r * FastMath.cos(theta), r * FastMath.sin(theta)); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/complex/Complex.java100644 1750 1750 106276 11532241246 26342 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.complex; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Representation of a Complex number - a number which has both a * real and imaginary part. *

                        * Implementations of arithmetic operations handle NaN and * infinite values according to the rules for {@link java.lang.Double} * arithmetic, applying definitional formulas and returning NaN or * infinite values in real or imaginary parts as these arise in computation. * See individual method javadocs for details.

                        *

                        * {@link #equals} identifies all values with NaN in either real * or imaginary part - e.g.,

                         * 1 + NaNi  == NaN + i == NaN + NaNi.

                        * * implements Serializable since 2.0 * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class Complex implements FieldElement, Serializable { /** The square root of -1. A number representing "0.0 + 1.0i" */ public static final Complex I = new Complex(0.0, 1.0); // CHECKSTYLE: stop ConstantName /** A complex number representing "NaN + NaNi" */ public static final Complex NaN = new Complex(Double.NaN, Double.NaN); // CHECKSTYLE: resume ConstantName /** A complex number representing "+INF + INFi" */ public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); /** A complex number representing "1.0 + 0.0i" */ public static final Complex ONE = new Complex(1.0, 0.0); /** A complex number representing "0.0 + 0.0i" */ public static final Complex ZERO = new Complex(0.0, 0.0); /** Serializable version identifier */ private static final long serialVersionUID = -6195664516687396620L; /** The imaginary part. */ private final double imaginary; /** The real part. */ private final double real; /** Record whether this complex number is equal to NaN. */ private final transient boolean isNaN; /** Record whether this complex number is infinite. */ private final transient boolean isInfinite; /** * Create a complex number given the real and imaginary parts. * * @param real the real part * @param imaginary the imaginary part */ public Complex(double real, double imaginary) { super(); this.real = real; this.imaginary = imaginary; isNaN = Double.isNaN(real) || Double.isNaN(imaginary); isInfinite = !isNaN && (Double.isInfinite(real) || Double.isInfinite(imaginary)); } /** * Return the absolute value of this complex number. *

                        * Returns NaN if either real or imaginary part is * NaN and Double.POSITIVE_INFINITY if * neither part is NaN, but at least one part takes an infinite * value.

                        * * @return the absolute value */ public double abs() { if (isNaN()) { return Double.NaN; } if (isInfinite()) { return Double.POSITIVE_INFINITY; } if (FastMath.abs(real) < FastMath.abs(imaginary)) { if (imaginary == 0.0) { return FastMath.abs(real); } double q = real / imaginary; return FastMath.abs(imaginary) * FastMath.sqrt(1 + q * q); } else { if (real == 0.0) { return FastMath.abs(imaginary); } double q = imaginary / real; return FastMath.abs(real) * FastMath.sqrt(1 + q * q); } } /** * Return the sum of this complex number and the given complex number. *

                        * Uses the definitional formula *

                             * (a + bi) + (c + di) = (a+c) + (b+d)i
                             * 

                        *

                        * If either this or rhs has a NaN value in either part, * {@link #NaN} is returned; otherwise Inifinite and NaN values are * returned in the parts of the result according to the rules for * {@link java.lang.Double} arithmetic.

                        * * @param rhs the other complex number * @return the complex number sum * @throws NullPointerException if rhs is null */ public Complex add(Complex rhs) { return createComplex(real + rhs.getReal(), imaginary + rhs.getImaginary()); } /** * Return the conjugate of this complex number. The conjugate of * "A + Bi" is "A - Bi". *

                        * {@link #NaN} is returned if either the real or imaginary * part of this Complex number equals Double.NaN.

                        *

                        * If the imaginary part is infinite, and the real part is not NaN, * the returned value has infinite imaginary part of the opposite * sign - e.g. the conjugate of 1 + POSITIVE_INFINITY i * is 1 - NEGATIVE_INFINITY i

                        * * @return the conjugate of this Complex object */ public Complex conjugate() { if (isNaN()) { return NaN; } return createComplex(real, -imaginary); } /** * Return the quotient of this complex number and the given complex number. *

                        * Implements the definitional formula *

                        
                             *    a + bi          ac + bd + (bc - ad)i
                             *    ----------- = -------------------------
                             *    c + di         c2 + d2
                             * 
                        * but uses * * prescaling of operands to limit the effects of overflows and * underflows in the computation.

                        *

                        * Infinite and NaN values are handled / returned according to the * following rules, applied in the order presented: *

                          *
                        • If either this or rhs has a NaN value in either part, * {@link #NaN} is returned.
                        • *
                        • If rhs equals {@link #ZERO}, {@link #NaN} is returned. *
                        • *
                        • If this and rhs are both infinite, * {@link #NaN} is returned.
                        • *
                        • If this is finite (i.e., has no infinite or NaN parts) and * rhs is infinite (one or both parts infinite), * {@link #ZERO} is returned.
                        • *
                        • If this is infinite and rhs is finite, NaN values are * returned in the parts of the result if the {@link java.lang.Double} * rules applied to the definitional formula force NaN results.
                        • *

                        * * @param rhs the other complex number * @return the complex number quotient * @throws NullPointerException if rhs is null */ public Complex divide(Complex rhs) { if (isNaN() || rhs.isNaN()) { return NaN; } double c = rhs.getReal(); double d = rhs.getImaginary(); if (c == 0.0 && d == 0.0) { return NaN; } if (rhs.isInfinite() && !isInfinite()) { return ZERO; } if (FastMath.abs(c) < FastMath.abs(d)) { double q = c / d; double denominator = c * q + d; return createComplex((real * q + imaginary) / denominator, (imaginary * q - real) / denominator); } else { double q = d / c; double denominator = d * q + c; return createComplex((imaginary * q + real) / denominator, (imaginary - real * q) / denominator); } } /** * Test for the equality of two Complex objects. *

                        * If both the real and imaginary parts of two Complex numbers * are exactly the same, and neither is Double.NaN, the two * Complex objects are considered to be equal.

                        *

                        * All NaN values are considered to be equal - i.e, if either * (or both) real and imaginary parts of the complex number are equal * to Double.NaN, the complex number is equal to * Complex.NaN.

                        * * @param other Object to test for equality to this * @return true if two Complex objects are equal, false if * object is null, not an instance of Complex, or * not equal to this Complex instance * */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof Complex){ Complex rhs = (Complex)other; if (rhs.isNaN()) { return this.isNaN(); } else { return (real == rhs.real) && (imaginary == rhs.imaginary); } } return false; } /** * Get a hashCode for the complex number. *

                        * All NaN values have the same hash code.

                        * * @return a hash code value for this object */ @Override public int hashCode() { if (isNaN()) { return 7; } return 37 * (17 * MathUtils.hash(imaginary) + MathUtils.hash(real)); } /** * Access the imaginary part. * * @return the imaginary part */ public double getImaginary() { return imaginary; } /** * Access the real part. * * @return the real part */ public double getReal() { return real; } /** * Returns true if either or both parts of this complex number is NaN; * false otherwise * * @return true if either or both parts of this complex number is NaN; * false otherwise */ public boolean isNaN() { return isNaN; } /** * Returns true if either the real or imaginary part of this complex number * takes an infinite value (either Double.POSITIVE_INFINITY or * Double.NEGATIVE_INFINITY) and neither part * is NaN. * * @return true if one or both parts of this complex number are infinite * and neither part is NaN */ public boolean isInfinite() { return isInfinite; } /** * Return the product of this complex number and the given complex number. *

                        * Implements preliminary checks for NaN and infinity followed by * the definitional formula: *

                        
                             * (a + bi)(c + di) = (ac - bd) + (ad + bc)i
                             * 
                        *

                        *

                        * Returns {@link #NaN} if either this or rhs has one or more * NaN parts. *

                        * Returns {@link #INF} if neither this nor rhs has one or more * NaN parts and if either this or rhs has one or more * infinite parts (same result is returned regardless of the sign of the * components). *

                        *

                        * Returns finite values in components of the result per the * definitional formula in all remaining cases. *

                        * * @param rhs the other complex number * @return the complex number product * @throws NullPointerException if rhs is null */ public Complex multiply(Complex rhs) { if (isNaN() || rhs.isNaN()) { return NaN; } if (Double.isInfinite(real) || Double.isInfinite(imaginary) || Double.isInfinite(rhs.real)|| Double.isInfinite(rhs.imaginary)) { // we don't use Complex.isInfinite() to avoid testing for NaN again return INF; } return createComplex(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + imaginary * rhs.real); } /** * Return the product of this complex number and the given scalar number. *

                        * Implements preliminary checks for NaN and infinity followed by * the definitional formula: *

                        
                             * c(a + bi) = (ca) + (cb)i
                             * 
                        *

                        *

                        * Returns {@link #NaN} if either this or rhs has one or more * NaN parts. *

                        * Returns {@link #INF} if neither this nor rhs has one or more * NaN parts and if either this or rhs has one or more * infinite parts (same result is returned regardless of the sign of the * components). *

                        *

                        * Returns finite values in components of the result per the * definitional formula in all remaining cases. *

                        * * @param rhs the scalar number * @return the complex number product */ public Complex multiply(double rhs) { if (isNaN() || Double.isNaN(rhs)) { return NaN; } if (Double.isInfinite(real) || Double.isInfinite(imaginary) || Double.isInfinite(rhs)) { // we don't use Complex.isInfinite() to avoid testing for NaN again return INF; } return createComplex(real * rhs, imaginary * rhs); } /** * Return the additive inverse of this complex number. *

                        * Returns Complex.NaN if either real or imaginary * part of this Complex number equals Double.NaN.

                        * * @return the negation of this complex number */ public Complex negate() { if (isNaN()) { return NaN; } return createComplex(-real, -imaginary); } /** * Return the difference between this complex number and the given complex * number. *

                        * Uses the definitional formula *

                             * (a + bi) - (c + di) = (a-c) + (b-d)i
                             * 

                        *

                        * If either this or rhs has a NaN value in either part, * {@link #NaN} is returned; otherwise inifinite and NaN values are * returned in the parts of the result according to the rules for * {@link java.lang.Double} arithmetic.

                        * * @param rhs the other complex number * @return the complex number difference * @throws NullPointerException if rhs is null */ public Complex subtract(Complex rhs) { if (isNaN() || rhs.isNaN()) { return NaN; } return createComplex(real - rhs.getReal(), imaginary - rhs.getImaginary()); } /** * Compute the * * inverse cosine of this complex number. *

                        * Implements the formula:

                             *  acos(z) = -i (log(z + i (sqrt(1 - z2))))

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN or infinite.

                        * * @return the inverse cosine of this complex number * @since 1.2 */ public Complex acos() { if (isNaN()) { return Complex.NaN; } return this.add(this.sqrt1z().multiply(Complex.I)).log() .multiply(Complex.I.negate()); } /** * Compute the * * inverse sine of this complex number. *

                        * Implements the formula:

                             *  asin(z) = -i (log(sqrt(1 - z2) + iz)) 

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN or infinite.

                        * * @return the inverse sine of this complex number. * @since 1.2 */ public Complex asin() { if (isNaN()) { return Complex.NaN; } return sqrt1z().add(this.multiply(Complex.I)).log() .multiply(Complex.I.negate()); } /** * Compute the * * inverse tangent of this complex number. *

                        * Implements the formula:

                             *  atan(z) = (i/2) log((i + z)/(i - z)) 

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN or infinite.

                        * * @return the inverse tangent of this complex number * @since 1.2 */ public Complex atan() { if (isNaN()) { return Complex.NaN; } return this.add(Complex.I).divide(Complex.I.subtract(this)).log() .multiply(Complex.I.divide(createComplex(2.0, 0.0))); } /** * Compute the * * cosine * of this complex number. *

                        * Implements the formula:

                             *  cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * cos(1 ± INFINITY i) = 1 ∓ INFINITY i
                             * cos(±INFINITY + i) = NaN + NaN i
                             * cos(±INFINITY ± INFINITY i) = NaN + NaN i

                        * * @return the cosine of this complex number * @since 1.2 */ public Complex cos() { if (isNaN()) { return Complex.NaN; } return createComplex(FastMath.cos(real) * MathUtils.cosh(imaginary), -FastMath.sin(real) * MathUtils.sinh(imaginary)); } /** * Compute the * * hyperbolic cosine of this complex number. *

                        * Implements the formula:

                             *  cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * cosh(1 ± INFINITY i) = NaN + NaN i
                             * cosh(±INFINITY + i) = INFINITY ± INFINITY i
                             * cosh(±INFINITY ± INFINITY i) = NaN + NaN i

                        * * @return the hyperbolic cosine of this complex number. * @since 1.2 */ public Complex cosh() { if (isNaN()) { return Complex.NaN; } return createComplex(MathUtils.cosh(real) * FastMath.cos(imaginary), MathUtils.sinh(real) * FastMath.sin(imaginary)); } /** * Compute the * * exponential function of this complex number. *

                        * Implements the formula:

                             *  exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and * {@link java.lang.Math#sin}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * exp(1 ± INFINITY i) = NaN + NaN i
                             * exp(INFINITY + i) = INFINITY + INFINITY i
                             * exp(-INFINITY + i) = 0 + 0i
                             * exp(±INFINITY ± INFINITY i) = NaN + NaN i

                        * * @return ethis * @since 1.2 */ public Complex exp() { if (isNaN()) { return Complex.NaN; } double expReal = FastMath.exp(real); return createComplex(expReal * FastMath.cos(imaginary), expReal * FastMath.sin(imaginary)); } /** * Compute the * * natural logarithm of this complex number. *

                        * Implements the formula:

                             *  log(a + bi) = ln(|a + bi|) + arg(a + bi)i
                        * where ln on the right hand side is {@link java.lang.Math#log}, * |a + bi| is the modulus, {@link Complex#abs}, and * arg(a + bi) = {@link java.lang.Math#atan2}(b, a)

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite (or critical) values in real or imaginary parts of the input may * result in infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * log(1 ± INFINITY i) = INFINITY ± (π/2)i
                             * log(INFINITY + i) = INFINITY + 0i
                             * log(-INFINITY + i) = INFINITY + πi
                             * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i
                             * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i
                             * log(0 + 0i) = -INFINITY + 0i
                             * 

                        * * @return ln of this complex number. * @since 1.2 */ public Complex log() { if (isNaN()) { return Complex.NaN; } return createComplex(FastMath.log(abs()), FastMath.atan2(imaginary, real)); } /** * Returns of value of this complex number raised to the power of x. *

                        * Implements the formula:

                             *  yx = exp(x·log(y))
                        * where exp and log are {@link #exp} and * {@link #log}, respectively.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN or infinite, or if y * equals {@link Complex#ZERO}.

                        * * @param x the exponent. * @return thisx * @throws NullPointerException if x is null * @since 1.2 */ public Complex pow(Complex x) { if (x == null) { throw new NullPointerException(); } return this.log().multiply(x).exp(); } /** * Compute the * * sine * of this complex number. *

                        * Implements the formula:

                             *  sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * sin(1 ± INFINITY i) = 1 ± INFINITY i
                             * sin(±INFINITY + i) = NaN + NaN i
                             * sin(±INFINITY ± INFINITY i) = NaN + NaN i

                        * * @return the sine of this complex number. * @since 1.2 */ public Complex sin() { if (isNaN()) { return Complex.NaN; } return createComplex(FastMath.sin(real) * MathUtils.cosh(imaginary), FastMath.cos(real) * MathUtils.sinh(imaginary)); } /** * Compute the * * hyperbolic sine of this complex number. *

                        * Implements the formula:

                             *  sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * sinh(1 ± INFINITY i) = NaN + NaN i
                             * sinh(±INFINITY + i) = ± INFINITY + INFINITY i
                             * sinh(±INFINITY ± INFINITY i) = NaN + NaN i

                        * * @return the hyperbolic sine of this complex number * @since 1.2 */ public Complex sinh() { if (isNaN()) { return Complex.NaN; } return createComplex(MathUtils.sinh(real) * FastMath.cos(imaginary), MathUtils.cosh(real) * FastMath.sin(imaginary)); } /** * Compute the * * square root of this complex number. *

                        * Implements the following algorithm to compute sqrt(a + bi): *

                        1. Let t = sqrt((|a| + |a + bi|) / 2)
                        2. *
                        3. if  a ≥ 0 return t + (b/2t)i
                               *  else return |b|/2t + sign(b)t i 
                        4. *
                        * where
                          *
                        • |a| = {@link Math#abs}(a)
                        • *
                        • |a + bi| = {@link Complex#abs}(a + bi)
                        • *
                        • sign(b) = {@link MathUtils#indicator}(b) *

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * sqrt(1 ± INFINITY i) = INFINITY + NaN i
                             * sqrt(INFINITY + i) = INFINITY + 0i
                             * sqrt(-INFINITY + i) = 0 + INFINITY i
                             * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i
                             * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i
                             * 

                        * * @return the square root of this complex number * @since 1.2 */ public Complex sqrt() { if (isNaN()) { return Complex.NaN; } if (real == 0.0 && imaginary == 0.0) { return createComplex(0.0, 0.0); } double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0); if (real >= 0.0) { return createComplex(t, imaginary / (2.0 * t)); } else { return createComplex(FastMath.abs(imaginary) / (2.0 * t), MathUtils.indicator(imaginary) * t); } } /** * Compute the * * square root of 1 - this2 for this complex * number. *

                        * Computes the result directly as * sqrt(Complex.ONE.subtract(z.multiply(z))).

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                        * * @return the square root of 1 - this2 * @since 1.2 */ public Complex sqrt1z() { return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt(); } /** * Compute the * * tangent of this complex number. *

                        * Implements the formula:

                             * tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite (or critical) values in real or imaginary parts of the input may * result in infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * tan(1 ± INFINITY i) = 0 + NaN i
                             * tan(±INFINITY + i) = NaN + NaN i
                             * tan(±INFINITY ± INFINITY i) = NaN + NaN i
                             * tan(±π/2 + 0 i) = ±INFINITY + NaN i

                        * * @return the tangent of this complex number * @since 1.2 */ public Complex tan() { if (isNaN()) { return Complex.NaN; } double real2 = 2.0 * real; double imaginary2 = 2.0 * imaginary; double d = FastMath.cos(real2) + MathUtils.cosh(imaginary2); return createComplex(FastMath.sin(real2) / d, MathUtils.sinh(imaginary2) / d); } /** * Compute the * * hyperbolic tangent of this complex number. *

                        * Implements the formula:

                             * tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
                        * where the (real) functions on the right-hand side are * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, * {@link MathUtils#cosh} and {@link MathUtils#sinh}.

                        *

                        * Returns {@link Complex#NaN} if either real or imaginary part of the * input argument is NaN.

                        *

                        * Infinite values in real or imaginary parts of the input may result in * infinite or NaN values returned in parts of the result.

                             * Examples:
                             * 
                             * tanh(1 ± INFINITY i) = NaN + NaN i
                             * tanh(±INFINITY + i) = NaN + 0 i
                             * tanh(±INFINITY ± INFINITY i) = NaN + NaN i
                             * tanh(0 + (π/2)i) = NaN + INFINITY i

                        * * @return the hyperbolic tangent of this complex number * @since 1.2 */ public Complex tanh() { if (isNaN()) { return Complex.NaN; } double real2 = 2.0 * real; double imaginary2 = 2.0 * imaginary; double d = MathUtils.cosh(real2) + FastMath.cos(imaginary2); return createComplex(MathUtils.sinh(real2) / d, FastMath.sin(imaginary2) / d); } /** *

                        Compute the argument of this complex number. *

                        *

                        The argument is the angle phi between the positive real axis and the point * representing this number in the complex plane. The value returned is between -PI (not inclusive) * and PI (inclusive), with negative values returned for numbers with negative imaginary parts. *

                        *

                        If either real or imaginary part (or both) is NaN, NaN is returned. Infinite parts are handled * as java.Math.atan2 handles them, essentially treating finite parts as zero in the presence of * an infinite coordinate and returning a multiple of pi/4 depending on the signs of the infinite * parts. See the javadoc for java.Math.atan2 for full details.

                        * * @return the argument of this complex number */ public double getArgument() { return FastMath.atan2(getImaginary(), getReal()); } /** *

                        Computes the n-th roots of this complex number. *

                        *

                        The nth roots are defined by the formula:

                             *  zk = abs 1/n (cos(phi + 2πk/n) + i (sin(phi + 2πk/n))
                        * for k=0, 1, ..., n-1, where abs and phi are * respectively the {@link #abs() modulus} and {@link #getArgument() argument} of this complex number. *

                        *

                        If one or both parts of this complex number is NaN, a list with just one element, * {@link #NaN} is returned.

                        *

                        if neither part is NaN, but at least one part is infinite, the result is a one-element * list containing {@link #INF}.

                        * * @param n degree of root * @return List all nth roots of this complex number * @throws IllegalArgumentException if parameter n is less than or equal to 0 * @since 2.0 */ public List nthRoot(int n) throws IllegalArgumentException { if (n <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N, n); } List result = new ArrayList(); if (isNaN()) { result.add(Complex.NaN); return result; } if (isInfinite()) { result.add(Complex.INF); return result; } // nth root of abs -- faster / more accurate to use a solver here? final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n); // Compute nth roots of complex number with k = 0, 1, ... n-1 final double nthPhi = getArgument()/n; final double slice = 2 * FastMath.PI / n; double innerPart = nthPhi; for (int k = 0; k < n ; k++) { // inner part final double realPart = nthRootOfAbs * FastMath.cos(innerPart); final double imaginaryPart = nthRootOfAbs * FastMath.sin(innerPart); result.add(createComplex(realPart, imaginaryPart)); innerPart += slice; } return result; } /** * Create a complex number given the real and imaginary parts. * * @param realPart the real part * @param imaginaryPart the imaginary part * @return a new complex number instance * @since 1.2 */ protected Complex createComplex(double realPart, double imaginaryPart) { return new Complex(realPart, imaginaryPart); } /** *

                        Resolve the transient fields in a deserialized Complex Object.

                        *

                        Subclasses will need to override {@link #createComplex} to deserialize properly

                        * @return A Complex instance with all fields resolved. * @since 2.0 */ protected final Object readResolve() { return createComplex(real, imaginary); } /** {@inheritDoc} */ public ComplexField getField() { return ComplexField.getInstance(); } } ././@LongLink100644 0 0 145 11532242444 10254 Lustar 0 0 commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/FractionConversionException.javacommons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/FractionConversionException.java100644 1750 1750 4305 11532241244 32507 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when a double value cannot be converted to a fraction * in the allowed number of iterations. * * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 1.2 */ public class FractionConversionException extends ConvergenceException { /** Serializable version identifier. */ private static final long serialVersionUID = -4661812640132576263L; /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param value double value to convert * @param maxIterations maximal number of iterations allowed */ public FractionConversionException(double value, int maxIterations) { super(LocalizedFormats.FAILED_FRACTION_CONVERSION, value, maxIterations); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param value double value to convert * @param p current numerator * @param q current denominator */ public FractionConversionException(double value, long p, long q) { super(LocalizedFormats.FRACTION_CONVERSION_OVERFLOW, value, p, q); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/BigFractionFormat.java100644 1750 1750 24614 11532241244 30402 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import java.math.BigInteger; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Formats a BigFraction number in proper format or improper format. *

                        * The number format for each of the whole number, numerator and, * denominator can be configured. *

                        * * @since 2.0 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class BigFractionFormat extends AbstractFormat implements Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -2932167925527338976L; /** * Create an improper formatting instance with the default number format * for the numerator and denominator. */ public BigFractionFormat() { } /** * Create an improper formatting instance with a custom number format for * both the numerator and denominator. * @param format the custom format for both the numerator and denominator. */ public BigFractionFormat(final NumberFormat format) { super(format); } /** * Create an improper formatting instance with a custom number format for * the numerator and a custom number format for the denominator. * @param numeratorFormat the custom format for the numerator. * @param denominatorFormat the custom format for the denominator. */ public BigFractionFormat(final NumberFormat numeratorFormat, final NumberFormat denominatorFormat) { super(numeratorFormat, denominatorFormat); } /** * Get the set of locales for which complex formats are available. This * is the same set as the {@link NumberFormat} set. * @return available complex format locales. */ public static Locale[] getAvailableLocales() { return NumberFormat.getAvailableLocales(); } /** * This static method calls formatBigFraction() on a default instance of * BigFractionFormat. * * @param f BigFraction object to format * @return A formatted BigFraction in proper form. */ public static String formatBigFraction(final BigFraction f) { return getImproperInstance().format(f); } /** * Returns the default complex format for the current locale. * @return the default complex format. */ public static BigFractionFormat getImproperInstance() { return getImproperInstance(Locale.getDefault()); } /** * Returns the default complex format for the given locale. * @param locale the specific locale used by the format. * @return the complex format specific to the given locale. */ public static BigFractionFormat getImproperInstance(final Locale locale) { return new BigFractionFormat(getDefaultNumberFormat(locale)); } /** * Returns the default complex format for the current locale. * @return the default complex format. */ public static BigFractionFormat getProperInstance() { return getProperInstance(Locale.getDefault()); } /** * Returns the default complex format for the given locale. * @param locale the specific locale used by the format. * @return the complex format specific to the given locale. */ public static BigFractionFormat getProperInstance(final Locale locale) { return new ProperBigFractionFormat(getDefaultNumberFormat(locale)); } /** * Formats a {@link BigFraction} object to produce a string. The BigFraction is * output in improper format. * * @param BigFraction the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ public StringBuffer format(final BigFraction BigFraction, final StringBuffer toAppendTo, final FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); getNumeratorFormat().format(BigFraction.getNumerator(), toAppendTo, pos); toAppendTo.append(" / "); getDenominatorFormat().format(BigFraction.getDenominator(), toAppendTo, pos); return toAppendTo; } /** * Formats an object and appends the result to a StringBuffer. * obj must be either a {@link BigFraction} object or a * {@link BigInteger} object or a {@link Number} object. Any other type of * object will result in an {@link IllegalArgumentException} being thrown. * * @param obj the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) * @throws IllegalArgumentException is obj is not a valid type. */ @Override public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) { final StringBuffer ret; if (obj instanceof BigFraction) { ret = format((BigFraction) obj, toAppendTo, pos); } else if (obj instanceof BigInteger) { ret = format(new BigFraction((BigInteger) obj), toAppendTo, pos); } else if (obj instanceof Number) { ret = format(new BigFraction(((Number) obj).doubleValue()), toAppendTo, pos); } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION); } return ret; } /** * Parses a string to produce a {@link BigFraction} object. * @param source the string to parse * @return the parsed {@link BigFraction} object. * @exception ParseException if the beginning of the specified string * cannot be parsed. */ @Override public BigFraction parse(final String source) throws ParseException { final ParsePosition parsePosition = new ParsePosition(0); final BigFraction result = parse(source, parsePosition); if (parsePosition.getIndex() == 0) { throw MathRuntimeException.createParseException( parsePosition.getErrorIndex(), LocalizedFormats.UNPARSEABLE_FRACTION_NUMBER, source); } return result; } /** * Parses a string to produce a {@link BigFraction} object. * This method expects the string to be formatted as an improper BigFraction. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link BigFraction} object. */ @Override public BigFraction parse(final String source, final ParsePosition pos) { final int initialIndex = pos.getIndex(); // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse numerator final BigInteger num = parseNextBigInteger(source, pos); if (num == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } // parse '/' final int startIndex = pos.getIndex(); final char c = parseNextCharacter(source, pos); switch (c) { case 0 : // no '/' // return num as a BigFraction return new BigFraction(num); case '/' : // found '/', continue parsing denominator break; default : // invalid '/' // set index back to initial, error index should be the last // character examined. pos.setIndex(initialIndex); pos.setErrorIndex(startIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse denominator final BigInteger den = parseNextBigInteger(source, pos); if (den == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } return new BigFraction(num, den); } /** * Parses a string to produce a BigInteger. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return a parsed BigInteger or null if string does not * contain a BigInteger at the specified position */ protected BigInteger parseNextBigInteger(final String source, final ParsePosition pos) { final int start = pos.getIndex(); int end = (source.charAt(start) == '-') ? (start + 1) : start; while((end < source.length()) && Character.isDigit(source.charAt(end))) { ++end; } try { BigInteger n = new BigInteger(source.substring(start, end)); pos.setIndex(end); return n; } catch (NumberFormatException nfe) { pos.setErrorIndex(start); return null; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/ProperBigFractionFormat.java100644 1750 1750 20133 11532241244 31562 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.math.BigInteger; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; /** * Formats a BigFraction number in proper format. The number format for each of * the whole number, numerator and, denominator can be configured. *

                        * Minus signs are only allowed in the whole number part - i.e., * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and * will result in a ParseException.

                        * * @since 1.1 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class ProperBigFractionFormat extends BigFractionFormat { /** Serializable version identifier */ private static final long serialVersionUID = -6337346779577272307L; /** The format used for the whole number. */ private NumberFormat wholeFormat; /** * Create a proper formatting instance with the default number format for * the whole, numerator, and denominator. */ public ProperBigFractionFormat() { this(getDefaultNumberFormat()); } /** * Create a proper formatting instance with a custom number format for the * whole, numerator, and denominator. * @param format the custom format for the whole, numerator, and * denominator. */ public ProperBigFractionFormat(final NumberFormat format) { this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); } /** * Create a proper formatting instance with a custom number format for each * of the whole, numerator, and denominator. * @param wholeFormat the custom format for the whole. * @param numeratorFormat the custom format for the numerator. * @param denominatorFormat the custom format for the denominator. */ public ProperBigFractionFormat(final NumberFormat wholeFormat, final NumberFormat numeratorFormat, final NumberFormat denominatorFormat) { super(numeratorFormat, denominatorFormat); setWholeFormat(wholeFormat); } /** * Formats a {@link BigFraction} object to produce a string. The BigFraction * is output in proper format. * * @param fraction the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ @Override public StringBuffer format(final BigFraction fraction, final StringBuffer toAppendTo, final FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); BigInteger num = fraction.getNumerator(); BigInteger den = fraction.getDenominator(); BigInteger whole = num.divide(den); num = num.remainder(den); if (!BigInteger.ZERO.equals(whole)) { getWholeFormat().format(whole, toAppendTo, pos); toAppendTo.append(' '); if (num.compareTo(BigInteger.ZERO) < 0) { num = num.negate(); } } getNumeratorFormat().format(num, toAppendTo, pos); toAppendTo.append(" / "); getDenominatorFormat().format(den, toAppendTo, pos); return toAppendTo; } /** * Access the whole format. * @return the whole format. */ public NumberFormat getWholeFormat() { return wholeFormat; } /** * Parses a string to produce a {@link BigFraction} object. This method * expects the string to be formatted as a proper BigFraction. *

                        * Minus signs are only allowed in the whole number part - i.e., * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and * will result in a ParseException.

                        * * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link BigFraction} object. */ @Override public BigFraction parse(final String source, final ParsePosition pos) { // try to parse improper BigFraction BigFraction ret = super.parse(source, pos); if (ret != null) { return ret; } final int initialIndex = pos.getIndex(); // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse whole BigInteger whole = parseNextBigInteger(source, pos); if (whole == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse numerator BigInteger num = parseNextBigInteger(source, pos); if (num == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } if (num.compareTo(BigInteger.ZERO) < 0) { // minus signs should be leading, invalid expression pos.setIndex(initialIndex); return null; } // parse '/' final int startIndex = pos.getIndex(); final char c = parseNextCharacter(source, pos); switch (c) { case 0 : // no '/' // return num as a BigFraction return new BigFraction(num); case '/' : // found '/', continue parsing denominator break; default : // invalid '/' // set index back to initial, error index should be the last // character examined. pos.setIndex(initialIndex); pos.setErrorIndex(startIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse denominator final BigInteger den = parseNextBigInteger(source, pos); if (den == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } if (den.compareTo(BigInteger.ZERO) < 0) { // minus signs must be leading, invalid pos.setIndex(initialIndex); return null; } boolean wholeIsNeg = whole.compareTo(BigInteger.ZERO) < 0; if (wholeIsNeg) { whole = whole.negate(); } num = whole.multiply(den).add(num); if (wholeIsNeg) { num = num.negate(); } return new BigFraction(num, den); } /** * Modify the whole format. * @param format The new whole format value. * @throws NullArgumentException if {@code format} is {@code null}. */ public void setWholeFormat(final NumberFormat format) { if (format == null) { throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT); } this.wholeFormat = format; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/AbstractFormat.java100644 1750 1750 17010 11532241244 27746 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Common part shared by both {@link FractionFormat} and {@link BigFractionFormat}. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ * @since 2.0 */ public abstract class AbstractFormat extends NumberFormat implements Serializable { /** Serializable version identifier. */ private static final long serialVersionUID = -6981118387974191891L; /** The format used for the denominator. */ protected NumberFormat denominatorFormat; /** The format used for the numerator. */ protected NumberFormat numeratorFormat; /** * Create an improper formatting instance with the default number format * for the numerator and denominator. */ protected AbstractFormat() { this(getDefaultNumberFormat()); } /** * Create an improper formatting instance with a custom number format for * both the numerator and denominator. * @param format the custom format for both the numerator and denominator. */ protected AbstractFormat(final NumberFormat format) { this(format, (NumberFormat) format.clone()); } /** * Create an improper formatting instance with a custom number format for * the numerator and a custom number format for the denominator. * @param numeratorFormat the custom format for the numerator. * @param denominatorFormat the custom format for the denominator. */ protected AbstractFormat(final NumberFormat numeratorFormat, final NumberFormat denominatorFormat) { this.numeratorFormat = numeratorFormat; this.denominatorFormat = denominatorFormat; } /** * Create a default number format. The default number format is based on * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only * customizing is the maximum number of BigFraction digits, which is set to 0. * @return the default number format. */ protected static NumberFormat getDefaultNumberFormat() { return getDefaultNumberFormat(Locale.getDefault()); } /** * Create a default number format. The default number format is based on * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only * customizing is the maximum number of BigFraction digits, which is set to 0. * @param locale the specific locale used by the format. * @return the default number format specific to the given locale. */ protected static NumberFormat getDefaultNumberFormat(final Locale locale) { final NumberFormat nf = NumberFormat.getNumberInstance(locale); nf.setMaximumFractionDigits(0); nf.setParseIntegerOnly(true); return nf; } /** * Access the denominator format. * @return the denominator format. */ public NumberFormat getDenominatorFormat() { return denominatorFormat; } /** * Access the numerator format. * @return the numerator format. */ public NumberFormat getNumeratorFormat() { return numeratorFormat; } /** * Modify the denominator format. * @param format the new denominator format value. * @throws NullArgumentException if {@code format} is {@code null}. */ public void setDenominatorFormat(final NumberFormat format) { if (format == null) { throw new NullArgumentException(LocalizedFormats.DENOMINATOR_FORMAT); } this.denominatorFormat = format; } /** * Modify the numerator format. * @param format the new numerator format value. * @throws NullArgumentException if {@code format} is {@code null}. */ public void setNumeratorFormat(final NumberFormat format) { if (format == null) { throw new NullArgumentException(LocalizedFormats.NUMERATOR_FORMAT); } this.numeratorFormat = format; } /** * Parses source until a non-whitespace character is found. * @param source the string to parse * @param pos input/ouput parsing parameter. On output, pos * holds the index of the next non-whitespace character. */ protected static void parseAndIgnoreWhitespace(final String source, final ParsePosition pos) { parseNextCharacter(source, pos); pos.setIndex(pos.getIndex() - 1); } /** * Parses source until a non-whitespace character is found. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the first non-whitespace character. */ protected static char parseNextCharacter(final String source, final ParsePosition pos) { int index = pos.getIndex(); final int n = source.length(); char ret = 0; if (index < n) { char c; do { c = source.charAt(index++); } while (Character.isWhitespace(c) && index < n); pos.setIndex(index); if (index < n) { ret = c; } } return ret; } /** * Formats a double value as a fraction and appends the result to a StringBuffer. * * @param value the double value to format * @param buffer StringBuffer to append to * @param position On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return a reference to the appended buffer * @see #format(Object, StringBuffer, FieldPosition) */ @Override public StringBuffer format(final double value, final StringBuffer buffer, final FieldPosition position) { return format(Double.valueOf(value), buffer, position); } /** * Formats a long value as a fraction and appends the result to a StringBuffer. * * @param value the long value to format * @param buffer StringBuffer to append to * @param position On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return a reference to the appended buffer * @see #format(Object, StringBuffer, FieldPosition) */ @Override public StringBuffer format(final long value, final StringBuffer buffer, final FieldPosition position) { return format(Long.valueOf(value), buffer, position); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/FractionFormat.java100644 1750 1750 23576 11532241244 27766 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import java.util.Locale; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Formats a Fraction number in proper format or improper format. The number * format for each of the whole number, numerator and, denominator can be * configured. * * @since 1.1 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class FractionFormat extends AbstractFormat { /** Serializable version identifier */ private static final long serialVersionUID = 3008655719530972611L; /** * Create an improper formatting instance with the default number format * for the numerator and denominator. */ public FractionFormat() { } /** * Create an improper formatting instance with a custom number format for * both the numerator and denominator. * @param format the custom format for both the numerator and denominator. */ public FractionFormat(final NumberFormat format) { super(format); } /** * Create an improper formatting instance with a custom number format for * the numerator and a custom number format for the denominator. * @param numeratorFormat the custom format for the numerator. * @param denominatorFormat the custom format for the denominator. */ public FractionFormat(final NumberFormat numeratorFormat, final NumberFormat denominatorFormat) { super(numeratorFormat, denominatorFormat); } /** * Get the set of locales for which complex formats are available. This * is the same set as the {@link NumberFormat} set. * @return available complex format locales. */ public static Locale[] getAvailableLocales() { return NumberFormat.getAvailableLocales(); } /** * This static method calls formatFraction() on a default instance of * FractionFormat. * * @param f Fraction object to format * @return A formatted fraction in proper form. */ public static String formatFraction(Fraction f) { return getImproperInstance().format(f); } /** * Returns the default complex format for the current locale. * @return the default complex format. */ public static FractionFormat getImproperInstance() { return getImproperInstance(Locale.getDefault()); } /** * Returns the default complex format for the given locale. * @param locale the specific locale used by the format. * @return the complex format specific to the given locale. */ public static FractionFormat getImproperInstance(final Locale locale) { return new FractionFormat(getDefaultNumberFormat(locale)); } /** * Returns the default complex format for the current locale. * @return the default complex format. */ public static FractionFormat getProperInstance() { return getProperInstance(Locale.getDefault()); } /** * Returns the default complex format for the given locale. * @param locale the specific locale used by the format. * @return the complex format specific to the given locale. */ public static FractionFormat getProperInstance(final Locale locale) { return new ProperFractionFormat(getDefaultNumberFormat(locale)); } /** * Create a default number format. The default number format is based on * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only * customizing is the maximum number of fraction digits, which is set to 0. * @return the default number format. */ protected static NumberFormat getDefaultNumberFormat() { return getDefaultNumberFormat(Locale.getDefault()); } /** * Formats a {@link Fraction} object to produce a string. The fraction is * output in improper format. * * @param fraction the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ public StringBuffer format(final Fraction fraction, final StringBuffer toAppendTo, final FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos); toAppendTo.append(" / "); getDenominatorFormat().format(fraction.getDenominator(), toAppendTo, pos); return toAppendTo; } /** * Formats an object and appends the result to a StringBuffer. obj must be either a * {@link Fraction} object or a {@link Number} object. Any other type of * object will result in an {@link IllegalArgumentException} being thrown. * * @param obj the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) * @throws IllegalArgumentException is obj is not a valid type. */ @Override public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) { StringBuffer ret = null; if (obj instanceof Fraction) { ret = format((Fraction) obj, toAppendTo, pos); } else if (obj instanceof Number) { try { ret = format(new Fraction(((Number) obj).doubleValue()), toAppendTo, pos); } catch (ConvergenceException ex) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_CONVERT_OBJECT_TO_FRACTION, ex.getLocalizedMessage()); } } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION); } return ret; } /** * Parses a string to produce a {@link Fraction} object. * @param source the string to parse * @return the parsed {@link Fraction} object. * @exception ParseException if the beginning of the specified string * cannot be parsed. */ @Override public Fraction parse(final String source) throws ParseException { final ParsePosition parsePosition = new ParsePosition(0); final Fraction result = parse(source, parsePosition); if (parsePosition.getIndex() == 0) { throw MathRuntimeException.createParseException( parsePosition.getErrorIndex(), LocalizedFormats.UNPARSEABLE_FRACTION_NUMBER, source); } return result; } /** * Parses a string to produce a {@link Fraction} object. This method * expects the string to be formatted as an improper fraction. * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link Fraction} object. */ @Override public Fraction parse(final String source, final ParsePosition pos) { final int initialIndex = pos.getIndex(); // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse numerator final Number num = getNumeratorFormat().parse(source, pos); if (num == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } // parse '/' final int startIndex = pos.getIndex(); final char c = parseNextCharacter(source, pos); switch (c) { case 0 : // no '/' // return num as a fraction return new Fraction(num.intValue(), 1); case '/' : // found '/', continue parsing denominator break; default : // invalid '/' // set index back to initial, error index should be the last // character examined. pos.setIndex(initialIndex); pos.setErrorIndex(startIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse denominator final Number den = getDenominatorFormat().parse(source, pos); if (den == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } return new Fraction(num.intValue(), den.intValue()); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/package.html100644 1750 1750 1727 11532241244 26440 0ustarlucluc 0 0 Fraction number type and fraction number formatting. commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/BigFraction.java100644 1750 1750 111067 11532241244 27250 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Representation of a rational number without any overflow. This class is * immutable. * * @version $Revision: 1073687 $ $Date: 2011-02-23 11:39:25 +0100 (mer. 23 févr. 2011) $ * @since 2.0 */ public class BigFraction extends Number implements FieldElement, Comparable, Serializable { /** A fraction representing "2 / 1". */ public static final BigFraction TWO = new BigFraction(2); /** A fraction representing "1". */ public static final BigFraction ONE = new BigFraction(1); /** A fraction representing "0". */ public static final BigFraction ZERO = new BigFraction(0); /** A fraction representing "-1 / 1". */ public static final BigFraction MINUS_ONE = new BigFraction(-1); /** A fraction representing "4/5". */ public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5); /** A fraction representing "1/5". */ public static final BigFraction ONE_FIFTH = new BigFraction(1, 5); /** A fraction representing "1/2". */ public static final BigFraction ONE_HALF = new BigFraction(1, 2); /** A fraction representing "1/4". */ public static final BigFraction ONE_QUARTER = new BigFraction(1, 4); /** A fraction representing "1/3". */ public static final BigFraction ONE_THIRD = new BigFraction(1, 3); /** A fraction representing "3/5". */ public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5); /** A fraction representing "3/4". */ public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4); /** A fraction representing "2/5". */ public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5); /** A fraction representing "2/4". */ public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4); /** A fraction representing "2/3". */ public static final BigFraction TWO_THIRDS = new BigFraction(2, 3); /** Serializable version identifier. */ private static final long serialVersionUID = -5630213147331578515L; /** BigInteger representation of 100. */ private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100); /** The numerator. */ private final BigInteger numerator; /** The denominator. */ private final BigInteger denominator; /** *

                        * Create a {@link BigFraction} equivalent to the passed BigInteger, ie * "num / 1". *

                        * * @param num * the numerator. */ public BigFraction(final BigInteger num) { this(num, BigInteger.ONE); } /** * Create a {@link BigFraction} given the numerator and denominator as * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms. * * @param num the numerator, must not be {@code null}. * @param den the denominator, must not be {@code null}.. * @throws ArithmeticException if the denominator is zero. */ public BigFraction(BigInteger num, BigInteger den) { if (num == null) { throw new NullPointerException(LocalizedFormats.NUMERATOR.getSourceString()); } if (den == null) { throw new NullPointerException(LocalizedFormats.DENOMINATOR.getSourceString()); } if (BigInteger.ZERO.equals(den)) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); } if (BigInteger.ZERO.equals(num)) { numerator = BigInteger.ZERO; denominator = BigInteger.ONE; } else { // reduce numerator and denominator by greatest common denominator final BigInteger gcd = num.gcd(den); if (BigInteger.ONE.compareTo(gcd) < 0) { num = num.divide(gcd); den = den.divide(gcd); } // move sign to numerator if (BigInteger.ZERO.compareTo(den) > 0) { num = num.negate(); den = den.negate(); } // store the values in the final fields numerator = num; denominator = den; } } /** * Create a fraction given the double value. *

                        * This constructor behaves differently from * {@link #BigFraction(double, double, int)}. It converts the * double value exactly, considering its internal bits representation. * This does work for all values except NaN and infinities and does * not requires any loop or convergence threshold. *

                        *

                        * Since this conversion is exact and since double numbers are sometimes * approximated, the fraction created may seem strange in some cases. For example * calling new BigFraction(1.0 / 3.0) does not create * the fraction 1/3 but the fraction 6004799503160661 / 18014398509481984 * because the double number passed to the constructor is not exactly 1/3 * (this number cannot be stored exactly in IEEE754). *

                        * @see #BigFraction(double, double, int) * @param value the double value to convert to a fraction. * @exception IllegalArgumentException if value is NaN or infinite */ public BigFraction(final double value) throws IllegalArgumentException { if (Double.isNaN(value)) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION); } if (Double.isInfinite(value)) { throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.INFINITE_VALUE_CONVERSION); } // compute m and k such that value = m * 2^k final long bits = Double.doubleToLongBits(value); final long sign = bits & 0x8000000000000000L; final long exponent = bits & 0x7ff0000000000000L; long m = bits & 0x000fffffffffffffL; if (exponent != 0) { // this was a normalized number, add the implicit most significant bit m |= 0x0010000000000000L; } if (sign != 0) { m = -m; } int k = ((int) (exponent >> 52)) - 1075; while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) { m = m >> 1; ++k; } if (k < 0) { numerator = BigInteger.valueOf(m); denominator = BigInteger.ZERO.flipBit(-k); } else { numerator = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k)); denominator = BigInteger.ONE; } } /** * Create a fraction given the double value and maximum error allowed. *

                        * References: *

                        *

                        * * @param value * the double value to convert to a fraction. * @param epsilon * maximum error allowed. The resulting fraction is within * epsilon of value, in absolute terms. * @param maxIterations * maximum number of convergents. * @throws FractionConversionException * if the continued fraction failed to converge. * @see #BigFraction(double) */ public BigFraction(final double value, final double epsilon, final int maxIterations) throws FractionConversionException { this(value, epsilon, Integer.MAX_VALUE, maxIterations); } /** * Create a fraction given the double value and either the maximum error * allowed or the maximum number of denominator digits. *

                        * * NOTE: This constructor is called with EITHER - a valid epsilon value and * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator * has no effect). OR - a valid maxDenominator value and the epsilon value * set to zero (that way epsilon only has effect if there is an exact match * before the maxDenominator value is reached). *

                        *

                        * * It has been done this way so that the same code can be (re)used for both * scenarios. However this could be confusing to users if it were part of * the public API and this constructor should therefore remain PRIVATE. *

                        * * See JIRA issue ticket MATH-181 for more details: * * https://issues.apache.org/jira/browse/MATH-181 * * @param value * the double value to convert to a fraction. * @param epsilon * maximum error allowed. The resulting fraction is within * epsilon of value, in absolute terms. * @param maxDenominator * maximum denominator value allowed. * @param maxIterations * maximum number of convergents. * @throws FractionConversionException * if the continued fraction failed to converge. */ private BigFraction(final double value, final double epsilon, final int maxDenominator, int maxIterations) throws FractionConversionException { long overflow = Integer.MAX_VALUE; double r0 = value; long a0 = (long) FastMath.floor(r0); if (a0 > overflow) { throw new FractionConversionException(value, a0, 1l); } // check for (almost) integer arguments, which should not go // to iterations. if (FastMath.abs(a0 - value) < epsilon) { numerator = BigInteger.valueOf(a0); denominator = BigInteger.ONE; return; } long p0 = 1; long q0 = 0; long p1 = a0; long q1 = 1; long p2 = 0; long q2 = 1; int n = 0; boolean stop = false; do { ++n; final double r1 = 1.0 / (r0 - a0); final long a1 = (long) FastMath.floor(r1); p2 = (a1 * p1) + p0; q2 = (a1 * q1) + q0; if ((p2 > overflow) || (q2 > overflow)) { throw new FractionConversionException(value, p2, q2); } final double convergent = (double) p2 / (double) q2; if ((n < maxIterations) && (FastMath.abs(convergent - value) > epsilon) && (q2 < maxDenominator)) { p0 = p1; p1 = p2; q0 = q1; q1 = q2; a0 = a1; r0 = r1; } else { stop = true; } } while (!stop); if (n >= maxIterations) { throw new FractionConversionException(value, maxIterations); } if (q2 < maxDenominator) { numerator = BigInteger.valueOf(p2); denominator = BigInteger.valueOf(q2); } else { numerator = BigInteger.valueOf(p1); denominator = BigInteger.valueOf(q1); } } /** * Create a fraction given the double value and maximum denominator. *

                        * References: *

                        *

                        * * @param value * the double value to convert to a fraction. * @param maxDenominator * The maximum allowed value for denominator. * @throws FractionConversionException * if the continued fraction failed to converge. */ public BigFraction(final double value, final int maxDenominator) throws FractionConversionException { this(value, 0, maxDenominator, 100); } /** *

                        * Create a {@link BigFraction} equivalent to the passed int, ie * "num / 1". *

                        * * @param num * the numerator. */ public BigFraction(final int num) { this(BigInteger.valueOf(num), BigInteger.ONE); } /** *

                        * Create a {@link BigFraction} given the numerator and denominator as simple * int. The {@link BigFraction} is reduced to lowest terms. *

                        * * @param num * the numerator. * @param den * the denominator. */ public BigFraction(final int num, final int den) { this(BigInteger.valueOf(num), BigInteger.valueOf(den)); } /** *

                        * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1". *

                        * * @param num * the numerator. */ public BigFraction(final long num) { this(BigInteger.valueOf(num), BigInteger.ONE); } /** *

                        * Create a {@link BigFraction} given the numerator and denominator as simple * long. The {@link BigFraction} is reduced to lowest terms. *

                        * * @param num * the numerator. * @param den * the denominator. */ public BigFraction(final long num, final long den) { this(BigInteger.valueOf(num), BigInteger.valueOf(den)); } /** *

                        * Creates a BigFraction instance with the 2 parts of a fraction * Y/Z. *

                        * *

                        * Any negative signs are resolved to be on the numerator. *

                        * * @param numerator * the numerator, for example the three in 'three sevenths'. * @param denominator * the denominator, for example the seven in 'three sevenths'. * @return a new fraction instance, with the numerator and denominator * reduced. * @throws ArithmeticException * if the denominator is zero. */ public static BigFraction getReducedFraction(final int numerator, final int denominator) { if (numerator == 0) { return ZERO; // normalize zero. } return new BigFraction(numerator, denominator); } /** *

                        * Returns the absolute value of this {@link BigFraction}. *

                        * * @return the absolute value as a {@link BigFraction}. */ public BigFraction abs() { return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate(); } /** *

                        * Adds the value of this fraction to the passed {@link BigInteger}, * returning the result in reduced form. *

                        * * @param bg * the {@link BigInteger} to add, must'nt be null. * @return a BigFraction instance with the resulting values. * @throws NullPointerException * if the {@link BigInteger} is null. */ public BigFraction add(final BigInteger bg) { return new BigFraction(numerator.add(denominator.multiply(bg)), denominator); } /** *

                        * Adds the value of this fraction to the passed integer, returning * the result in reduced form. *

                        * * @param i * the integer to add. * @return a BigFraction instance with the resulting values. */ public BigFraction add(final int i) { return add(BigInteger.valueOf(i)); } /** *

                        * Adds the value of this fraction to the passed long, returning * the result in reduced form. *

                        * * @param l * the long to add. * @return a BigFraction instance with the resulting values. */ public BigFraction add(final long l) { return add(BigInteger.valueOf(l)); } /** *

                        * Adds the value of this fraction to another, returning the result in * reduced form. *

                        * * @param fraction * the {@link BigFraction} to add, must not be null. * @return a {@link BigFraction} instance with the resulting values. * @throws NullPointerException if the {@link BigFraction} is {@code null}. */ public BigFraction add(final BigFraction fraction) { if (fraction == null) { throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString()); } if (ZERO.equals(fraction)) { return this; } BigInteger num = null; BigInteger den = null; if (denominator.equals(fraction.denominator)) { num = numerator.add(fraction.numerator); den = denominator; } else { num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator)); den = denominator.multiply(fraction.denominator); } return new BigFraction(num, den); } /** *

                        * Gets the fraction as a BigDecimal. This calculates the * fraction as the numerator divided by denominator. *

                        * * @return the fraction as a BigDecimal. * @throws ArithmeticException * if the exact quotient does not have a terminating decimal * expansion. * @see BigDecimal */ public BigDecimal bigDecimalValue() { return new BigDecimal(numerator).divide(new BigDecimal(denominator)); } /** *

                        * Gets the fraction as a BigDecimal following the passed * rounding mode. This calculates the fraction as the numerator divided by * denominator. *

                        * * @param roundingMode * rounding mode to apply. see {@link BigDecimal} constants. * @return the fraction as a BigDecimal. * @throws IllegalArgumentException * if roundingMode does not represent a valid rounding * mode. * @see BigDecimal */ public BigDecimal bigDecimalValue(final int roundingMode) { return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode); } /** *

                        * Gets the fraction as a BigDecimal following the passed scale * and rounding mode. This calculates the fraction as the numerator divided * by denominator. *

                        * * @param scale * scale of the BigDecimal quotient to be returned. * see {@link BigDecimal} for more information. * @param roundingMode * rounding mode to apply. see {@link BigDecimal} constants. * @return the fraction as a BigDecimal. * @see BigDecimal */ public BigDecimal bigDecimalValue(final int scale, final int roundingMode) { return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode); } /** *

                        * Compares this object to another based on size. *

                        * * @param object * the object to compare to, must not be null. * @return -1 if this is less than object, +1 if this is greater * than object, 0 if they are equal. * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(final BigFraction object) { BigInteger nOd = numerator.multiply(object.denominator); BigInteger dOn = denominator.multiply(object.numerator); return nOd.compareTo(dOn); } /** *

                        * Divide the value of this fraction by the passed BigInteger, * ie "this * 1 / bg", returning the result in reduced form. *

                        * * @param bg * the BigInteger to divide by, must not be * null. * @return a {@link BigFraction} instance with the resulting values. * @throws NullPointerException if the {@code BigInteger} is {@code null}. * @throws ArithmeticException * if the fraction to divide by is zero. */ public BigFraction divide(final BigInteger bg) { if (BigInteger.ZERO.equals(bg)) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); } return new BigFraction(numerator, denominator.multiply(bg)); } /** *

                        * Divide the value of this fraction by the passed int, ie * "this * 1 / i", returning the result in reduced form. *

                        * * @param i * the int to divide by. * @return a {@link BigFraction} instance with the resulting values. * @throws ArithmeticException * if the fraction to divide by is zero. */ public BigFraction divide(final int i) { return divide(BigInteger.valueOf(i)); } /** *

                        * Divide the value of this fraction by the passed long, ie * "this * 1 / l", returning the result in reduced form. *

                        * * @param l * the long to divide by. * @return a {@link BigFraction} instance with the resulting values. * @throws ArithmeticException * if the fraction to divide by is zero. */ public BigFraction divide(final long l) { return divide(BigInteger.valueOf(l)); } /** *

                        * Divide the value of this fraction by another, returning the result in * reduced form. *

                        * * @param fraction Fraction to divide by, must not be {@code null}. * @return a {@link BigFraction} instance with the resulting values. * @throws NullPointerException if the {@code fraction} is {@code null}. * @throws ArithmeticException if the fraction to divide by is zero. */ public BigFraction divide(final BigFraction fraction) { if (fraction == null) { throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString()); } if (BigInteger.ZERO.equals(fraction.numerator)) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); } return multiply(fraction.reciprocal()); } /** *

                        * Gets the fraction as a double. This calculates the fraction as * the numerator divided by denominator. *

                        * * @return the fraction as a double * @see java.lang.Number#doubleValue() */ @Override public double doubleValue() { return numerator.doubleValue() / denominator.doubleValue(); } /** *

                        * Test for the equality of two fractions. If the lowest term numerator and * denominators are the same for both fractions, the two fractions are * considered to be equal. *

                        * * @param other * fraction to test for equality to this fraction, can be * null. * @return true if two fractions are equal, false if object is * null, not an instance of {@link BigFraction}, or not * equal to this fraction instance. * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(final Object other) { boolean ret = false; if (this == other) { ret = true; } else if (other instanceof BigFraction) { BigFraction rhs = ((BigFraction) other).reduce(); BigFraction thisOne = this.reduce(); ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator); } return ret; } /** *

                        * Gets the fraction as a float. This calculates the fraction as * the numerator divided by denominator. *

                        * * @return the fraction as a float. * @see java.lang.Number#floatValue() */ @Override public float floatValue() { return numerator.floatValue() / denominator.floatValue(); } /** *

                        * Access the denominator as a BigInteger. *

                        * * @return the denominator as a BigInteger. */ public BigInteger getDenominator() { return denominator; } /** *

                        * Access the denominator as a int. *

                        * * @return the denominator as a int. */ public int getDenominatorAsInt() { return denominator.intValue(); } /** *

                        * Access the denominator as a long. *

                        * * @return the denominator as a long. */ public long getDenominatorAsLong() { return denominator.longValue(); } /** *

                        * Access the numerator as a BigInteger. *

                        * * @return the numerator as a BigInteger. */ public BigInteger getNumerator() { return numerator; } /** *

                        * Access the numerator as a int. *

                        * * @return the numerator as a int. */ public int getNumeratorAsInt() { return numerator.intValue(); } /** *

                        * Access the numerator as a long. *

                        * * @return the numerator as a long. */ public long getNumeratorAsLong() { return numerator.longValue(); } /** *

                        * Gets a hashCode for the fraction. *

                        * * @return a hash code value for this object. * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode(); } /** *

                        * Gets the fraction as an int. This returns the whole number part * of the fraction. *

                        * * @return the whole number fraction part. * @see java.lang.Number#intValue() */ @Override public int intValue() { return numerator.divide(denominator).intValue(); } /** *

                        * Gets the fraction as a long. This returns the whole number part * of the fraction. *

                        * * @return the whole number fraction part. * @see java.lang.Number#longValue() */ @Override public long longValue() { return numerator.divide(denominator).longValue(); } /** *

                        * Multiplies the value of this fraction by the passed * BigInteger, returning the result in reduced form. *

                        * * @param bg the {@code BigInteger} to multiply by. * @return a {@code BigFraction} instance with the resulting values. * @throws NullPointerException if {@code bg} is {@code null}. */ public BigFraction multiply(final BigInteger bg) { if (bg == null) { throw new NullPointerException(); } return new BigFraction(bg.multiply(numerator), denominator); } /** *

                        * Multiply the value of this fraction by the passed int, returning * the result in reduced form. *

                        * * @param i * the int to multiply by. * @return a {@link BigFraction} instance with the resulting values. */ public BigFraction multiply(final int i) { return multiply(BigInteger.valueOf(i)); } /** *

                        * Multiply the value of this fraction by the passed long, * returning the result in reduced form. *

                        * * @param l * the long to multiply by. * @return a {@link BigFraction} instance with the resulting values. */ public BigFraction multiply(final long l) { return multiply(BigInteger.valueOf(l)); } /** *

                        * Multiplies the value of this fraction by another, returning the result in * reduced form. *

                        * * @param fraction Fraction to multiply by, must not be {@code null}. * @return a {@link BigFraction} instance with the resulting values. * @throws NullPointerException if {@code fraction} is {@code null}. */ public BigFraction multiply(final BigFraction fraction) { if (fraction == null) { throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString()); } if (numerator.equals(BigInteger.ZERO) || fraction.numerator.equals(BigInteger.ZERO)) { return ZERO; } return new BigFraction(numerator.multiply(fraction.numerator), denominator.multiply(fraction.denominator)); } /** *

                        * Return the additive inverse of this fraction, returning the result in * reduced form. *

                        * * @return the negation of this fraction. */ public BigFraction negate() { return new BigFraction(numerator.negate(), denominator); } /** *

                        * Gets the fraction percentage as a double. This calculates the * fraction as the numerator divided by denominator multiplied by 100. *

                        * * @return the fraction percentage as a double. */ public double percentageValue() { return (numerator.divide(denominator)).multiply(ONE_HUNDRED_DOUBLE).doubleValue(); } /** *

                        * Returns a integer whose value is * (thisexponent), returning the result in reduced form. *

                        * * @param exponent * exponent to which this BigInteger is to be * raised. * @return thisexponent. */ public BigFraction pow(final int exponent) { if (exponent < 0) { return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent)); } return new BigFraction(numerator.pow(exponent), denominator.pow(exponent)); } /** *

                        * Returns a BigFraction whose value is * (thisexponent), returning the result in reduced form. *

                        * * @param exponent * exponent to which this BigFraction is to be raised. * @return thisexponent as a BigFraction. */ public BigFraction pow(final long exponent) { if (exponent < 0) { return new BigFraction(MathUtils.pow(denominator, -exponent), MathUtils.pow(numerator, -exponent)); } return new BigFraction(MathUtils.pow(numerator, exponent), MathUtils.pow(denominator, exponent)); } /** *

                        * Returns a BigFraction whose value is * (thisexponent), returning the result in reduced form. *

                        * * @param exponent * exponent to which this BigFraction is to be raised. * @return thisexponent as a BigFraction. */ public BigFraction pow(final BigInteger exponent) { if (exponent.compareTo(BigInteger.ZERO) < 0) { final BigInteger eNeg = exponent.negate(); return new BigFraction(MathUtils.pow(denominator, eNeg), MathUtils.pow(numerator, eNeg)); } return new BigFraction(MathUtils.pow(numerator, exponent), MathUtils.pow(denominator, exponent)); } /** *

                        * Returns a double whose value is * (thisexponent), returning the result in reduced form. *

                        * * @param exponent * exponent to which this BigFraction is to be raised. * @return thisexponent. */ public double pow(final double exponent) { return FastMath.pow(numerator.doubleValue(), exponent) / FastMath.pow(denominator.doubleValue(), exponent); } /** *

                        * Return the multiplicative inverse of this fraction. *

                        * * @return the reciprocal fraction. */ public BigFraction reciprocal() { return new BigFraction(denominator, numerator); } /** *

                        * Reduce this BigFraction to its lowest terms. *

                        * * @return the reduced BigFraction. It doesn't change anything if * the fraction can be reduced. */ public BigFraction reduce() { final BigInteger gcd = numerator.gcd(denominator); return new BigFraction(numerator.divide(gcd), denominator.divide(gcd)); } /** *

                        * Subtracts the value of an {@link BigInteger} from the value of this one, * returning the result in reduced form. *

                        * * @param bg the {@link BigInteger} to subtract, cannot be {@code null}. * @return a {@code BigFraction} instance with the resulting values. * @throws NullPointerException if the {@link BigInteger} is {@code null}. */ public BigFraction subtract(final BigInteger bg) { if (bg == null) { throw new NullPointerException(); } return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator); } /** *

                        * Subtracts the value of an integer from the value of this one, * returning the result in reduced form. *

                        * * @param i * the integer to subtract. * @return a BigFraction instance with the resulting values. */ public BigFraction subtract(final int i) { return subtract(BigInteger.valueOf(i)); } /** *

                        * Subtracts the value of an integer from the value of this one, * returning the result in reduced form. *

                        * * @param l * the long to subtract. * @return a BigFraction instance with the resulting values, or * this object if the long is zero. */ public BigFraction subtract(final long l) { return subtract(BigInteger.valueOf(l)); } /** *

                        * Subtracts the value of another fraction from the value of this one, * returning the result in reduced form. *

                        * * @param fraction {@link BigFraction} to subtract, must not be {@code null}. * @return a {@link BigFraction} instance with the resulting values * @throws NullPointerException if the {@code fraction} is {@code null}. */ public BigFraction subtract(final BigFraction fraction) { if (fraction == null) { throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString()); } if (ZERO.equals(fraction)) { return this; } BigInteger num = null; BigInteger den = null; if (denominator.equals(fraction.denominator)) { num = numerator.subtract(fraction.numerator); den = denominator; } else { num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator)); den = denominator.multiply(fraction.denominator); } return new BigFraction(num, den); } /** *

                        * Returns the String representing this fraction, ie * "num / dem" or just "num" if the denominator is one. *

                        * * @return a string representation of the fraction. * @see java.lang.Object#toString() */ @Override public String toString() { String str = null; if (BigInteger.ONE.equals(denominator)) { str = numerator.toString(); } else if (BigInteger.ZERO.equals(numerator)) { str = "0"; } else { str = numerator + " / " + denominator; } return str; } /** {@inheritDoc} */ public BigFractionField getField() { return BigFractionField.getInstance(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/Fraction.java100644 1750 1750 55163 11532241244 26612 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import java.math.BigInteger; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.FastMath; /** * Representation of a rational number. * * implements Serializable since 2.0 * * @since 1.1 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class Fraction extends Number implements FieldElement, Comparable, Serializable { /** A fraction representing "2 / 1". */ public static final Fraction TWO = new Fraction(2, 1); /** A fraction representing "1". */ public static final Fraction ONE = new Fraction(1, 1); /** A fraction representing "0". */ public static final Fraction ZERO = new Fraction(0, 1); /** A fraction representing "4/5". */ public static final Fraction FOUR_FIFTHS = new Fraction(4, 5); /** A fraction representing "1/5". */ public static final Fraction ONE_FIFTH = new Fraction(1, 5); /** A fraction representing "1/2". */ public static final Fraction ONE_HALF = new Fraction(1, 2); /** A fraction representing "1/4". */ public static final Fraction ONE_QUARTER = new Fraction(1, 4); /** A fraction representing "1/3". */ public static final Fraction ONE_THIRD = new Fraction(1, 3); /** A fraction representing "3/5". */ public static final Fraction THREE_FIFTHS = new Fraction(3, 5); /** A fraction representing "3/4". */ public static final Fraction THREE_QUARTERS = new Fraction(3, 4); /** A fraction representing "2/5". */ public static final Fraction TWO_FIFTHS = new Fraction(2, 5); /** A fraction representing "2/4". */ public static final Fraction TWO_QUARTERS = new Fraction(2, 4); /** A fraction representing "2/3". */ public static final Fraction TWO_THIRDS = new Fraction(2, 3); /** A fraction representing "-1 / 1". */ public static final Fraction MINUS_ONE = new Fraction(-1, 1); /** Serializable version identifier */ private static final long serialVersionUID = 3698073679419233275L; /** The denominator. */ private final int denominator; /** The numerator. */ private final int numerator; /** * Create a fraction given the double value. * @param value the double value to convert to a fraction. * @throws FractionConversionException if the continued fraction failed to * converge. */ public Fraction(double value) throws FractionConversionException { this(value, 1.0e-5, 100); } /** * Create a fraction given the double value and maximum error allowed. *

                        * References: *

                        *

                        * @param value the double value to convert to a fraction. * @param epsilon maximum error allowed. The resulting fraction is within * epsilon of value, in absolute terms. * @param maxIterations maximum number of convergents * @throws FractionConversionException if the continued fraction failed to * converge. */ public Fraction(double value, double epsilon, int maxIterations) throws FractionConversionException { this(value, epsilon, Integer.MAX_VALUE, maxIterations); } /** * Create a fraction given the double value and maximum denominator. *

                        * References: *

                        *

                        * @param value the double value to convert to a fraction. * @param maxDenominator The maximum allowed value for denominator * @throws FractionConversionException if the continued fraction failed to * converge */ public Fraction(double value, int maxDenominator) throws FractionConversionException { this(value, 0, maxDenominator, 100); } /** * Create a fraction given the double value and either the maximum error * allowed or the maximum number of denominator digits. *

                        * * NOTE: This constructor is called with EITHER * - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE * (that way the maxDenominator has no effect). * OR * - a valid maxDenominator value and the epsilon value set to zero * (that way epsilon only has effect if there is an exact match before * the maxDenominator value is reached). *

                        * * It has been done this way so that the same code can be (re)used for both * scenarios. However this could be confusing to users if it were part of * the public API and this constructor should therefore remain PRIVATE. *

                        * * See JIRA issue ticket MATH-181 for more details: * * https://issues.apache.org/jira/browse/MATH-181 * * @param value the double value to convert to a fraction. * @param epsilon maximum error allowed. The resulting fraction is within * epsilon of value, in absolute terms. * @param maxDenominator maximum denominator value allowed. * @param maxIterations maximum number of convergents * @throws FractionConversionException if the continued fraction failed to * converge. */ private Fraction(double value, double epsilon, int maxDenominator, int maxIterations) throws FractionConversionException { long overflow = Integer.MAX_VALUE; double r0 = value; long a0 = (long)FastMath.floor(r0); if (a0 > overflow) { throw new FractionConversionException(value, a0, 1l); } // check for (almost) integer arguments, which should not go // to iterations. if (FastMath.abs(a0 - value) < epsilon) { this.numerator = (int) a0; this.denominator = 1; return; } long p0 = 1; long q0 = 0; long p1 = a0; long q1 = 1; long p2 = 0; long q2 = 1; int n = 0; boolean stop = false; do { ++n; double r1 = 1.0 / (r0 - a0); long a1 = (long)FastMath.floor(r1); p2 = (a1 * p1) + p0; q2 = (a1 * q1) + q0; if ((p2 > overflow) || (q2 > overflow)) { throw new FractionConversionException(value, p2, q2); } double convergent = (double)p2 / (double)q2; if (n < maxIterations && FastMath.abs(convergent - value) > epsilon && q2 < maxDenominator) { p0 = p1; p1 = p2; q0 = q1; q1 = q2; a0 = a1; r0 = r1; } else { stop = true; } } while (!stop); if (n >= maxIterations) { throw new FractionConversionException(value, maxIterations); } if (q2 < maxDenominator) { this.numerator = (int) p2; this.denominator = (int) q2; } else { this.numerator = (int) p1; this.denominator = (int) q1; } } /** * Create a fraction from an int. * The fraction is num / 1. * @param num the numerator. */ public Fraction(int num) { this(num, 1); } /** * Create a fraction given the numerator and denominator. The fraction is * reduced to lowest terms. * @param num the numerator. * @param den the denominator. * @throws ArithmeticException if the denominator is zero */ public Fraction(int num, int den) { if (den == 0) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, num, den); } if (den < 0) { if (num == Integer.MIN_VALUE || den == Integer.MIN_VALUE) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.OVERFLOW_IN_FRACTION, num, den); } num = -num; den = -den; } // reduce numerator and denominator by greatest common denominator. final int d = MathUtils.gcd(num, den); if (d > 1) { num /= d; den /= d; } // move sign to numerator. if (den < 0) { num = -num; den = -den; } this.numerator = num; this.denominator = den; } /** * Returns the absolute value of this fraction. * @return the absolute value. */ public Fraction abs() { Fraction ret; if (numerator >= 0) { ret = this; } else { ret = negate(); } return ret; } /** * Compares this object to another based on size. * @param object the object to compare to * @return -1 if this is less than object, +1 if this is greater * than object, 0 if they are equal. */ public int compareTo(Fraction object) { long nOd = ((long) numerator) * object.denominator; long dOn = ((long) denominator) * object.numerator; return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0); } /** * Gets the fraction as a double. This calculates the fraction as * the numerator divided by denominator. * @return the fraction as a double */ @Override public double doubleValue() { return (double)numerator / (double)denominator; } /** * Test for the equality of two fractions. If the lowest term * numerator and denominators are the same for both fractions, the two * fractions are considered to be equal. * @param other fraction to test for equality to this fraction * @return true if two fractions are equal, false if object is * null, not an instance of {@link Fraction}, or not equal * to this fraction instance. */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof Fraction) { // since fractions are always in lowest terms, numerators and // denominators can be compared directly for equality. Fraction rhs = (Fraction)other; return (numerator == rhs.numerator) && (denominator == rhs.denominator); } return false; } /** * Gets the fraction as a float. This calculates the fraction as * the numerator divided by denominator. * @return the fraction as a float */ @Override public float floatValue() { return (float)doubleValue(); } /** * Access the denominator. * @return the denominator. */ public int getDenominator() { return denominator; } /** * Access the numerator. * @return the numerator. */ public int getNumerator() { return numerator; } /** * Gets a hashCode for the fraction. * @return a hash code value for this object */ @Override public int hashCode() { return 37 * (37 * 17 + numerator) + denominator; } /** * Gets the fraction as an int. This returns the whole number part * of the fraction. * @return the whole number fraction part */ @Override public int intValue() { return (int)doubleValue(); } /** * Gets the fraction as a long. This returns the whole number part * of the fraction. * @return the whole number fraction part */ @Override public long longValue() { return (long)doubleValue(); } /** * Return the additive inverse of this fraction. * @return the negation of this fraction. */ public Fraction negate() { if (numerator==Integer.MIN_VALUE) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator); } return new Fraction(-numerator, denominator); } /** * Return the multiplicative inverse of this fraction. * @return the reciprocal fraction */ public Fraction reciprocal() { return new Fraction(denominator, numerator); } /** *

                        Adds the value of this fraction to another, returning the result in reduced form. * The algorithm follows Knuth, 4.5.1.

                        * * @param fraction the fraction to add, must not be null * @return a Fraction instance with the resulting values * @throws IllegalArgumentException if the fraction is null * @throws ArithmeticException if the resulting numerator or denominator exceeds * Integer.MAX_VALUE */ public Fraction add(Fraction fraction) { return addSub(fraction, true /* add */); } /** * Add an integer to the fraction. * @param i the integer to add. * @return this + i */ public Fraction add(final int i) { return new Fraction(numerator + i * denominator, denominator); } /** *

                        Subtracts the value of another fraction from the value of this one, * returning the result in reduced form.

                        * * @param fraction the fraction to subtract, must not be null * @return a Fraction instance with the resulting values * @throws IllegalArgumentException if the fraction is null * @throws ArithmeticException if the resulting numerator or denominator * cannot be represented in an int. */ public Fraction subtract(Fraction fraction) { return addSub(fraction, false /* subtract */); } /** * Subtract an integer from the fraction. * @param i the integer to subtract. * @return this - i */ public Fraction subtract(final int i) { return new Fraction(numerator - i * denominator, denominator); } /** * Implement add and subtract using algorithm described in Knuth 4.5.1. * * @param fraction the fraction to subtract, must not be null * @param isAdd true to add, false to subtract * @return a Fraction instance with the resulting values * @throws IllegalArgumentException if the fraction is null * @throws ArithmeticException if the resulting numerator or denominator * cannot be represented in an int. */ private Fraction addSub(Fraction fraction, boolean isAdd) { if (fraction == null) { throw new NullArgumentException(LocalizedFormats.FRACTION); } // zero is identity for addition. if (numerator == 0) { return isAdd ? fraction : fraction.negate(); } if (fraction.numerator == 0) { return this; } // if denominators are randomly distributed, d1 will be 1 about 61% // of the time. int d1 = MathUtils.gcd(denominator, fraction.denominator); if (d1==1) { // result is ( (u*v' +/- u'v) / u'v') int uvp = MathUtils.mulAndCheck(numerator, fraction.denominator); int upv = MathUtils.mulAndCheck(fraction.numerator, denominator); return new Fraction (isAdd ? MathUtils.addAndCheck(uvp, upv) : MathUtils.subAndCheck(uvp, upv), MathUtils.mulAndCheck(denominator, fraction.denominator)); } // the quantity 't' requires 65 bits of precision; see knuth 4.5.1 // exercise 7. we're going to use a BigInteger. // t = u(v'/d1) +/- v(u'/d1) BigInteger uvp = BigInteger.valueOf(numerator) .multiply(BigInteger.valueOf(fraction.denominator/d1)); BigInteger upv = BigInteger.valueOf(fraction.numerator) .multiply(BigInteger.valueOf(denominator/d1)); BigInteger t = isAdd ? uvp.add(upv) : uvp.subtract(upv); // but d2 doesn't need extra precision because // d2 = gcd(t,d1) = gcd(t mod d1, d1) int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue(); int d2 = (tmodd1==0)?d1:MathUtils.gcd(tmodd1, d1); // result is (t/d2) / (u'/d1)(v'/d2) BigInteger w = t.divide(BigInteger.valueOf(d2)); if (w.bitLength() > 31) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.NUMERATOR_OVERFLOW_AFTER_MULTIPLY, w); } return new Fraction (w.intValue(), MathUtils.mulAndCheck(denominator/d1, fraction.denominator/d2)); } /** *

                        Multiplies the value of this fraction by another, returning the * result in reduced form.

                        * * @param fraction the fraction to multiply by, must not be null * @return a Fraction instance with the resulting values * @throws IllegalArgumentException if the fraction is null * @throws ArithmeticException if the resulting numerator or denominator exceeds * Integer.MAX_VALUE */ public Fraction multiply(Fraction fraction) { if (fraction == null) { throw new NullArgumentException(LocalizedFormats.FRACTION); } if (numerator == 0 || fraction.numerator == 0) { return ZERO; } // knuth 4.5.1 // make sure we don't overflow unless the result *must* overflow. int d1 = MathUtils.gcd(numerator, fraction.denominator); int d2 = MathUtils.gcd(fraction.numerator, denominator); return getReducedFraction (MathUtils.mulAndCheck(numerator/d1, fraction.numerator/d2), MathUtils.mulAndCheck(denominator/d2, fraction.denominator/d1)); } /** * Multiply the fraction by an integer. * @param i the integer to multiply by. * @return this * i */ public Fraction multiply(final int i) { return new Fraction(numerator * i, denominator); } /** *

                        Divide the value of this fraction by another.

                        * * @param fraction the fraction to divide by, must not be null * @return a Fraction instance with the resulting values * @throws IllegalArgumentException if the fraction is null * @throws ArithmeticException if the fraction to divide by is zero * @throws ArithmeticException if the resulting numerator or denominator exceeds * Integer.MAX_VALUE */ public Fraction divide(Fraction fraction) { if (fraction == null) { throw new NullArgumentException(LocalizedFormats.FRACTION); } if (fraction.numerator == 0) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.ZERO_FRACTION_TO_DIVIDE_BY, fraction.numerator, fraction.denominator); } return multiply(fraction.reciprocal()); } /** * Divide the fraction by an integer. * @param i the integer to divide by. * @return this * i */ public Fraction divide(final int i) { return new Fraction(numerator, denominator * i); } /** *

                        Creates a Fraction instance with the 2 parts * of a fraction Y/Z.

                        * *

                        Any negative signs are resolved to be on the numerator.

                        * * @param numerator the numerator, for example the three in 'three sevenths' * @param denominator the denominator, for example the seven in 'three sevenths' * @return a new fraction instance, with the numerator and denominator reduced * @throws ArithmeticException if the denominator is zero */ public static Fraction getReducedFraction(int numerator, int denominator) { if (denominator == 0) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, numerator, denominator); } if (numerator==0) { return ZERO; // normalize zero. } // allow 2^k/-2^31 as a valid fraction (where k>0) if (denominator==Integer.MIN_VALUE && (numerator&1)==0) { numerator/=2; denominator/=2; } if (denominator < 0) { if (numerator==Integer.MIN_VALUE || denominator==Integer.MIN_VALUE) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator); } numerator = -numerator; denominator = -denominator; } // simplify fraction. int gcd = MathUtils.gcd(numerator, denominator); numerator /= gcd; denominator /= gcd; return new Fraction(numerator, denominator); } /** *

                        * Returns the String representing this fraction, ie * "num / dem" or just "num" if the denominator is one. *

                        * * @return a string representation of the fraction. * @see java.lang.Object#toString() */ @Override public String toString() { String str = null; if (denominator == 1) { str = Integer.toString(numerator); } else if (numerator == 0) { str = "0"; } else { str = numerator + " / " + denominator; } return str; } /** {@inheritDoc} */ public FractionField getField() { return FractionField.getInstance(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/ProperFractionFormat.java100644 1750 1750 17261 11532241244 31150 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.util.MathUtils; /** * Formats a Fraction number in proper format. The number format for each of * the whole number, numerator and, denominator can be configured. *

                        * Minus signs are only allowed in the whole number part - i.e., * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and * will result in a ParseException.

                        * * @since 1.1 * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class ProperFractionFormat extends FractionFormat { /** Serializable version identifier */ private static final long serialVersionUID = 760934726031766749L; /** The format used for the whole number. */ private NumberFormat wholeFormat; /** * Create a proper formatting instance with the default number format for * the whole, numerator, and denominator. */ public ProperFractionFormat() { this(getDefaultNumberFormat()); } /** * Create a proper formatting instance with a custom number format for the * whole, numerator, and denominator. * @param format the custom format for the whole, numerator, and * denominator. */ public ProperFractionFormat(NumberFormat format) { this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); } /** * Create a proper formatting instance with a custom number format for each * of the whole, numerator, and denominator. * @param wholeFormat the custom format for the whole. * @param numeratorFormat the custom format for the numerator. * @param denominatorFormat the custom format for the denominator. */ public ProperFractionFormat(NumberFormat wholeFormat, NumberFormat numeratorFormat, NumberFormat denominatorFormat) { super(numeratorFormat, denominatorFormat); setWholeFormat(wholeFormat); } /** * Formats a {@link Fraction} object to produce a string. The fraction * is output in proper format. * * @param fraction the object to format. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ @Override public StringBuffer format(Fraction fraction, StringBuffer toAppendTo, FieldPosition pos) { pos.setBeginIndex(0); pos.setEndIndex(0); int num = fraction.getNumerator(); int den = fraction.getDenominator(); int whole = num / den; num = num % den; if (whole != 0) { getWholeFormat().format(whole, toAppendTo, pos); toAppendTo.append(' '); num = Math.abs(num); } getNumeratorFormat().format(num, toAppendTo, pos); toAppendTo.append(" / "); getDenominatorFormat().format(den, toAppendTo, pos); return toAppendTo; } /** * Access the whole format. * @return the whole format. */ public NumberFormat getWholeFormat() { return wholeFormat; } /** * Parses a string to produce a {@link Fraction} object. This method * expects the string to be formatted as a proper fraction. *

                        * Minus signs are only allowed in the whole number part - i.e., * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and * will result in a ParseException.

                        * * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the parsed {@link Fraction} object. */ @Override public Fraction parse(String source, ParsePosition pos) { // try to parse improper fraction Fraction ret = super.parse(source, pos); if (ret != null) { return ret; } int initialIndex = pos.getIndex(); // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse whole Number whole = getWholeFormat().parse(source, pos); if (whole == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse numerator Number num = getNumeratorFormat().parse(source, pos); if (num == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } if (num.intValue() < 0) { // minus signs should be leading, invalid expression pos.setIndex(initialIndex); return null; } // parse '/' int startIndex = pos.getIndex(); char c = parseNextCharacter(source, pos); switch (c) { case 0 : // no '/' // return num as a fraction return new Fraction(num.intValue(), 1); case '/' : // found '/', continue parsing denominator break; default : // invalid '/' // set index back to initial, error index should be the last // character examined. pos.setIndex(initialIndex); pos.setErrorIndex(startIndex); return null; } // parse whitespace parseAndIgnoreWhitespace(source, pos); // parse denominator Number den = getDenominatorFormat().parse(source, pos); if (den == null) { // invalid integer number // set index back to initial, error index should already be set // character examined. pos.setIndex(initialIndex); return null; } if (den.intValue() < 0) { // minus signs must be leading, invalid pos.setIndex(initialIndex); return null; } int w = whole.intValue(); int n = num.intValue(); int d = den.intValue(); return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d); } /** * Modify the whole format. * @param format The new whole format value. * @throws NullArgumentException if {@code format} is {@code null}. */ public void setWholeFormat(NumberFormat format) { if (format == null) { throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT); } this.wholeFormat = format; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/BigFractionField.java100644 1750 1750 4556 11532241244 30160 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import org.apache.commons.math.Field; /** * Representation of the fractional numbers without any overflow field. *

                        * This class is a singleton. *

                        * @see Fraction * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public class BigFractionField implements Field, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1699294557189741703L; /** Private constructor for the singleton. */ private BigFractionField() { } /** Get the unique instance. * @return the unique instance */ public static BigFractionField getInstance() { return LazyHolder.INSTANCE; } /** {@inheritDoc} */ public BigFraction getOne() { return BigFraction.ONE; } /** {@inheritDoc} */ public BigFraction getZero() { return BigFraction.ZERO; } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the instance. *

                        We use here the Initialization On Demand Holder Idiom.

                        */ private static class LazyHolder { /** Cached field instance. */ private static final BigFractionField INSTANCE = new BigFractionField(); } // CHECKSTYLE: resume HideUtilityClassConstructor /** Handle deserialization of the singleton. * @return the singleton instance */ private Object readResolve() { // return the singleton instance return LazyHolder.INSTANCE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/fraction/FractionField.java100644 1750 1750 4472 11532241244 27533 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.fraction; import java.io.Serializable; import org.apache.commons.math.Field; /** * Representation of the fractional numbers field. *

                        * This class is a singleton. *

                        * @see Fraction * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public class FractionField implements Field, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = -1257768487499119313L; /** Private constructor for the singleton. */ private FractionField() { } /** Get the unique instance. * @return the unique instance */ public static FractionField getInstance() { return LazyHolder.INSTANCE; } /** {@inheritDoc} */ public Fraction getOne() { return Fraction.ONE; } /** {@inheritDoc} */ public Fraction getZero() { return Fraction.ZERO; } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the instance. *

                        We use here the Initialization On Demand Holder Idiom.

                        */ private static class LazyHolder { /** Cached field instance. */ private static final FractionField INSTANCE = new FractionField(); } // CHECKSTYLE: resume HideUtilityClassConstructor /** Handle deserialization of the singleton. * @return the singleton instance */ private Object readResolve() { // return the singleton instance return LazyHolder.INSTANCE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/MathException.java100644 1750 1750 15630 11532241247 26006 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.io.PrintStream; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.Locale; import org.apache.commons.math.exception.MathThrowable; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Base class for commons-math checked exceptions. *

                        * Supports nesting, emulating JDK 1.4 behavior if necessary.

                        *

                        * Adapted from .

                        * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ */ public class MathException extends Exception implements MathThrowable { /** Serializable version identifier. */ private static final long serialVersionUID = 7428019509644517071L; /** * Pattern used to build the message. */ private final Localizable pattern; /** * Arguments used to build the message. */ private final Object[] arguments; /** * Constructs a new MathException with no * detail message. */ public MathException() { this.pattern = LocalizedFormats.SIMPLE_MESSAGE; this.arguments = new Object[] { "" }; } /** * Constructs a new MathException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MathException(Localizable, Object...)} */ @Deprecated public MathException(String pattern, Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Constructs a new MathException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathException(Localizable pattern, Object ... arguments) { this.pattern = pattern; this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); } /** * Constructs a new MathException with specified * nested Throwable root cause. * * @param rootCause the exception or error that caused this exception * to be thrown. */ public MathException(Throwable rootCause) { super(rootCause); this.pattern = LocalizedFormats.SIMPLE_MESSAGE; this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() }; } /** * Constructs a new MathException with specified * formatted detail message and nested Throwable root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param rootCause the exception or error that caused this exception * to be thrown. * @param pattern format specifier * @param arguments format arguments * @since 1.2 * @deprecated as of 2.2 replaced by {@link #MathException(Throwable, Localizable, Object...)} */ @Deprecated public MathException(Throwable rootCause, String pattern, Object ... arguments) { this(rootCause, new DummyLocalizable(pattern), arguments); } /** * Constructs a new MathException with specified * formatted detail message and nested Throwable root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param rootCause the exception or error that caused this exception * to be thrown. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathException(Throwable rootCause, Localizable pattern, Object ... arguments) { super(rootCause); this.pattern = pattern; this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); } /** Gets the pattern used to build the message of this throwable. * * @return the pattern used to build the message of this throwable * @since 1.2 * @deprecated as of 2.2 replaced by {@link #getSpecificPattern()} and {@link #getGeneralPattern()} */ @Deprecated public String getPattern() { return pattern.getSourceString(); } /** * {@inheritDoc} * * @since 2.2 */ public Localizable getSpecificPattern() { return null; } /** * {@inheritDoc} * * @since 2.2 */ public Localizable getGeneralPattern() { return pattern; } /** {@inheritDoc} */ public Object[] getArguments() { return arguments.clone(); } /** Gets the message in a specified locale. * * @param locale Locale in which the message should be translated * * @return localized message * @since 1.2 */ public String getMessage(final Locale locale) { if (pattern != null) { return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments); } return ""; } /** {@inheritDoc} */ @Override public String getMessage() { return getMessage(Locale.US); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } /** * Prints the stack trace of this exception to the standard error stream. */ @Override public void printStackTrace() { printStackTrace(System.err); } /** * Prints the stack trace of this exception to the specified stream. * * @param out the PrintStream to use for output */ @Override public void printStackTrace(PrintStream out) { synchronized (out) { PrintWriter pw = new PrintWriter(out, false); printStackTrace(pw); // Flush the PrintWriter before it's GC'ed. pw.flush(); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/MathRuntimeException.java100644 1750 1750 65577 11532241247 27371 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.io.EOFException; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.text.MessageFormat; import java.text.ParseException; import java.util.ConcurrentModificationException; import java.util.Locale; import java.util.NoSuchElementException; import org.apache.commons.math.exception.MathThrowable; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Base class for commons-math unchecked exceptions. * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public class MathRuntimeException extends RuntimeException implements MathThrowable { /** Serializable version identifier. */ private static final long serialVersionUID = 9058794795027570002L; /** * Pattern used to build the message. */ private final Localizable pattern; /** * Arguments used to build the message. */ private final Object[] arguments; /** * Constructs a new MathRuntimeException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MathRuntimeException(Localizable, Object...)} */ @Deprecated public MathRuntimeException(final String pattern, final Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Constructs a new MathRuntimeException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathRuntimeException(final Localizable pattern, final Object ... arguments) { this.pattern = pattern; this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); } /** * Constructs a new MathRuntimeException with specified * nested Throwable root cause. * * @param rootCause the exception or error that caused this exception * to be thrown. */ public MathRuntimeException(final Throwable rootCause) { super(rootCause); this.pattern = LocalizedFormats.SIMPLE_MESSAGE; this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() }; } /** * Constructs a new MathRuntimeException with specified * formatted detail message and nested Throwable root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param rootCause the exception or error that caused this exception * to be thrown. * @param pattern format specifier * @param arguments format arguments * @deprecated as of 2.2 replaced by {@link #MathRuntimeException(Throwable, Localizable, Object...)} */ @Deprecated public MathRuntimeException(final Throwable rootCause, final String pattern, final Object ... arguments) { this(rootCause, new DummyLocalizable(pattern), arguments); } /** * Constructs a new MathRuntimeException with specified * formatted detail message and nested Throwable root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param rootCause the exception or error that caused this exception * to be thrown. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathRuntimeException(final Throwable rootCause, final Localizable pattern, final Object ... arguments) { super(rootCause); this.pattern = pattern; this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); } /** * Builds a message string by from a pattern and its arguments. * @param locale Locale in which the message should be translated * @param pattern format specifier * @param arguments format arguments * @return a message string * @since 2.2 */ private static String buildMessage(final Locale locale, final Localizable pattern, final Object ... arguments) { return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments); } /** Gets the pattern used to build the message of this throwable. * * @return the pattern used to build the message of this throwable * @deprecated as of 2.2 replaced by {@link #getSpecificPattern()} and {@link #getGeneralPattern()} */ @Deprecated public String getPattern() { return pattern.getSourceString(); } /** * {@inheritDoc} * * @since 2.2 */ public Localizable getSpecificPattern() { return null; } /** * {@inheritDoc} * * @since 2.2 */ public Localizable getGeneralPattern() { return pattern; } /** {@inheritDoc} */ public Object[] getArguments() { return arguments.clone(); } /** Gets the message in a specified locale. * * @param locale Locale in which the message should be translated * * @return localized message */ public String getMessage(final Locale locale) { if (pattern != null) { return buildMessage(locale, pattern, arguments); } return ""; } /** {@inheritDoc} */ @Override public String getMessage() { return getMessage(Locale.US); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } /** * Prints the stack trace of this exception to the standard error stream. */ @Override public void printStackTrace() { printStackTrace(System.err); } /** * Prints the stack trace of this exception to the specified stream. * * @param out the PrintStream to use for output */ @Override public void printStackTrace(final PrintStream out) { synchronized (out) { PrintWriter pw = new PrintWriter(out, false); printStackTrace(pw); // Flush the PrintWriter before it's GC'ed. pw.flush(); } } /** * Constructs a new ArithmeticException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createArithmeticException(Localizable, Object...)} */ @Deprecated public static ArithmeticException createArithmeticException(final String pattern, final Object ... arguments) { return createArithmeticException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new ArithmeticException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static ArithmeticException createArithmeticException(final Localizable pattern, final Object ... arguments) { return new ArithmeticException() { /** Serializable version identifier. */ private static final long serialVersionUID = 5305498554076846637L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new ArrayIndexOutOfBoundsException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createArrayIndexOutOfBoundsException(Localizable, Object...)} */ @Deprecated public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final String pattern, final Object ... arguments) { return createArrayIndexOutOfBoundsException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new ArrayIndexOutOfBoundsException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final Localizable pattern, final Object ... arguments) { return new ArrayIndexOutOfBoundsException() { /** Serializable version identifier. */ private static final long serialVersionUID = 6718518191249632175L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new EOFException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createEOFException(Localizable, Object...)} */ @Deprecated public static EOFException createEOFException(final String pattern, final Object ... arguments) { return createEOFException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new EOFException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static EOFException createEOFException(final Localizable pattern, final Object ... arguments) { return new EOFException() { /** Serializable version identifier. */ private static final long serialVersionUID = 6067985859347601503L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new IOException with specified nested * Throwable root cause. *

                        This factory method allows chaining of other exceptions within an * IOException even for Java 5. The constructor for * IOException with a cause parameter was introduced only * with Java 6.

                        * @param rootCause the exception or error that caused this exception * to be thrown. * @return built exception */ public static IOException createIOException(final Throwable rootCause) { IOException ioe = new IOException(rootCause.getLocalizedMessage()); ioe.initCause(rootCause); return ioe; } /** * Constructs a new IllegalArgumentException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createIllegalArgumentException(Localizable, Object...)} */ @Deprecated public static IllegalArgumentException createIllegalArgumentException(final String pattern, final Object ... arguments) { return createIllegalArgumentException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new IllegalArgumentException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static IllegalArgumentException createIllegalArgumentException(final Localizable pattern, final Object ... arguments) { return new IllegalArgumentException() { /** Serializable version identifier. */ private static final long serialVersionUID = -4284649691002411505L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new IllegalArgumentException with specified nested * Throwable root cause. * @param rootCause the exception or error that caused this exception * to be thrown. * @return built exception */ public static IllegalArgumentException createIllegalArgumentException(final Throwable rootCause) { IllegalArgumentException iae = new IllegalArgumentException(rootCause.getLocalizedMessage()); iae.initCause(rootCause); return iae; } /** * Constructs a new IllegalStateException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createIllegalStateException(Localizable, Object...)} */ @Deprecated public static IllegalStateException createIllegalStateException(final String pattern, final Object ... arguments) { return createIllegalStateException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new IllegalStateException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static IllegalStateException createIllegalStateException(final Localizable pattern, final Object ... arguments) { return new IllegalStateException() { /** Serializable version identifier. */ private static final long serialVersionUID = 6880901520234515725L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new ConcurrentModificationException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createConcurrentModificationException(Localizable, Object...)} */ @Deprecated public static ConcurrentModificationException createConcurrentModificationException(final String pattern, final Object ... arguments) { return createConcurrentModificationException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new ConcurrentModificationException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static ConcurrentModificationException createConcurrentModificationException(final Localizable pattern, final Object ... arguments) { return new ConcurrentModificationException() { /** Serializable version identifier. */ private static final long serialVersionUID = -1878427236170442052L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new NoSuchElementException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createNoSuchElementException(Localizable, Object...)} */ @Deprecated public static NoSuchElementException createNoSuchElementException(final String pattern, final Object ... arguments) { return createNoSuchElementException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new NoSuchElementException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static NoSuchElementException createNoSuchElementException(final Localizable pattern, final Object ... arguments) { return new NoSuchElementException() { /** Serializable version identifier. */ private static final long serialVersionUID = 1632410088350355086L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new UnsupportedOperationException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 * @deprecated in 2.2. Please use {@link org.apache.commons.math.exception.MathUnsupportedOperationException} * instead. */ @Deprecated public static UnsupportedOperationException createUnsupportedOperationException(final Localizable pattern, final Object ... arguments) { return new UnsupportedOperationException() { /** Serializable version identifier. */ private static final long serialVersionUID = -4284649691002411505L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new NullPointerException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createNullPointerException(Localizable, Object...)} */ @Deprecated public static NullPointerException createNullPointerException(final String pattern, final Object ... arguments) { return createNullPointerException(new DummyLocalizable(pattern), arguments); } /** * Constructs a new NullPointerException with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 * @deprecated in 2.2. Checks for "null" must not be performed in Commons-Math. */ @Deprecated public static NullPointerException createNullPointerException(final Localizable pattern, final Object ... arguments) { return new NullPointerException() { /** Serializable version identifier. */ private static final long serialVersionUID = 451965530686593945L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** * Constructs a new ParseException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param offset offset at which error occurred * @param pattern format specifier * @param arguments format arguments * @return built exception * @deprecated as of 2.2 replaced by {@link #createParseException(int, Localizable, Object...)} */ @Deprecated public static ParseException createParseException(final int offset, final String pattern, final Object ... arguments) { return createParseException(offset, new DummyLocalizable(pattern), arguments); } /** * Constructs a new ParseException with specified * formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param offset offset at which error occurred * @param pattern format specifier * @param arguments format arguments * @return built exception * @since 2.2 */ public static ParseException createParseException(final int offset, final Localizable pattern, final Object ... arguments) { return new ParseException(null, offset) { /** Serializable version identifier. */ private static final long serialVersionUID = 8153587599409010120L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, pattern, arguments); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), pattern, arguments); } }; } /** Create an {@link java.lang.RuntimeException} for an internal error. * @param cause underlying cause * @return an {@link java.lang.RuntimeException} for an internal error */ public static RuntimeException createInternalError(final Throwable cause) { final String argument = "https://issues.apache.org/jira/browse/MATH"; return new RuntimeException(cause) { /** Serializable version identifier. */ private static final long serialVersionUID = -201865440834027016L; /** {@inheritDoc} */ @Override public String getMessage() { return buildMessage(Locale.US, LocalizedFormats.INTERNAL_ERROR, argument); } /** {@inheritDoc} */ @Override public String getLocalizedMessage() { return buildMessage(Locale.getDefault(), LocalizedFormats.INTERNAL_ERROR, argument); } }; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/special/Beta.java100644 1750 1750 16104 11532241245 25524 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.util.ContinuedFraction; import org.apache.commons.math.util.FastMath; /** * This is a utility class that provides computation methods related to the * Beta family of functions. * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public class Beta { /** Maximum allowed numerical error. */ private static final double DEFAULT_EPSILON = 10e-15; /** * Default constructor. Prohibit instantiation. */ private Beta() { super(); } /** * Returns the *
                        * regularized beta function I(x, a, b). * * @param x the value. * @param a the a parameter. * @param b the b parameter. * @return the regularized beta function I(x, a, b) * @throws MathException if the algorithm fails to converge. */ public static double regularizedBeta(double x, double a, double b) throws MathException { return regularizedBeta(x, a, b, DEFAULT_EPSILON, Integer.MAX_VALUE); } /** * Returns the * * regularized beta function I(x, a, b). * * @param x the value. * @param a the a parameter. * @param b the b parameter. * @param epsilon When the absolute value of the nth item in the * series is less than epsilon the approximation ceases * to calculate further elements in the series. * @return the regularized beta function I(x, a, b) * @throws MathException if the algorithm fails to converge. */ public static double regularizedBeta(double x, double a, double b, double epsilon) throws MathException { return regularizedBeta(x, a, b, epsilon, Integer.MAX_VALUE); } /** * Returns the regularized beta function I(x, a, b). * * @param x the value. * @param a the a parameter. * @param b the b parameter. * @param maxIterations Maximum number of "iterations" to complete. * @return the regularized beta function I(x, a, b) * @throws MathException if the algorithm fails to converge. */ public static double regularizedBeta(double x, double a, double b, int maxIterations) throws MathException { return regularizedBeta(x, a, b, DEFAULT_EPSILON, maxIterations); } /** * Returns the regularized beta function I(x, a, b). * * The implementation of this method is based on: * * * @param x the value. * @param a the a parameter. * @param b the b parameter. * @param epsilon When the absolute value of the nth item in the * series is less than epsilon the approximation ceases * to calculate further elements in the series. * @param maxIterations Maximum number of "iterations" to complete. * @return the regularized beta function I(x, a, b) * @throws MathException if the algorithm fails to converge. */ public static double regularizedBeta(double x, final double a, final double b, double epsilon, int maxIterations) throws MathException { double ret; if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || (x < 0) || (x > 1) || (a <= 0.0) || (b <= 0.0)) { ret = Double.NaN; } else if (x > (a + 1.0) / (a + b + 2.0)) { ret = 1.0 - regularizedBeta(1.0 - x, b, a, epsilon, maxIterations); } else { ContinuedFraction fraction = new ContinuedFraction() { @Override protected double getB(int n, double x) { double ret; double m; if (n % 2 == 0) { // even m = n / 2.0; ret = (m * (b - m) * x) / ((a + (2 * m) - 1) * (a + (2 * m))); } else { m = (n - 1.0) / 2.0; ret = -((a + m) * (a + b + m) * x) / ((a + (2 * m)) * (a + (2 * m) + 1.0)); } return ret; } @Override protected double getA(int n, double x) { return 1.0; } }; ret = FastMath.exp((a * FastMath.log(x)) + (b * FastMath.log(1.0 - x)) - FastMath.log(a) - logBeta(a, b, epsilon, maxIterations)) * 1.0 / fraction.evaluate(x, epsilon, maxIterations); } return ret; } /** * Returns the natural logarithm of the beta function B(a, b). * * @param a the a parameter. * @param b the b parameter. * @return log(B(a, b)) */ public static double logBeta(double a, double b) { return logBeta(a, b, DEFAULT_EPSILON, Integer.MAX_VALUE); } /** * Returns the natural logarithm of the beta function B(a, b). * * The implementation of this method is based on: * * * @param a the a parameter. * @param b the b parameter. * @param epsilon When the absolute value of the nth item in the * series is less than epsilon the approximation ceases * to calculate further elements in the series. * @param maxIterations Maximum number of "iterations" to complete. * @return log(B(a, b)) */ public static double logBeta(double a, double b, double epsilon, int maxIterations) { double ret; if (Double.isNaN(a) || Double.isNaN(b) || (a <= 0.0) || (b <= 0.0)) { ret = Double.NaN; } else { ret = Gamma.logGamma(a) + Gamma.logGamma(b) - Gamma.logGamma(a + b); } return ret; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/special/Gamma.java100644 1750 1750 30236 11532241245 25675 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.util.ContinuedFraction; import org.apache.commons.math.util.FastMath; /** * This is a utility class that provides computation methods related to the * Gamma family of functions. * * @version $Revision: 1042510 $ $Date: 2010-12-06 02:54:18 +0100 (lun. 06 déc. 2010) $ */ public class Gamma { /** * Euler-Mascheroni constant * @since 2.0 */ public static final double GAMMA = 0.577215664901532860606512090082; /** Maximum allowed numerical error. */ private static final double DEFAULT_EPSILON = 10e-15; /** Lanczos coefficients */ private static final double[] LANCZOS = { 0.99999999999999709182, 57.156235665862923517, -59.597960355475491248, 14.136097974741747174, -0.49191381609762019978, .33994649984811888699e-4, .46523628927048575665e-4, -.98374475304879564677e-4, .15808870322491248884e-3, -.21026444172410488319e-3, .21743961811521264320e-3, -.16431810653676389022e-3, .84418223983852743293e-4, -.26190838401581408670e-4, .36899182659531622704e-5, }; /** Avoid repeated computation of log of 2 PI in logGamma */ private static final double HALF_LOG_2_PI = 0.5 * FastMath.log(2.0 * FastMath.PI); // limits for switching algorithm in digamma /** C limit. */ private static final double C_LIMIT = 49; /** S limit. */ private static final double S_LIMIT = 1e-5; /** * Default constructor. Prohibit instantiation. */ private Gamma() { super(); } /** * Returns the natural logarithm of the gamma function Γ(x). * * The implementation of this method is based on: * * * @param x the value. * @return log(Γ(x)) */ public static double logGamma(double x) { double ret; if (Double.isNaN(x) || (x <= 0.0)) { ret = Double.NaN; } else { double g = 607.0 / 128.0; double sum = 0.0; for (int i = LANCZOS.length - 1; i > 0; --i) { sum = sum + (LANCZOS[i] / (x + i)); } sum = sum + LANCZOS[0]; double tmp = x + g + .5; ret = ((x + .5) * FastMath.log(tmp)) - tmp + HALF_LOG_2_PI + FastMath.log(sum / x); } return ret; } /** * Returns the regularized gamma function P(a, x). * * @param a the a parameter. * @param x the value. * @return the regularized gamma function P(a, x) * @throws MathException if the algorithm fails to converge. */ public static double regularizedGammaP(double a, double x) throws MathException { return regularizedGammaP(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE); } /** * Returns the regularized gamma function P(a, x). * * The implementation of this method is based on: * * * @param a the a parameter. * @param x the value. * @param epsilon When the absolute value of the nth item in the * series is less than epsilon the approximation ceases * to calculate further elements in the series. * @param maxIterations Maximum number of "iterations" to complete. * @return the regularized gamma function P(a, x) * @throws MathException if the algorithm fails to converge. */ public static double regularizedGammaP(double a, double x, double epsilon, int maxIterations) throws MathException { double ret; if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) { ret = Double.NaN; } else if (x == 0.0) { ret = 0.0; } else if (x >= a + 1) { // use regularizedGammaQ because it should converge faster in this // case. ret = 1.0 - regularizedGammaQ(a, x, epsilon, maxIterations); } else { // calculate series double n = 0.0; // current element index double an = 1.0 / a; // n-th element in the series double sum = an; // partial sum while (FastMath.abs(an/sum) > epsilon && n < maxIterations && sum < Double.POSITIVE_INFINITY) { // compute next element in the series n = n + 1.0; an = an * (x / (a + n)); // update partial sum sum = sum + an; } if (n >= maxIterations) { throw new MaxIterationsExceededException(maxIterations); } else if (Double.isInfinite(sum)) { ret = 1.0; } else { ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * sum; } } return ret; } /** * Returns the regularized gamma function Q(a, x) = 1 - P(a, x). * * @param a the a parameter. * @param x the value. * @return the regularized gamma function Q(a, x) * @throws MathException if the algorithm fails to converge. */ public static double regularizedGammaQ(double a, double x) throws MathException { return regularizedGammaQ(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE); } /** * Returns the regularized gamma function Q(a, x) = 1 - P(a, x). * * The implementation of this method is based on: * * * @param a the a parameter. * @param x the value. * @param epsilon When the absolute value of the nth item in the * series is less than epsilon the approximation ceases * to calculate further elements in the series. * @param maxIterations Maximum number of "iterations" to complete. * @return the regularized gamma function P(a, x) * @throws MathException if the algorithm fails to converge. */ public static double regularizedGammaQ(final double a, double x, double epsilon, int maxIterations) throws MathException { double ret; if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) { ret = Double.NaN; } else if (x == 0.0) { ret = 1.0; } else if (x < a + 1.0) { // use regularizedGammaP because it should converge faster in this // case. ret = 1.0 - regularizedGammaP(a, x, epsilon, maxIterations); } else { // create continued fraction ContinuedFraction cf = new ContinuedFraction() { @Override protected double getA(int n, double x) { return ((2.0 * n) + 1.0) - a + x; } @Override protected double getB(int n, double x) { return n * (a - n); } }; ret = 1.0 / cf.evaluate(x, epsilon, maxIterations); ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * ret; } return ret; } /** *

                        Computes the digamma function of x.

                        * *

                        This is an independently written implementation of the algorithm described in * Jose Bernardo, Algorithm AS 103: Psi (Digamma) Function, Applied Statistics, 1976.

                        * *

                        Some of the constants have been changed to increase accuracy at the moderate expense * of run-time. The result should be accurate to within 10^-8 absolute tolerance for * x >= 10^-5 and within 10^-8 relative tolerance for x > 0.

                        * *

                        Performance for large negative values of x will be quite expensive (proportional to * |x|). Accuracy for negative values of x should be about 10^-8 absolute for results * less than 10^5 and 10^-8 relative for results larger than that.

                        * * @param x the argument * @return digamma(x) to within 10-8 relative or absolute error whichever is smaller * @see Digamma at wikipedia * @see Bernardo's original article * @since 2.0 */ public static double digamma(double x) { if (x > 0 && x <= S_LIMIT) { // use method 5 from Bernardo AS103 // accurate to O(x) return -GAMMA - 1 / x; } if (x >= C_LIMIT) { // use method 4 (accurate to O(1/x^8) double inv = 1 / (x * x); // 1 1 1 1 // log(x) - --- - ------ + ------- - ------- // 2 x 12 x^2 120 x^4 252 x^6 return FastMath.log(x) - 0.5 / x - inv * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252)); } return digamma(x + 1) - 1 / x; } /** *

                        Computes the trigamma function of x. This function is derived by taking the derivative of * the implementation of digamma.

                        * * @param x the argument * @return trigamma(x) to within 10-8 relative or absolute error whichever is smaller * @see Trigamma at wikipedia * @see Gamma#digamma(double) * @since 2.0 */ public static double trigamma(double x) { if (x > 0 && x <= S_LIMIT) { return 1 / (x * x); } if (x >= C_LIMIT) { double inv = 1 / (x * x); // 1 1 1 1 1 // - + ---- + ---- - ----- + ----- // x 2 3 5 7 // 2 x 6 x 30 x 42 x return 1 / x + inv / 2 + inv / x * (1.0 / 6 - inv * (1.0 / 30 + inv / 42)); } return trigamma(x + 1) + 1 / (x * x); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/special/Erf.java100644 1750 1750 7064 11532241245 25352 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.special; import org.apache.commons.math.MathException; import org.apache.commons.math.util.FastMath; /** * This is a utility class that provides computation methods related to the * error functions. * * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $ */ public class Erf { /** * Default constructor. Prohibit instantiation. */ private Erf() { super(); } /** *

                        Returns the error function

                        *

                        erf(x) = 2/√π 0x e-t2dt

                        * *

                        This implementation computes erf(x) using the * {@link Gamma#regularizedGammaP(double, double, double, int) regularized gamma function}, * following Erf, equation (3)

                        * *

                        The value returned is always between -1 and 1 (inclusive). If {@code abs(x) > 40}, then * {@code erf(x)} is indistinguishable from either 1 or -1 as a double, so the appropriate extreme * value is returned.

                        * * @param x the value. * @return the error function erf(x) * @throws MathException if the algorithm fails to converge. * @see Gamma#regularizedGammaP(double, double, double, int) */ public static double erf(double x) throws MathException { if (FastMath.abs(x) > 40) { return x > 0 ? 1 : -1; } double ret = Gamma.regularizedGammaP(0.5, x * x, 1.0e-15, 10000); if (x < 0) { ret = -ret; } return ret; } /** *

                        Returns the complementary error function

                        *

                        erfc(x) = 2/√π x e-t2dt
                        * = 1 - {@link #erf(double) erf(x)}

                        * *

                        This implementation computes erfc(x) using the * {@link Gamma#regularizedGammaQ(double, double, double, int) regularized gamma function}, * following Erf, equation (3).

                        * *

                        The value returned is always between 0 and 2 (inclusive). If {@code abs(x) > 40}, then * {@code erf(x)} is indistinguishable from either 0 or 2 as a double, so the appropriate extreme * value is returned.

                        * * @param x the value * @return the complementary error function erfc(x) * @throws MathException if the algorithm fails to converge * @see Gamma#regularizedGammaQ(double, double, double, int) * @since 2.2 */ public static double erfc(double x) throws MathException { if (FastMath.abs(x) > 40) { return x > 0 ? 0 : 2; } final double ret = Gamma.regularizedGammaQ(0.5, x * x, 1.0e-15, 10000); return x < 0 ? 2 - ret : ret; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/special/package.html100644 1750 1750 1722 11532241245 26247 0ustarlucluc 0 0 Implementations of special functions such as Beta and Gamma. commons-math-2.2-src/src/main/java/org/apache/commons/math/DimensionMismatchException.java100644 1750 1750 4234 11532241247 30506 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Error thrown when two dimensions differ. * * @since 1.2 * @version $Revision: 1061778 $ $Date: 2011-01-21 13:12:39 +0100 (ven. 21 janv. 2011) $ * @deprecated in 2.2 (to be removed in 3.0). Please use its equivalent from package * {@link org.apache.commons.math.exception}. */ public class DimensionMismatchException extends MathException { /** Serializable version identifier */ private static final long serialVersionUID = -1316089546353786411L; /** First dimension. */ private final int dimension1; /** Second dimension. */ private final int dimension2; /** * Construct an exception from the mismatched dimensions * @param dimension1 first dimension * @param dimension2 second dimension */ public DimensionMismatchException(final int dimension1, final int dimension2) { super(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, dimension1, dimension2); this.dimension1 = dimension1; this.dimension2 = dimension2; } /** * Get the first dimension * @return first dimension */ public int getDimension1() { return dimension1; } /** * Get the second dimension * @return second dimension */ public int getDimension2() { return dimension2; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/ConvergingAlgorithmImpl.java100644 1750 1750 11364 11532241247 30030 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; /** * Provide a default implementation for several functions useful to generic * converging algorithms. * * @version $Revision: 1062691 $ $Date: 2011-01-24 10:12:47 +0100 (lun. 24 janv. 2011) $ * @since 2.0 * @deprecated in 2.2 (to be removed in 3.0). */ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm { /** Maximum absolute error. */ protected double absoluteAccuracy; /** Maximum relative error. */ protected double relativeAccuracy; /** Maximum number of iterations. */ protected int maximalIterationCount; /** Default maximum absolute error. */ protected double defaultAbsoluteAccuracy; /** Default maximum relative error. */ protected double defaultRelativeAccuracy; /** Default maximum number of iterations. */ protected int defaultMaximalIterationCount; /** The last iteration count. */ protected int iterationCount; /** * Construct an algorithm with given iteration count and accuracy. * * @param defaultAbsoluteAccuracy maximum absolute error * @param defaultMaximalIterationCount maximum number of iterations * @throws IllegalArgumentException if f is null or the * defaultAbsoluteAccuracy is not valid * @deprecated in 2.2. Derived classes should use the "setter" methods * in order to assign meaningful values to all the instances variables. */ @Deprecated protected ConvergingAlgorithmImpl(final int defaultMaximalIterationCount, final double defaultAbsoluteAccuracy) { this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; this.defaultRelativeAccuracy = 1.0e-14; this.absoluteAccuracy = defaultAbsoluteAccuracy; this.relativeAccuracy = defaultRelativeAccuracy; this.defaultMaximalIterationCount = defaultMaximalIterationCount; this.maximalIterationCount = defaultMaximalIterationCount; this.iterationCount = 0; } /** * Default constructor. * * @since 2.2 * @deprecated in 2.2 (to be removed as soon as the single non-default one * has been removed). */ @Deprecated protected ConvergingAlgorithmImpl() {} /** {@inheritDoc} */ public int getIterationCount() { return iterationCount; } /** {@inheritDoc} */ public void setAbsoluteAccuracy(double accuracy) { absoluteAccuracy = accuracy; } /** {@inheritDoc} */ public double getAbsoluteAccuracy() { return absoluteAccuracy; } /** {@inheritDoc} */ public void resetAbsoluteAccuracy() { absoluteAccuracy = defaultAbsoluteAccuracy; } /** {@inheritDoc} */ public void setMaximalIterationCount(int count) { maximalIterationCount = count; } /** {@inheritDoc} */ public int getMaximalIterationCount() { return maximalIterationCount; } /** {@inheritDoc} */ public void resetMaximalIterationCount() { maximalIterationCount = defaultMaximalIterationCount; } /** {@inheritDoc} */ public void setRelativeAccuracy(double accuracy) { relativeAccuracy = accuracy; } /** {@inheritDoc} */ public double getRelativeAccuracy() { return relativeAccuracy; } /** {@inheritDoc} */ public void resetRelativeAccuracy() { relativeAccuracy = defaultRelativeAccuracy; } /** * Reset the iterations counter to 0. * * @since 2.2 */ protected void resetIterationsCounter() { iterationCount = 0; } /** * Increment the iterations counter by 1. * * @throws MaxIterationsExceededException if the maximal number * of iterations is exceeded. * @since 2.2 */ protected void incrementIterationsCounter() throws MaxIterationsExceededException { if (++iterationCount > maximalIterationCount) { throw new MaxIterationsExceededException(maximalIterationCount); } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/MathConfigurationException.java100644 1750 1750 6712 11532241247 30517 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math; import java.io.Serializable; import org.apache.commons.math.exception.util.DummyLocalizable; import org.apache.commons.math.exception.util.Localizable; /** * Signals a configuration problem with any of the factory methods. * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ */ public class MathConfigurationException extends MathException implements Serializable{ /** Serializable version identifier */ private static final long serialVersionUID = 5261476508226103366L; /** * Default constructor. */ public MathConfigurationException() { super(); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 1.2 */ public MathConfigurationException(String pattern, Object ... arguments) { this(new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathConfigurationException(Localizable pattern, Object ... arguments) { super(pattern, arguments); } /** * Create an exception with a given root cause. * @param cause the exception or error that caused this exception to be thrown */ public MathConfigurationException(Throwable cause) { super(cause); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param pattern format specifier * @param arguments format arguments * @since 1.2 */ public MathConfigurationException(Throwable cause, String pattern, Object ... arguments) { this(cause, new DummyLocalizable(pattern), arguments); } /** * Constructs an exception with specified formatted detail message and root cause. * Message formatting is delegated to {@link java.text.MessageFormat}. * @param cause the exception or error that caused this exception to be thrown * @param pattern format specifier * @param arguments format arguments * @since 2.2 */ public MathConfigurationException(Throwable cause, Localizable pattern, Object ... arguments) { super(cause, pattern, arguments); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java100644 1750 1750 44143 11532241247 30470 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Open addressed map from int to double. *

                        This class provides a dedicated map from integers to doubles with a * much smaller memory overhead than standard java.util.Map.

                        *

                        This class is not synchronized. The specialized iterators returned by * {@link #iterator()} are fail-fast: they throw a * ConcurrentModificationException when they detect the map has been * modified during iteration.

                        * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class OpenIntToDoubleHashMap implements Serializable { /** Status indicator for free table entries. */ protected static final byte FREE = 0; /** Status indicator for full table entries. */ protected static final byte FULL = 1; /** Status indicator for removed table entries. */ protected static final byte REMOVED = 2; /** Serializable version identifier */ private static final long serialVersionUID = -3646337053166149105L; /** Load factor for the map. */ private static final float LOAD_FACTOR = 0.5f; /** Default starting size. *

                        This must be a power of two for bit mask to work properly.

                        */ private static final int DEFAULT_EXPECTED_SIZE = 16; /** Multiplier for size growth when map fills up. *

                        This must be a power of two for bit mask to work properly.

                        */ private static final int RESIZE_MULTIPLIER = 2; /** Number of bits to perturb the index when probing for collision resolution. */ private static final int PERTURB_SHIFT = 5; /** Keys table. */ private int[] keys; /** Values table. */ private double[] values; /** States table. */ private byte[] states; /** Return value for missing entries. */ private final double missingEntries; /** Current size of the map. */ private int size; /** Bit mask for hash values. */ private int mask; /** Modifications count. */ private transient int count; /** * Build an empty map with default size and using NaN for missing entries. */ public OpenIntToDoubleHashMap() { this(DEFAULT_EXPECTED_SIZE, Double.NaN); } /** * Build an empty map with default size * @param missingEntries value to return when a missing entry is fetched */ public OpenIntToDoubleHashMap(final double missingEntries) { this(DEFAULT_EXPECTED_SIZE, missingEntries); } /** * Build an empty map with specified size and using NaN for missing entries. * @param expectedSize expected number of elements in the map */ public OpenIntToDoubleHashMap(final int expectedSize) { this(expectedSize, Double.NaN); } /** * Build an empty map with specified size. * @param expectedSize expected number of elements in the map * @param missingEntries value to return when a missing entry is fetched */ public OpenIntToDoubleHashMap(final int expectedSize, final double missingEntries) { final int capacity = computeCapacity(expectedSize); keys = new int[capacity]; values = new double[capacity]; states = new byte[capacity]; this.missingEntries = missingEntries; mask = capacity - 1; } /** * Copy constructor. * @param source map to copy */ public OpenIntToDoubleHashMap(final OpenIntToDoubleHashMap source) { final int length = source.keys.length; keys = new int[length]; System.arraycopy(source.keys, 0, keys, 0, length); values = new double[length]; System.arraycopy(source.values, 0, values, 0, length); states = new byte[length]; System.arraycopy(source.states, 0, states, 0, length); missingEntries = source.missingEntries; size = source.size; mask = source.mask; count = source.count; } /** * Compute the capacity needed for a given size. * @param expectedSize expected size of the map * @return capacity to use for the specified size */ private static int computeCapacity(final int expectedSize) { if (expectedSize == 0) { return 1; } final int capacity = (int) FastMath.ceil(expectedSize / LOAD_FACTOR); final int powerOfTwo = Integer.highestOneBit(capacity); if (powerOfTwo == capacity) { return capacity; } return nextPowerOfTwo(capacity); } /** * Find the smallest power of two greater than the input value * @param i input value * @return smallest power of two greater than the input value */ private static int nextPowerOfTwo(final int i) { return Integer.highestOneBit(i) << 1; } /** * Get the stored value associated with the given key * @param key key associated with the data * @return data associated with the key */ public double get(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return values[index]; } if (states[index] == FREE) { return missingEntries; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return values[index]; } } return missingEntries; } /** * Check if a value is associated with a key. * @param key key to check * @return true if a value is associated with key */ public boolean containsKey(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return true; } if (states[index] == FREE) { return false; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return true; } } return false; } /** * Get an iterator over map elements. *

                        The specialized iterators returned are fail-fast: they throw a * ConcurrentModificationException when they detect the map * has been modified during iteration.

                        * @return iterator over the map elements */ public Iterator iterator() { return new Iterator(); } /** * Perturb the hash for starting probing. * @param hash initial hash * @return perturbed hash */ private static int perturb(final int hash) { return hash & 0x7fffffff; } /** * Find the index at which a key should be inserted * @param key key to lookup * @return index at which key should be inserted */ private int findInsertionIndex(final int key) { return findInsertionIndex(keys, states, key, mask); } /** * Find the index at which a key should be inserted * @param keys keys table * @param states states table * @param key key to lookup * @param mask bit mask for hash values * @return index at which key should be inserted */ private static int findInsertionIndex(final int[] keys, final byte[] states, final int key, final int mask) { final int hash = hashOf(key); int index = hash & mask; if (states[index] == FREE) { return index; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index); } int perturb = perturb(hash); int j = index; if (states[index] == FULL) { while (true) { j = probe(perturb, j); index = j & mask; perturb >>= PERTURB_SHIFT; if (states[index] != FULL || keys[index] == key) { break; } } } if (states[index] == FREE) { return index; } else if (states[index] == FULL) { // due to the loop exit condition, // if (states[index] == FULL) then keys[index] == key return changeIndexSign(index); } final int firstRemoved = index; while (true) { j = probe(perturb, j); index = j & mask; if (states[index] == FREE) { return firstRemoved; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index); } perturb >>= PERTURB_SHIFT; } } /** * Compute next probe for collision resolution * @param perturb perturbed hash * @param j previous probe * @return next probe */ private static int probe(final int perturb, final int j) { return (j << 2) + j + perturb + 1; } /** * Change the index sign * @param index initial index * @return changed index */ private static int changeIndexSign(final int index) { return -index - 1; } /** * Get the number of elements stored in the map. * @return number of elements stored in the map */ public int size() { return size; } /** * Remove the value associated with a key. * @param key key to which the value is associated * @return removed value */ public double remove(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return doRemove(index); } if (states[index] == FREE) { return missingEntries; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return doRemove(index); } } return missingEntries; } /** * Check if the tables contain an element associated with specified key * at specified index. * @param key key to check * @param index index to check * @return true if an element is associated with key at index */ private boolean containsKey(final int key, final int index) { return (key != 0 || states[index] == FULL) && keys[index] == key; } /** * Remove an element at specified index. * @param index index of the element to remove * @return removed value */ private double doRemove(int index) { keys[index] = 0; states[index] = REMOVED; final double previous = values[index]; values[index] = missingEntries; --size; ++count; return previous; } /** * Put a value associated with a key in the map. * @param key key to which value is associated * @param value value to put in the map * @return previous value associated with the key */ public double put(final int key, final double value) { int index = findInsertionIndex(key); double previous = missingEntries; boolean newMapping = true; if (index < 0) { index = changeIndexSign(index); previous = values[index]; newMapping = false; } keys[index] = key; states[index] = FULL; values[index] = value; if (newMapping) { ++size; if (shouldGrowTable()) { growTable(); } ++count; } return previous; } /** * Grow the tables. */ private void growTable() { final int oldLength = states.length; final int[] oldKeys = keys; final double[] oldValues = values; final byte[] oldStates = states; final int newLength = RESIZE_MULTIPLIER * oldLength; final int[] newKeys = new int[newLength]; final double[] newValues = new double[newLength]; final byte[] newStates = new byte[newLength]; final int newMask = newLength - 1; for (int i = 0; i < oldLength; ++i) { if (oldStates[i] == FULL) { final int key = oldKeys[i]; final int index = findInsertionIndex(newKeys, newStates, key, newMask); newKeys[index] = key; newValues[index] = oldValues[i]; newStates[index] = FULL; } } mask = newMask; keys = newKeys; values = newValues; states = newStates; } /** * Check if tables should grow due to increased size. * @return true if tables should grow */ private boolean shouldGrowTable() { return size > (mask + 1) * LOAD_FACTOR; } /** * Compute the hash value of a key * @param key key to hash * @return hash value of the key */ private static int hashOf(final int key) { final int h = key ^ ((key >>> 20) ^ (key >>> 12)); return h ^ (h >>> 7) ^ (h >>> 4); } /** Iterator class for the map. */ public class Iterator { /** Reference modification count. */ private final int referenceCount; /** Index of current element. */ private int current; /** Index of next element. */ private int next; /** * Simple constructor. */ private Iterator() { // preserve the modification count of the map to detect concurrent modifications later referenceCount = count; // initialize current index next = -1; try { advance(); } catch (NoSuchElementException nsee) { // ignored } } /** * Check if there is a next element in the map. * @return true if there is a next element */ public boolean hasNext() { return next >= 0; } /** * Get the key of current entry. * @return key of current entry * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public int key() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } return keys[current]; } /** * Get the value of current entry. * @return value of current entry * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public double value() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } return values[current]; } /** * Advance iterator one step further. * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public void advance() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } // advance on step current = next; // prepare next step try { while (states[++next] != FULL) { // nothing to do } } catch (ArrayIndexOutOfBoundsException e) { next = -2; if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } } } } /** * Read a serialized object. * @param stream input stream * @throws IOException if object cannot be read * @throws ClassNotFoundException if the class corresponding * to the serialized object cannot be found */ private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); count = 0; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/BigReal.java100644 1750 1750 20104 11532241247 25510 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; import java.math.RoundingMode; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; /** * Arbitrary precision decimal number. *

                        * This class is a simple wrapper around the standard BigDecimal * in order to implement the {@link FieldElement} interface. *

                        * @since 2.0 * @version $Revision: 925812 $ $Date: 2010-03-21 16:49:31 +0100 (dim. 21 mars 2010) $ */ public class BigReal implements FieldElement, Comparable, Serializable { /** A big real representing 0. */ public static final BigReal ZERO = new BigReal(BigDecimal.ZERO); /** A big real representing 1. */ public static final BigReal ONE = new BigReal(BigDecimal.ONE); /** Serializable version identifier. */ private static final long serialVersionUID = 4984534880991310382L; /** Underlying BigDecimal. */ private final BigDecimal d; /** Rounding mode for divisions. **/ private RoundingMode roundingMode = RoundingMode.HALF_UP; /*** BigDecimal scale ***/ private int scale = 64; /** Build an instance from a BigDecimal. * @param val value of the instance */ public BigReal(BigDecimal val) { d = val; } /** Build an instance from a BigInteger. * @param val value of the instance */ public BigReal(BigInteger val) { d = new BigDecimal(val); } /** Build an instance from an unscaled BigInteger. * @param unscaledVal unscaled value * @param scale scale to use */ public BigReal(BigInteger unscaledVal, int scale) { d = new BigDecimal(unscaledVal, scale); } /** Build an instance from an unscaled BigInteger. * @param unscaledVal unscaled value * @param scale scale to use * @param mc to used */ public BigReal(BigInteger unscaledVal, int scale, MathContext mc) { d = new BigDecimal(unscaledVal, scale, mc); } /** Build an instance from a BigInteger. * @param val value of the instance * @param mc context to use */ public BigReal(BigInteger val, MathContext mc) { d = new BigDecimal(val, mc); } /** Build an instance from a characters representation. * @param in character representation of the value */ public BigReal(char[] in) { d = new BigDecimal(in); } /** Build an instance from a characters representation. * @param in character representation of the value * @param offset offset of the first character to analyze * @param len length of the array slice to analyze */ public BigReal(char[] in, int offset, int len) { d = new BigDecimal(in, offset, len); } /** Build an instance from a characters representation. * @param in character representation of the value * @param offset offset of the first character to analyze * @param len length of the array slice to analyze * @param mc context to use */ public BigReal(char[] in, int offset, int len, MathContext mc) { d = new BigDecimal(in, offset, len, mc); } /** Build an instance from a characters representation. * @param in character representation of the value * @param mc context to use */ public BigReal(char[] in, MathContext mc) { d = new BigDecimal(in, mc); } /** Build an instance from a double. * @param val value of the instance */ public BigReal(double val) { d = new BigDecimal(val); } /** Build an instance from a double. * @param val value of the instance * @param mc context to use */ public BigReal(double val, MathContext mc) { d = new BigDecimal(val, mc); } /** Build an instance from an int. * @param val value of the instance */ public BigReal(int val) { d = new BigDecimal(val); } /** Build an instance from an int. * @param val value of the instance * @param mc context to use */ public BigReal(int val, MathContext mc) { d = new BigDecimal(val, mc); } /** Build an instance from a long. * @param val value of the instance */ public BigReal(long val) { d = new BigDecimal(val); } /** Build an instance from a long. * @param val value of the instance * @param mc context to use */ public BigReal(long val, MathContext mc) { d = new BigDecimal(val, mc); } /** Build an instance from a String representation. * @param val character representation of the value */ public BigReal(String val) { d = new BigDecimal(val); } /** Build an instance from a String representation. * @param val character representation of the value * @param mc context to use */ public BigReal(String val, MathContext mc) { d = new BigDecimal(val, mc); } /*** * Gets the rounding mode for division operations * The default is {@code RoundingMode.HALF_UP} * @return the rounding mode. * @since 2.1 */ public RoundingMode getRoundingMode() { return roundingMode; } /*** * Sets the rounding mode for decimal divisions. * @param roundingMode rounding mode for decimal divisions * @since 2.1 */ public void setRoundingMode(RoundingMode roundingMode) { this.roundingMode = roundingMode; } /*** * Sets the scale for division operations. * The default is 64 * @return the scale * @since 2.1 */ public int getScale() { return scale; } /*** * Sets the scale for division operations. * @param scale scale for division operations * @since 2.1 */ public void setScale(int scale) { this.scale = scale; } /** {@inheritDoc} */ public BigReal add(BigReal a) { return new BigReal(d.add(a.d)); } /** {@inheritDoc} */ public BigReal subtract(BigReal a) { return new BigReal(d.subtract(a.d)); } /** {@inheritDoc} */ public BigReal divide(BigReal a) throws ArithmeticException { return new BigReal(d.divide(a.d, scale, roundingMode)); } /** {@inheritDoc} */ public BigReal multiply(BigReal a) { return new BigReal(d.multiply(a.d)); } /** {@inheritDoc} */ public int compareTo(BigReal a) { return d.compareTo(a.d); } /** Get the double value corresponding to the instance. * @return double value corresponding to the instance */ public double doubleValue() { return d.doubleValue(); } /** Get the BigDecimal value corresponding to the instance. * @return BigDecimal value corresponding to the instance */ public BigDecimal bigDecimalValue() { return d; } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other){ return true; } if (other instanceof BigReal){ return d.equals(((BigReal) other).d); } return false; } /** {@inheritDoc} */ @Override public int hashCode() { return d.hashCode(); } /** {@inheritDoc} */ public Field getField() { return BigRealField.getInstance(); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/FastMath.java100644 1750 1750 361440 11532241247 25745 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; /** * Faster, more accurate, portable alternative to {@link StrictMath}. *

                        * Additionally implements the following methods not found in StrictMath: *

                          *
                        • {@link #asinh(double)}
                        • *
                        • {@link #acosh(double)}
                        • *
                        • {@link #atanh(double)}
                        • *
                        * The following methods are found in StrictMath since 1.6 only *
                          *
                        • {@link #copySign(double, double)}
                        • *
                        • {@link #getExponent(double)}
                        • *
                        • {@link #nextAfter(double,double)}
                        • *
                        • {@link #nextUp(double)}
                        • *
                        • {@link #scalb(double, int)}
                        • *
                        • {@link #copySign(float, float)}
                        • *
                        • {@link #getExponent(float)}
                        • *
                        • {@link #nextAfter(float,double)}
                        • *
                        • {@link #nextUp(float)}
                        • *
                        • {@link #scalb(float, int)}
                        • *
                        * @version $Revision: 1074294 $ $Date: 2011-02-24 22:18:59 +0100 (jeu. 24 févr. 2011) $ * @since 2.2 */ public class FastMath { /** Archimede's constant PI, ratio of circle circumference to diameter. */ public static final double PI = 105414357.0 / 33554432.0 + 1.984187159361080883e-9; /** Napier's constant e, base of the natural logarithm. */ public static final double E = 2850325.0 / 1048576.0 + 8.254840070411028747e-8; /** Exponential evaluated at integer values, * exp(x) = expIntTableA[x + 750] + expIntTableB[x+750]. */ private static final double EXP_INT_TABLE_A[] = new double[1500]; /** Exponential evaluated at integer values, * exp(x) = expIntTableA[x + 750] + expIntTableB[x+750] */ private static final double EXP_INT_TABLE_B[] = new double[1500]; /** Exponential over the range of 0 - 1 in increments of 2^-10 * exp(x/1024) = expFracTableA[x] + expFracTableB[x]. */ private static final double EXP_FRAC_TABLE_A[] = new double[1025]; /** Exponential over the range of 0 - 1 in increments of 2^-10 * exp(x/1024) = expFracTableA[x] + expFracTableB[x]. */ private static final double EXP_FRAC_TABLE_B[] = new double[1025]; /** Factorial table, for Taylor series expansions. */ private static final double FACT[] = new double[20]; /** Extended precision logarithm table over the range 1 - 2 in increments of 2^-10. */ private static final double LN_MANT[][] = new double[1024][]; /** log(2) (high bits). */ private static final double LN_2_A = 0.693147063255310059; /** log(2) (low bits). */ private static final double LN_2_B = 1.17304635250823482e-7; /** Coefficients for slowLog. */ private static final double LN_SPLIT_COEF[][] = { {2.0, 0.0}, {0.6666666269302368, 3.9736429850260626E-8}, {0.3999999761581421, 2.3841857910019882E-8}, {0.2857142686843872, 1.7029898543501842E-8}, {0.2222222089767456, 1.3245471311735498E-8}, {0.1818181574344635, 2.4384203044354907E-8}, {0.1538461446762085, 9.140260083262505E-9}, {0.13333332538604736, 9.220590270857665E-9}, {0.11764700710773468, 1.2393345855018391E-8}, {0.10526403784751892, 8.251545029714408E-9}, {0.0952233225107193, 1.2675934823758863E-8}, {0.08713622391223907, 1.1430250008909141E-8}, {0.07842259109020233, 2.404307984052299E-9}, {0.08371849358081818, 1.176342548272881E-8}, {0.030589580535888672, 1.2958646899018938E-9}, {0.14982303977012634, 1.225743062930824E-8}, }; /** Coefficients for log, when input 0.99 < x < 1.01. */ private static final double LN_QUICK_COEF[][] = { {1.0, 5.669184079525E-24}, {-0.25, -0.25}, {0.3333333134651184, 1.986821492305628E-8}, {-0.25, -6.663542893624021E-14}, {0.19999998807907104, 1.1921056801463227E-8}, {-0.1666666567325592, -7.800414592973399E-9}, {0.1428571343421936, 5.650007086920087E-9}, {-0.12502530217170715, -7.44321345601866E-11}, {0.11113807559013367, 9.219544613762692E-9}, }; /** Coefficients for log in the range of 1.0 < x < 1.0 + 2^-10. */ private static final double LN_HI_PREC_COEF[][] = { {1.0, -6.032174644509064E-23}, {-0.25, -0.25}, {0.3333333134651184, 1.9868161777724352E-8}, {-0.2499999701976776, -2.957007209750105E-8}, {0.19999954104423523, 1.5830993332061267E-10}, {-0.16624879837036133, -2.6033824355191673E-8} }; /** Sine table (high bits). */ private static final double SINE_TABLE_A[] = new double[14]; /** Sine table (low bits). */ private static final double SINE_TABLE_B[] = new double[14]; /** Cosine table (high bits). */ private static final double COSINE_TABLE_A[] = new double[14]; /** Cosine table (low bits). */ private static final double COSINE_TABLE_B[] = new double[14]; /** Tangent table, used by atan() (high bits). */ private static final double TANGENT_TABLE_A[] = new double[14]; /** Tangent table, used by atan() (low bits). */ private static final double TANGENT_TABLE_B[] = new double[14]; /** Bits of 1/(2*pi), need for reducePayneHanek(). */ private static final long RECIP_2PI[] = new long[] { (0x28be60dbL << 32) | 0x9391054aL, (0x7f09d5f4L << 32) | 0x7d4d3770L, (0x36d8a566L << 32) | 0x4f10e410L, (0x7f9458eaL << 32) | 0xf7aef158L, (0x6dc91b8eL << 32) | 0x909374b8L, (0x01924bbaL << 32) | 0x82746487L, (0x3f877ac7L << 32) | 0x2c4a69cfL, (0xba208d7dL << 32) | 0x4baed121L, (0x3a671c09L << 32) | 0xad17df90L, (0x4e64758eL << 32) | 0x60d4ce7dL, (0x272117e2L << 32) | 0xef7e4a0eL, (0xc7fe25ffL << 32) | 0xf7816603L, (0xfbcbc462L << 32) | 0xd6829b47L, (0xdb4d9fb3L << 32) | 0xc9f2c26dL, (0xd3d18fd9L << 32) | 0xa797fa8bL, (0x5d49eeb1L << 32) | 0xfaf97c5eL, (0xcf41ce7dL << 32) | 0xe294a4baL, 0x9afed7ecL << 32 }; /** Bits of pi/4, need for reducePayneHanek(). */ private static final long PI_O_4_BITS[] = new long[] { (0xc90fdaa2L << 32) | 0x2168c234L, (0xc4c6628bL << 32) | 0x80dc1cd1L }; /** Eighths. * This is used by sinQ, because its faster to do a table lookup than * a multiply in this time-critical routine */ private static final double EIGHTHS[] = {0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625}; /** Table of 2^((n+2)/3) */ private static final double CBRTTWO[] = { 0.6299605249474366, 0.7937005259840998, 1.0, 1.2599210498948732, 1.5874010519681994 }; /* * There are 52 bits in the mantissa of a double. * For additional precision, the code splits double numbers into two parts, * by clearing the low order 30 bits if possible, and then performs the arithmetic * on each half separately. */ /** * 0x40000000 - used to split a double into two parts, both with the low order bits cleared. * Equivalent to 2^30. */ private static final long HEX_40000000 = 0x40000000L; // 1073741824L /** Mask used to clear low order 30 bits */ private static final long MASK_30BITS = -1L - (HEX_40000000 -1); // 0xFFFFFFFFC0000000L; /** 2^52 - double numbers this large must be integral (no fraction) or NaN or Infinite */ private static final double TWO_POWER_52 = 4503599627370496.0; // Initialize tables static { int i; // Generate an array of factorials FACT[0] = 1.0; for (i = 1; i < FACT.length; i++) { FACT[i] = FACT[i-1] * i; } double tmp[] = new double[2]; double recip[] = new double[2]; // Populate expIntTable for (i = 0; i < 750; i++) { expint(i, tmp); EXP_INT_TABLE_A[i+750] = tmp[0]; EXP_INT_TABLE_B[i+750] = tmp[1]; if (i != 0) { // Negative integer powers splitReciprocal(tmp, recip); EXP_INT_TABLE_A[750-i] = recip[0]; EXP_INT_TABLE_B[750-i] = recip[1]; } } // Populate expFracTable for (i = 0; i < EXP_FRAC_TABLE_A.length; i++) { slowexp(i/1024.0, tmp); EXP_FRAC_TABLE_A[i] = tmp[0]; EXP_FRAC_TABLE_B[i] = tmp[1]; } // Populate lnMant table for (i = 0; i < LN_MANT.length; i++) { double d = Double.longBitsToDouble( (((long) i) << 42) | 0x3ff0000000000000L ); LN_MANT[i] = slowLog(d); } // Build the sine and cosine tables buildSinCosTables(); } /** * Private Constructor */ private FastMath() { } // Generic helper methods /** * Get the high order bits from the mantissa. * Equivalent to adding and subtracting HEX_40000 but also works for very large numbers * * @param d the value to split * @return the high order part of the mantissa */ private static double doubleHighPart(double d) { if (d > -MathUtils.SAFE_MIN && d < MathUtils.SAFE_MIN){ return d; // These are un-normalised - don't try to convert } long xl = Double.doubleToLongBits(d); xl = xl & MASK_30BITS; // Drop low order bits return Double.longBitsToDouble(xl); } /** Compute the square root of a number. *

                        Note: this implementation currently delegates to {@link Math#sqrt} * @param a number on which evaluation is done * @return square root of a */ public static double sqrt(final double a) { return Math.sqrt(a); } /** Compute the hyperbolic cosine of a number. * @param x number on which evaluation is done * @return hyperbolic cosine of x */ public static double cosh(double x) { if (x != x) { return x; } if (x > 20.0) { return exp(x)/2.0; } if (x < -20) { return exp(-x)/2.0; } double hiPrec[] = new double[2]; if (x < 0.0) { x = -x; } exp(x, 0.0, hiPrec); double ya = hiPrec[0] + hiPrec[1]; double yb = -(ya - hiPrec[0] - hiPrec[1]); double temp = ya * HEX_40000000; double yaa = ya + temp - temp; double yab = ya - yaa; // recip = 1/y double recip = 1.0/ya; temp = recip * HEX_40000000; double recipa = recip + temp - temp; double recipb = recip - recipa; // Correct for rounding in division recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip; // Account for yb recipb += -yb * recip * recip; // y = y + 1/y temp = ya + recipa; yb += -(temp - ya - recipa); ya = temp; temp = ya + recipb; yb += -(temp - ya - recipb); ya = temp; double result = ya + yb; result *= 0.5; return result; } /** Compute the hyperbolic sine of a number. * @param x number on which evaluation is done * @return hyperbolic sine of x */ public static double sinh(double x) { boolean negate = false; if (x != x) { return x; } if (x > 20.0) { return exp(x)/2.0; } if (x < -20) { return -exp(-x)/2.0; } if (x == 0) { return x; } if (x < 0.0) { x = -x; negate = true; } double result; if (x > 0.25) { double hiPrec[] = new double[2]; exp(x, 0.0, hiPrec); double ya = hiPrec[0] + hiPrec[1]; double yb = -(ya - hiPrec[0] - hiPrec[1]); double temp = ya * HEX_40000000; double yaa = ya + temp - temp; double yab = ya - yaa; // recip = 1/y double recip = 1.0/ya; temp = recip * HEX_40000000; double recipa = recip + temp - temp; double recipb = recip - recipa; // Correct for rounding in division recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip; // Account for yb recipb += -yb * recip * recip; recipa = -recipa; recipb = -recipb; // y = y + 1/y temp = ya + recipa; yb += -(temp - ya - recipa); ya = temp; temp = ya + recipb; yb += -(temp - ya - recipb); ya = temp; result = ya + yb; result *= 0.5; } else { double hiPrec[] = new double[2]; expm1(x, hiPrec); double ya = hiPrec[0] + hiPrec[1]; double yb = -(ya - hiPrec[0] - hiPrec[1]); /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */ double denom = 1.0 + ya; double denomr = 1.0 / denom; double denomb = -(denom - 1.0 - ya) + yb; double ratio = ya * denomr; double temp = ratio * HEX_40000000; double ra = ratio + temp - temp; double rb = ratio - ra; temp = denom * HEX_40000000; double za = denom + temp - temp; double zb = denom - za; rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr; // Adjust for yb rb += yb*denomr; // numerator rb += -ya * denomb * denomr * denomr; // denominator // y = y - 1/y temp = ya + ra; yb += -(temp - ya - ra); ya = temp; temp = ya + rb; yb += -(temp - ya - rb); ya = temp; result = ya + yb; result *= 0.5; } if (negate) { result = -result; } return result; } /** Compute the hyperbolic tangent of a number. * @param x number on which evaluation is done * @return hyperbolic tangent of x */ public static double tanh(double x) { boolean negate = false; if (x != x) { return x; } if (x > 20.0) { return 1.0; } if (x < -20) { return -1.0; } if (x == 0) { return x; } if (x < 0.0) { x = -x; negate = true; } double result; if (x >= 0.5) { double hiPrec[] = new double[2]; // tanh(x) = (exp(2x) - 1) / (exp(2x) + 1) exp(x*2.0, 0.0, hiPrec); double ya = hiPrec[0] + hiPrec[1]; double yb = -(ya - hiPrec[0] - hiPrec[1]); /* Numerator */ double na = -1.0 + ya; double nb = -(na + 1.0 - ya); double temp = na + yb; nb += -(temp - na - yb); na = temp; /* Denominator */ double da = 1.0 + ya; double db = -(da - 1.0 - ya); temp = da + yb; db += -(temp - da - yb); da = temp; temp = da * HEX_40000000; double daa = da + temp - temp; double dab = da - daa; // ratio = na/da double ratio = na/da; temp = ratio * HEX_40000000; double ratioa = ratio + temp - temp; double ratiob = ratio - ratioa; // Correct for rounding in division ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da; // Account for nb ratiob += nb / da; // Account for db ratiob += -db * na / da / da; result = ratioa + ratiob; } else { double hiPrec[] = new double[2]; // tanh(x) = expm1(2x) / (expm1(2x) + 2) expm1(x*2.0, hiPrec); double ya = hiPrec[0] + hiPrec[1]; double yb = -(ya - hiPrec[0] - hiPrec[1]); /* Numerator */ double na = ya; double nb = yb; /* Denominator */ double da = 2.0 + ya; double db = -(da - 2.0 - ya); double temp = da + yb; db += -(temp - da - yb); da = temp; temp = da * HEX_40000000; double daa = da + temp - temp; double dab = da - daa; // ratio = na/da double ratio = na/da; temp = ratio * HEX_40000000; double ratioa = ratio + temp - temp; double ratiob = ratio - ratioa; // Correct for rounding in division ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da; // Account for nb ratiob += nb / da; // Account for db ratiob += -db * na / da / da; result = ratioa + ratiob; } if (negate) { result = -result; } return result; } /** Compute the inverse hyperbolic cosine of a number. * @param a number on which evaluation is done * @return inverse hyperbolic cosine of a */ public static double acosh(final double a) { return FastMath.log(a + FastMath.sqrt(a * a - 1)); } /** Compute the inverse hyperbolic sine of a number. * @param a number on which evaluation is done * @return inverse hyperbolic sine of a */ public static double asinh(double a) { boolean negative = false; if (a < 0) { negative = true; a = -a; } double absAsinh; if (a > 0.167) { absAsinh = FastMath.log(FastMath.sqrt(a * a + 1) + a); } else { final double a2 = a * a; if (a > 0.097) { absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0 - a2 * (1.0 / 15.0 - a2 * (1.0 / 17.0) * 15.0 / 16.0) * 13.0 / 14.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); } else if (a > 0.036) { absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); } else if (a > 0.0036) { absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0); } else { absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0) * 3.0 / 4.0) / 2.0); } } return negative ? -absAsinh : absAsinh; } /** Compute the inverse hyperbolic tangent of a number. * @param a number on which evaluation is done * @return inverse hyperbolic tangent of a */ public static double atanh(double a) { boolean negative = false; if (a < 0) { negative = true; a = -a; } double absAtanh; if (a > 0.15) { absAtanh = 0.5 * FastMath.log((1 + a) / (1 - a)); } else { final double a2 = a * a; if (a > 0.087) { absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0 + a2 * (1.0 / 15.0 + a2 * (1.0 / 17.0))))))))); } else if (a > 0.031) { absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0))))))); } else if (a > 0.003) { absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0))))); } else { absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0))); } } return negative ? -absAtanh : absAtanh; } /** Compute the signum of a number. * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise * @param a number on which evaluation is done * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a */ public static double signum(final double a) { return (a < 0.0) ? -1.0 : ((a > 0.0) ? 1.0 : a); // return +0.0/-0.0/NaN depending on a } /** Compute the signum of a number. * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise * @param a number on which evaluation is done * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a */ public static float signum(final float a) { return (a < 0.0f) ? -1.0f : ((a > 0.0f) ? 1.0f : a); // return +0.0/-0.0/NaN depending on a } /** Compute next number towards positive infinity. * @param a number to which neighbor should be computed * @return neighbor of a towards positive infinity */ public static double nextUp(final double a) { return nextAfter(a, Double.POSITIVE_INFINITY); } /** Compute next number towards positive infinity. * @param a number to which neighbor should be computed * @return neighbor of a towards positive infinity */ public static float nextUp(final float a) { return nextAfter(a, Float.POSITIVE_INFINITY); } /** Returns a pseudo-random number between 0.0 and 1.0. *

                        Note: this implementation currently delegates to {@link Math#random} * @return a random number between 0.0 and 1.0 */ public static double random() { return Math.random(); } /** * Exponential function. * * Computes exp(x), function result is nearly rounded. It will be correctly * rounded to the theoretical value for 99.9% of input values, otherwise it will * have a 1 UPL error. * * Method: * Lookup intVal = exp(int(x)) * Lookup fracVal = exp(int(x-int(x) / 1024.0) * 1024.0 ); * Compute z as the exponential of the remaining bits by a polynomial minus one * exp(x) = intVal * fracVal * (1 + z) * * Accuracy: * Calculation is done with 63 bits of precision, so result should be correctly * rounded for 99.9% of input values, with less than 1 ULP error otherwise. * * @param x a double * @return double ex */ public static double exp(double x) { return exp(x, 0.0, null); } /** * Internal helper method for exponential function. * @param x original argument of the exponential function * @param extra extra bits of precision on input (To Be Confirmed) * @param hiPrec extra bits of precision on output (To Be Confirmed) * @return exp(x) */ private static double exp(double x, double extra, double[] hiPrec) { double intPartA; double intPartB; int intVal; /* Lookup exp(floor(x)). * intPartA will have the upper 22 bits, intPartB will have the lower * 52 bits. */ if (x < 0.0) { intVal = (int) -x; if (intVal > 746) { if (hiPrec != null) { hiPrec[0] = 0.0; hiPrec[1] = 0.0; } return 0.0; } if (intVal > 709) { /* This will produce a subnormal output */ final double result = exp(x+40.19140625, extra, hiPrec) / 285040095144011776.0; if (hiPrec != null) { hiPrec[0] /= 285040095144011776.0; hiPrec[1] /= 285040095144011776.0; } return result; } if (intVal == 709) { /* exp(1.494140625) is nearly a machine number... */ final double result = exp(x+1.494140625, extra, hiPrec) / 4.455505956692756620; if (hiPrec != null) { hiPrec[0] /= 4.455505956692756620; hiPrec[1] /= 4.455505956692756620; } return result; } intVal++; intPartA = EXP_INT_TABLE_A[750-intVal]; intPartB = EXP_INT_TABLE_B[750-intVal]; intVal = -intVal; } else { intVal = (int) x; if (intVal > 709) { if (hiPrec != null) { hiPrec[0] = Double.POSITIVE_INFINITY; hiPrec[1] = 0.0; } return Double.POSITIVE_INFINITY; } intPartA = EXP_INT_TABLE_A[750+intVal]; intPartB = EXP_INT_TABLE_B[750+intVal]; } /* Get the fractional part of x, find the greatest multiple of 2^-10 less than * x and look up the exp function of it. * fracPartA will have the upper 22 bits, fracPartB the lower 52 bits. */ final int intFrac = (int) ((x - intVal) * 1024.0); final double fracPartA = EXP_FRAC_TABLE_A[intFrac]; final double fracPartB = EXP_FRAC_TABLE_B[intFrac]; /* epsilon is the difference in x from the nearest multiple of 2^-10. It * has a value in the range 0 <= epsilon < 2^-10. * Do the subtraction from x as the last step to avoid possible loss of percison. */ final double epsilon = x - (intVal + intFrac / 1024.0); /* Compute z = exp(epsilon) - 1.0 via a minimax polynomial. z has full double precision (52 bits). Since z < 2^-10, we will have 62 bits of precision when combined with the contant 1. This will be used in the last addition below to get proper rounding. */ /* Remez generated polynomial. Converges on the interval [0, 2^-10], error is less than 0.5 ULP */ double z = 0.04168701738764507; z = z * epsilon + 0.1666666505023083; z = z * epsilon + 0.5000000000042687; z = z * epsilon + 1.0; z = z * epsilon + -3.940510424527919E-20; /* Compute (intPartA+intPartB) * (fracPartA+fracPartB) by binomial expansion. tempA is exact since intPartA and intPartB only have 22 bits each. tempB will have 52 bits of precision. */ double tempA = intPartA * fracPartA; double tempB = intPartA * fracPartB + intPartB * fracPartA + intPartB * fracPartB; /* Compute the result. (1+z)(tempA+tempB). Order of operations is important. For accuracy add by increasing size. tempA is exact and much larger than the others. If there are extra bits specified from the pow() function, use them. */ final double tempC = tempB + tempA; final double result; if (extra != 0.0) { result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA; } else { result = tempC*z + tempB + tempA; } if (hiPrec != null) { // If requesting high precision hiPrec[0] = tempA; hiPrec[1] = tempC*extra*z + tempC*extra + tempC*z + tempB; } return result; } /** Compute exp(x) - 1 * @param x number to compute shifted exponential * @return exp(x) - 1 */ public static double expm1(double x) { return expm1(x, null); } /** Internal helper method for expm1 * @param x number to compute shifted exponential * @param hiPrecOut receive high precision result for -1.0 < x < 1.0 * @return exp(x) - 1 */ private static double expm1(double x, double hiPrecOut[]) { if (x != x || x == 0.0) { // NaN or zero return x; } if (x <= -1.0 || x >= 1.0) { // If not between +/- 1.0 //return exp(x) - 1.0; double hiPrec[] = new double[2]; exp(x, 0.0, hiPrec); if (x > 0.0) { return -1.0 + hiPrec[0] + hiPrec[1]; } else { final double ra = -1.0 + hiPrec[0]; double rb = -(ra + 1.0 - hiPrec[0]); rb += hiPrec[1]; return ra + rb; } } double baseA; double baseB; double epsilon; boolean negative = false; if (x < 0.0) { x = -x; negative = true; } { int intFrac = (int) (x * 1024.0); double tempA = EXP_FRAC_TABLE_A[intFrac] - 1.0; double tempB = EXP_FRAC_TABLE_B[intFrac]; double temp = tempA + tempB; tempB = -(temp - tempA - tempB); tempA = temp; temp = tempA * HEX_40000000; baseA = tempA + temp - temp; baseB = tempB + (tempA - baseA); epsilon = x - intFrac/1024.0; } /* Compute expm1(epsilon) */ double zb = 0.008336750013465571; zb = zb * epsilon + 0.041666663879186654; zb = zb * epsilon + 0.16666666666745392; zb = zb * epsilon + 0.49999999999999994; zb = zb * epsilon; zb = zb * epsilon; double za = epsilon; double temp = za + zb; zb = -(temp - za - zb); za = temp; temp = za * HEX_40000000; temp = za + temp - temp; zb += za - temp; za = temp; /* Combine the parts. expm1(a+b) = expm1(a) + expm1(b) + expm1(a)*expm1(b) */ double ya = za * baseA; //double yb = za*baseB + zb*baseA + zb*baseB; temp = ya + za * baseB; double yb = -(temp - ya - za * baseB); ya = temp; temp = ya + zb * baseA; yb += -(temp - ya - zb * baseA); ya = temp; temp = ya + zb * baseB; yb += -(temp - ya - zb*baseB); ya = temp; //ya = ya + za + baseA; //yb = yb + zb + baseB; temp = ya + baseA; yb += -(temp - baseA - ya); ya = temp; temp = ya + za; //yb += (ya > za) ? -(temp - ya - za) : -(temp - za - ya); yb += -(temp - ya - za); ya = temp; temp = ya + baseB; //yb += (ya > baseB) ? -(temp - ya - baseB) : -(temp - baseB - ya); yb += -(temp - ya - baseB); ya = temp; temp = ya + zb; //yb += (ya > zb) ? -(temp - ya - zb) : -(temp - zb - ya); yb += -(temp - ya - zb); ya = temp; if (negative) { /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */ double denom = 1.0 + ya; double denomr = 1.0 / denom; double denomb = -(denom - 1.0 - ya) + yb; double ratio = ya * denomr; temp = ratio * HEX_40000000; final double ra = ratio + temp - temp; double rb = ratio - ra; temp = denom * HEX_40000000; za = denom + temp - temp; zb = denom - za; rb += (ya - za * ra - za * rb - zb * ra - zb * rb) * denomr; // f(x) = x/1+x // Compute f'(x) // Product rule: d(uv) = du*v + u*dv // Chain rule: d(f(g(x)) = f'(g(x))*f(g'(x)) // d(1/x) = -1/(x*x) // d(1/1+x) = -1/( (1+x)^2) * 1 = -1/((1+x)*(1+x)) // d(x/1+x) = -x/((1+x)(1+x)) + 1/1+x = 1 / ((1+x)(1+x)) // Adjust for yb rb += yb * denomr; // numerator rb += -ya * denomb * denomr * denomr; // denominator // negate ya = -ra; yb = -rb; } if (hiPrecOut != null) { hiPrecOut[0] = ya; hiPrecOut[1] = yb; } return ya + yb; } /** * For x between 0 and 1, returns exp(x), uses extended precision * @param x argument of exponential * @param result placeholder where to place exp(x) split in two terms * for extra precision (i.e. exp(x) = result[0] ° result[1] * @return exp(x) */ private static double slowexp(final double x, final double result[]) { final double xs[] = new double[2]; final double ys[] = new double[2]; final double facts[] = new double[2]; final double as[] = new double[2]; split(x, xs); ys[0] = ys[1] = 0.0; for (int i = 19; i >= 0; i--) { splitMult(xs, ys, as); ys[0] = as[0]; ys[1] = as[1]; split(FACT[i], as); splitReciprocal(as, facts); splitAdd(ys, facts, as); ys[0] = as[0]; ys[1] = as[1]; } if (result != null) { result[0] = ys[0]; result[1] = ys[1]; } return ys[0] + ys[1]; } /** Compute split[0], split[1] such that their sum is equal to d, * and split[0] has its 30 least significant bits as zero. * @param d number to split * @param split placeholder where to place the result */ private static void split(final double d, final double split[]) { if (d < 8e298 && d > -8e298) { final double a = d * HEX_40000000; split[0] = (d + a) - a; split[1] = d - split[0]; } else { final double a = d * 9.31322574615478515625E-10; split[0] = (d + a - d) * HEX_40000000; split[1] = d - split[0]; } } /** Recompute a split. * @param a input/out array containing the split, changed * on output */ private static void resplit(final double a[]) { final double c = a[0] + a[1]; final double d = -(c - a[0] - a[1]); if (c < 8e298 && c > -8e298) { double z = c * HEX_40000000; a[0] = (c + z) - z; a[1] = c - a[0] + d; } else { double z = c * 9.31322574615478515625E-10; a[0] = (c + z - c) * HEX_40000000; a[1] = c - a[0] + d; } } /** Multiply two numbers in split form. * @param a first term of multiplication * @param b second term of multiplication * @param ans placeholder where to put the result */ private static void splitMult(double a[], double b[], double ans[]) { ans[0] = a[0] * b[0]; ans[1] = a[0] * b[1] + a[1] * b[0] + a[1] * b[1]; /* Resplit */ resplit(ans); } /** Add two numbers in split form. * @param a first term of addition * @param b second term of addition * @param ans placeholder where to put the result */ private static void splitAdd(final double a[], final double b[], final double ans[]) { ans[0] = a[0] + b[0]; ans[1] = a[1] + b[1]; resplit(ans); } /** Compute the reciprocal of in. Use the following algorithm. * in = c + d. * want to find x + y such that x+y = 1/(c+d) and x is much * larger than y and x has several zero bits on the right. * * Set b = 1/(2^22), a = 1 - b. Thus (a+b) = 1. * Use following identity to compute (a+b)/(c+d) * * (a+b)/(c+d) = a/c + (bc - ad) / (c^2 + cd) * set x = a/c and y = (bc - ad) / (c^2 + cd) * This will be close to the right answer, but there will be * some rounding in the calculation of X. So by carefully * computing 1 - (c+d)(x+y) we can compute an error and * add that back in. This is done carefully so that terms * of similar size are subtracted first. * @param in initial number, in split form * @param result placeholder where to put the result */ private static void splitReciprocal(final double in[], final double result[]) { final double b = 1.0/4194304.0; final double a = 1.0 - b; if (in[0] == 0.0) { in[0] = in[1]; in[1] = 0.0; } result[0] = a / in[0]; result[1] = (b*in[0]-a*in[1]) / (in[0]*in[0] + in[0]*in[1]); if (result[1] != result[1]) { // can happen if result[1] is NAN result[1] = 0.0; } /* Resplit */ resplit(result); for (int i = 0; i < 2; i++) { /* this may be overkill, probably once is enough */ double err = 1.0 - result[0] * in[0] - result[0] * in[1] - result[1] * in[0] - result[1] * in[1]; /*err = 1.0 - err; */ err = err * (result[0] + result[1]); /*printf("err = %16e\n", err); */ result[1] += err; } } /** Compute (a[0] + a[1]) * (b[0] + b[1]) in extended precision. * @param a first term of the multiplication * @param b second term of the multiplication * @param result placeholder where to put the result */ private static void quadMult(final double a[], final double b[], final double result[]) { final double xs[] = new double[2]; final double ys[] = new double[2]; final double zs[] = new double[2]; /* a[0] * b[0] */ split(a[0], xs); split(b[0], ys); splitMult(xs, ys, zs); result[0] = zs[0]; result[1] = zs[1]; /* a[0] * b[1] */ split(b[1], ys); splitMult(xs, ys, zs); double tmp = result[0] + zs[0]; result[1] = result[1] - (tmp - result[0] - zs[0]); result[0] = tmp; tmp = result[0] + zs[1]; result[1] = result[1] - (tmp - result[0] - zs[1]); result[0] = tmp; /* a[1] * b[0] */ split(a[1], xs); split(b[0], ys); splitMult(xs, ys, zs); tmp = result[0] + zs[0]; result[1] = result[1] - (tmp - result[0] - zs[0]); result[0] = tmp; tmp = result[0] + zs[1]; result[1] = result[1] - (tmp - result[0] - zs[1]); result[0] = tmp; /* a[1] * b[0] */ split(a[1], xs); split(b[1], ys); splitMult(xs, ys, zs); tmp = result[0] + zs[0]; result[1] = result[1] - (tmp - result[0] - zs[0]); result[0] = tmp; tmp = result[0] + zs[1]; result[1] = result[1] - (tmp - result[0] - zs[1]); result[0] = tmp; } /** Compute exp(p) for a integer p in extended precision. * @param p integer whose exponential is requested * @param result placeholder where to put the result in extended precision * @return exp(p) in standard precision (equal to result[0] + result[1]) */ private static double expint(int p, final double result[]) { //double x = M_E; final double xs[] = new double[2]; final double as[] = new double[2]; final double ys[] = new double[2]; //split(x, xs); //xs[1] = (double)(2.7182818284590452353602874713526625L - xs[0]); //xs[0] = 2.71827697753906250000; //xs[1] = 4.85091998273542816811e-06; //xs[0] = Double.longBitsToDouble(0x4005bf0800000000L); //xs[1] = Double.longBitsToDouble(0x3ed458a2bb4a9b00L); /* E */ xs[0] = 2.718281828459045; xs[1] = 1.4456468917292502E-16; split(1.0, ys); while (p > 0) { if ((p & 1) != 0) { quadMult(ys, xs, as); ys[0] = as[0]; ys[1] = as[1]; } quadMult(xs, xs, as); xs[0] = as[0]; xs[1] = as[1]; p >>= 1; } if (result != null) { result[0] = ys[0]; result[1] = ys[1]; resplit(result); } return ys[0] + ys[1]; } /** * Natural logarithm. * * @param x a double * @return log(x) */ public static double log(final double x) { return log(x, null); } /** * Internal helper method for natural logarithm function. * @param x original argument of the natural logarithm function * @param hiPrec extra bits of precision on output (To Be Confirmed) * @return log(x) */ private static double log(final double x, final double[] hiPrec) { if (x==0) { // Handle special case of +0/-0 return Double.NEGATIVE_INFINITY; } long bits = Double.doubleToLongBits(x); /* Handle special cases of negative input, and NaN */ if ((bits & 0x8000000000000000L) != 0 || x != x) { if (x != 0.0) { if (hiPrec != null) { hiPrec[0] = Double.NaN; } return Double.NaN; } } /* Handle special cases of Positive infinity. */ if (x == Double.POSITIVE_INFINITY) { if (hiPrec != null) { hiPrec[0] = Double.POSITIVE_INFINITY; } return Double.POSITIVE_INFINITY; } /* Extract the exponent */ int exp = (int)(bits >> 52)-1023; if ((bits & 0x7ff0000000000000L) == 0) { // Subnormal! if (x == 0) { // Zero if (hiPrec != null) { hiPrec[0] = Double.NEGATIVE_INFINITY; } return Double.NEGATIVE_INFINITY; } /* Normalize the subnormal number. */ bits <<= 1; while ( (bits & 0x0010000000000000L) == 0) { exp--; bits <<= 1; } } if (exp == -1 || exp == 0) { if (x < 1.01 && x > 0.99 && hiPrec == null) { /* The normal method doesn't work well in the range [0.99, 1.01], so call do a straight polynomial expansion in higer precision. */ /* Compute x - 1.0 and split it */ double xa = x - 1.0; double xb = xa - x + 1.0; double tmp = xa * HEX_40000000; double aa = xa + tmp - tmp; double ab = xa - aa; xa = aa; xb = ab; double ya = LN_QUICK_COEF[LN_QUICK_COEF.length-1][0]; double yb = LN_QUICK_COEF[LN_QUICK_COEF.length-1][1]; for (int i = LN_QUICK_COEF.length - 2; i >= 0; i--) { /* Multiply a = y * x */ aa = ya * xa; ab = ya * xb + yb * xa + yb * xb; /* split, so now y = a */ tmp = aa * HEX_40000000; ya = aa + tmp - tmp; yb = aa - ya + ab; /* Add a = y + lnQuickCoef */ aa = ya + LN_QUICK_COEF[i][0]; ab = yb + LN_QUICK_COEF[i][1]; /* Split y = a */ tmp = aa * HEX_40000000; ya = aa + tmp - tmp; yb = aa - ya + ab; } /* Multiply a = y * x */ aa = ya * xa; ab = ya * xb + yb * xa + yb * xb; /* split, so now y = a */ tmp = aa * HEX_40000000; ya = aa + tmp - tmp; yb = aa - ya + ab; return ya + yb; } } // lnm is a log of a number in the range of 1.0 - 2.0, so 0 <= lnm < ln(2) double lnm[] = LN_MANT[(int)((bits & 0x000ffc0000000000L) >> 42)]; /* double epsilon = x / Double.longBitsToDouble(bits & 0xfffffc0000000000L); epsilon -= 1.0; */ // y is the most significant 10 bits of the mantissa //double y = Double.longBitsToDouble(bits & 0xfffffc0000000000L); //double epsilon = (x - y) / y; double epsilon = (bits & 0x3ffffffffffL) / (TWO_POWER_52 + (bits & 0x000ffc0000000000L)); double lnza = 0.0; double lnzb = 0.0; if (hiPrec != null) { /* split epsilon -> x */ double tmp = epsilon * HEX_40000000; double aa = epsilon + tmp - tmp; double ab = epsilon - aa; double xa = aa; double xb = ab; /* Need a more accurate epsilon, so adjust the division. */ double numer = bits & 0x3ffffffffffL; double denom = TWO_POWER_52 + (bits & 0x000ffc0000000000L); aa = numer - xa*denom - xb * denom; xb += aa / denom; /* Remez polynomial evaluation */ double ya = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][0]; double yb = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][1]; for (int i = LN_HI_PREC_COEF.length - 2; i >= 0; i--) { /* Multiply a = y * x */ aa = ya * xa; ab = ya * xb + yb * xa + yb * xb; /* split, so now y = a */ tmp = aa * HEX_40000000; ya = aa + tmp - tmp; yb = aa - ya + ab; /* Add a = y + lnHiPrecCoef */ aa = ya + LN_HI_PREC_COEF[i][0]; ab = yb + LN_HI_PREC_COEF[i][1]; /* Split y = a */ tmp = aa * HEX_40000000; ya = aa + tmp - tmp; yb = aa - ya + ab; } /* Multiply a = y * x */ aa = ya * xa; ab = ya * xb + yb * xa + yb * xb; /* split, so now lnz = a */ /* tmp = aa * 1073741824.0; lnza = aa + tmp - tmp; lnzb = aa - lnza + ab; */ lnza = aa + ab; lnzb = -(lnza - aa - ab); } else { /* High precision not required. Eval Remez polynomial using standard double precision */ lnza = -0.16624882440418567; lnza = lnza * epsilon + 0.19999954120254515; lnza = lnza * epsilon + -0.2499999997677497; lnza = lnza * epsilon + 0.3333333333332802; lnza = lnza * epsilon + -0.5; lnza = lnza * epsilon + 1.0; lnza = lnza * epsilon; } /* Relative sizes: * lnzb [0, 2.33E-10] * lnm[1] [0, 1.17E-7] * ln2B*exp [0, 1.12E-4] * lnza [0, 9.7E-4] * lnm[0] [0, 0.692] * ln2A*exp [0, 709] */ /* Compute the following sum: * lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp; */ //return lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp; double a = LN_2_A*exp; double b = 0.0; double c = a+lnm[0]; double d = -(c-a-lnm[0]); a = c; b = b + d; c = a + lnza; d = -(c - a - lnza); a = c; b = b + d; c = a + LN_2_B*exp; d = -(c - a - LN_2_B*exp); a = c; b = b + d; c = a + lnm[1]; d = -(c - a - lnm[1]); a = c; b = b + d; c = a + lnzb; d = -(c - a - lnzb); a = c; b = b + d; if (hiPrec != null) { hiPrec[0] = a; hiPrec[1] = b; } return a + b; } /** Compute log(1 + x). * @param x a number * @return log(1 + x) */ public static double log1p(final double x) { double xpa = 1.0 + x; double xpb = -(xpa - 1.0 - x); if (x == -1) { return x/0.0; // -Infinity } if (x > 0 && 1/x == 0) { // x = Infinity return x; } if (x>1e-6 || x<-1e-6) { double hiPrec[] = new double[2]; final double lores = log(xpa, hiPrec); if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN return lores; } /* Do a taylor series expansion around xpa */ /* f(x+y) = f(x) + f'(x)*y + f''(x)/2 y^2 */ double fx1 = xpb/xpa; double epsilon = 0.5 * fx1 + 1.0; epsilon = epsilon * fx1; return epsilon + hiPrec[1] + hiPrec[0]; } /* Value is small |x| < 1e6, do a Taylor series centered on 1.0 */ double y = x * 0.333333333333333 - 0.5; y = y * x + 1.0; y = y * x; return y; } /** Compute the base 10 logarithm. * @param x a number * @return log10(x) */ public static double log10(final double x) { final double hiPrec[] = new double[2]; final double lores = log(x, hiPrec); if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN return lores; } final double tmp = hiPrec[0] * HEX_40000000; final double lna = hiPrec[0] + tmp - tmp; final double lnb = hiPrec[0] - lna + hiPrec[1]; final double rln10a = 0.4342944622039795; final double rln10b = 1.9699272335463627E-8; return rln10b * lnb + rln10b * lna + rln10a * lnb + rln10a * lna; } /** * Power function. Compute x^y. * * @param x a double * @param y a double * @return double */ public static double pow(double x, double y) { final double lns[] = new double[2]; if (y == 0.0) { return 1.0; } if (x != x) { // X is NaN return x; } if (x == 0) { long bits = Double.doubleToLongBits(x); if ((bits & 0x8000000000000000L) != 0) { // -zero long yi = (long) y; if (y < 0 && y == yi && (yi & 1) == 1) { return Double.NEGATIVE_INFINITY; } if (y < 0 && y == yi && (yi & 1) == 1) { return -0.0; } if (y > 0 && y == yi && (yi & 1) == 1) { return -0.0; } } if (y < 0) { return Double.POSITIVE_INFINITY; } if (y > 0) { return 0.0; } return Double.NaN; } if (x == Double.POSITIVE_INFINITY) { if (y != y) { // y is NaN return y; } if (y < 0.0) { return 0.0; } else { return Double.POSITIVE_INFINITY; } } if (y == Double.POSITIVE_INFINITY) { if (x * x == 1.0) return Double.NaN; if (x * x > 1.0) { return Double.POSITIVE_INFINITY; } else { return 0.0; } } if (x == Double.NEGATIVE_INFINITY) { if (y != y) { // y is NaN return y; } if (y < 0) { long yi = (long) y; if (y == yi && (yi & 1) == 1) { return -0.0; } return 0.0; } if (y > 0) { long yi = (long) y; if (y == yi && (yi & 1) == 1) { return Double.NEGATIVE_INFINITY; } return Double.POSITIVE_INFINITY; } } if (y == Double.NEGATIVE_INFINITY) { if (x * x == 1.0) { return Double.NaN; } if (x * x < 1.0) { return Double.POSITIVE_INFINITY; } else { return 0.0; } } /* Handle special case x<0 */ if (x < 0) { // y is an even integer in this case if (y >= TWO_POWER_52 || y <= -TWO_POWER_52) { return pow(-x, y); } if (y == (long) y) { // If y is an integer return ((long)y & 1) == 0 ? pow(-x, y) : -pow(-x, y); } else { return Double.NaN; } } /* Split y into ya and yb such that y = ya+yb */ double ya; double yb; if (y < 8e298 && y > -8e298) { double tmp1 = y * HEX_40000000; ya = y + tmp1 - tmp1; yb = y - ya; } else { double tmp1 = y * 9.31322574615478515625E-10; double tmp2 = tmp1 * 9.31322574615478515625E-10; ya = (tmp1 + tmp2 - tmp1) * HEX_40000000 * HEX_40000000; yb = y - ya; } /* Compute ln(x) */ final double lores = log(x, lns); if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN return lores; } double lna = lns[0]; double lnb = lns[1]; /* resplit lns */ double tmp1 = lna * HEX_40000000; double tmp2 = lna + tmp1 - tmp1; lnb += lna - tmp2; lna = tmp2; // y*ln(x) = (aa+ab) final double aa = lna * ya; final double ab = lna * yb + lnb * ya + lnb * yb; lna = aa+ab; lnb = -(lna - aa - ab); double z = 1.0 / 120.0; z = z * lnb + (1.0 / 24.0); z = z * lnb + (1.0 / 6.0); z = z * lnb + 0.5; z = z * lnb + 1.0; z = z * lnb; final double result = exp(lna, z, null); //result = result + result * z; return result; } /** xi in the range of [1, 2]. * 3 5 7 * x+1 / x x x \ * ln ----- = 2 * | x + ---- + ---- + ---- + ... | * 1-x \ 3 5 7 / * * So, compute a Remez approximation of the following function * * ln ((sqrt(x)+1)/(1-sqrt(x))) / x * * This will be an even function with only positive coefficents. * x is in the range [0 - 1/3]. * * Transform xi for input to the above function by setting * x = (xi-1)/(xi+1). Input to the polynomial is x^2, then * the result is multiplied by x. * @param xi number from which log is requested * @return log(xi) */ private static double[] slowLog(double xi) { double x[] = new double[2]; double x2[] = new double[2]; double y[] = new double[2]; double a[] = new double[2]; split(xi, x); /* Set X = (x-1)/(x+1) */ x[0] += 1.0; resplit(x); splitReciprocal(x, a); x[0] -= 2.0; resplit(x); splitMult(x, a, y); x[0] = y[0]; x[1] = y[1]; /* Square X -> X2*/ splitMult(x, x, x2); //x[0] -= 1.0; //resplit(x); y[0] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][0]; y[1] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][1]; for (int i = LN_SPLIT_COEF.length-2; i >= 0; i--) { splitMult(y, x2, a); y[0] = a[0]; y[1] = a[1]; splitAdd(y, LN_SPLIT_COEF[i], a); y[0] = a[0]; y[1] = a[1]; } splitMult(y, x, a); y[0] = a[0]; y[1] = a[1]; return y; } /** * For x between 0 and pi/4 compute sine. * @param x number from which sine is requested * @param result placeholder where to put the result in extended precision * @return sin(x) */ private static double slowSin(final double x, final double result[]) { final double xs[] = new double[2]; final double ys[] = new double[2]; final double facts[] = new double[2]; final double as[] = new double[2]; split(x, xs); ys[0] = ys[1] = 0.0; for (int i = 19; i >= 0; i--) { splitMult(xs, ys, as); ys[0] = as[0]; ys[1] = as[1]; if ( (i & 1) == 0) { continue; } split(FACT[i], as); splitReciprocal(as, facts); if ( (i & 2) != 0 ) { facts[0] = -facts[0]; facts[1] = -facts[1]; } splitAdd(ys, facts, as); ys[0] = as[0]; ys[1] = as[1]; } if (result != null) { result[0] = ys[0]; result[1] = ys[1]; } return ys[0] + ys[1]; } /** * For x between 0 and pi/4 compute cosine * @param x number from which cosine is requested * @param result placeholder where to put the result in extended precision * @return cos(x) */ private static double slowCos(final double x, final double result[]) { final double xs[] = new double[2]; final double ys[] = new double[2]; final double facts[] = new double[2]; final double as[] = new double[2]; split(x, xs); ys[0] = ys[1] = 0.0; for (int i = 19; i >= 0; i--) { splitMult(xs, ys, as); ys[0] = as[0]; ys[1] = as[1]; if ( (i & 1) != 0) { continue; } split(FACT[i], as); splitReciprocal(as, facts); if ( (i & 2) != 0 ) { facts[0] = -facts[0]; facts[1] = -facts[1]; } splitAdd(ys, facts, as); ys[0] = as[0]; ys[1] = as[1]; } if (result != null) { result[0] = ys[0]; result[1] = ys[1]; } return ys[0] + ys[1]; } /** Build the sine and cosine tables. */ private static void buildSinCosTables() { final double result[] = new double[2]; /* Use taylor series for 0 <= x <= 6/8 */ for (int i = 0; i < 7; i++) { double x = i / 8.0; slowSin(x, result); SINE_TABLE_A[i] = result[0]; SINE_TABLE_B[i] = result[1]; slowCos(x, result); COSINE_TABLE_A[i] = result[0]; COSINE_TABLE_B[i] = result[1]; } /* Use angle addition formula to complete table to 13/8, just beyond pi/2 */ for (int i = 7; i < 14; i++) { double xs[] = new double[2]; double ys[] = new double[2]; double as[] = new double[2]; double bs[] = new double[2]; double temps[] = new double[2]; if ( (i & 1) == 0) { // Even, use double angle xs[0] = SINE_TABLE_A[i/2]; xs[1] = SINE_TABLE_B[i/2]; ys[0] = COSINE_TABLE_A[i/2]; ys[1] = COSINE_TABLE_B[i/2]; /* compute sine */ splitMult(xs, ys, result); SINE_TABLE_A[i] = result[0] * 2.0; SINE_TABLE_B[i] = result[1] * 2.0; /* Compute cosine */ splitMult(ys, ys, as); splitMult(xs, xs, temps); temps[0] = -temps[0]; temps[1] = -temps[1]; splitAdd(as, temps, result); COSINE_TABLE_A[i] = result[0]; COSINE_TABLE_B[i] = result[1]; } else { xs[0] = SINE_TABLE_A[i/2]; xs[1] = SINE_TABLE_B[i/2]; ys[0] = COSINE_TABLE_A[i/2]; ys[1] = COSINE_TABLE_B[i/2]; as[0] = SINE_TABLE_A[i/2+1]; as[1] = SINE_TABLE_B[i/2+1]; bs[0] = COSINE_TABLE_A[i/2+1]; bs[1] = COSINE_TABLE_B[i/2+1]; /* compute sine */ splitMult(xs, bs, temps); splitMult(ys, as, result); splitAdd(result, temps, result); SINE_TABLE_A[i] = result[0]; SINE_TABLE_B[i] = result[1]; /* Compute cosine */ splitMult(ys, bs, result); splitMult(xs, as, temps); temps[0] = -temps[0]; temps[1] = -temps[1]; splitAdd(result, temps, result); COSINE_TABLE_A[i] = result[0]; COSINE_TABLE_B[i] = result[1]; } } /* Compute tangent = sine/cosine */ for (int i = 0; i < 14; i++) { double xs[] = new double[2]; double ys[] = new double[2]; double as[] = new double[2]; as[0] = COSINE_TABLE_A[i]; as[1] = COSINE_TABLE_B[i]; splitReciprocal(as, ys); xs[0] = SINE_TABLE_A[i]; xs[1] = SINE_TABLE_B[i]; splitMult(xs, ys, as); TANGENT_TABLE_A[i] = as[0]; TANGENT_TABLE_B[i] = as[1]; } } /** * Computes sin(x) - x, where |x| < 1/16. * Use a Remez polynomial approximation. * @param x a number smaller than 1/16 * @return sin(x) - x */ private static double polySine(final double x) { double x2 = x*x; double p = 2.7553817452272217E-6; p = p * x2 + -1.9841269659586505E-4; p = p * x2 + 0.008333333333329196; p = p * x2 + -0.16666666666666666; //p *= x2; //p *= x; p = p * x2 * x; return p; } /** * Computes cos(x) - 1, where |x| < 1/16. * Use a Remez polynomial approximation. * @param x a number smaller than 1/16 * @return cos(x) - 1 */ private static double polyCosine(double x) { double x2 = x*x; double p = 2.479773539153719E-5; p = p * x2 + -0.0013888888689039883; p = p * x2 + 0.041666666666621166; p = p * x2 + -0.49999999999999994; p *= x2; return p; } /** * Compute sine over the first quadrant (0 < x < pi/2). * Use combination of table lookup and rational polynomial expansion. * @param xa number from which sine is requested * @param xb extra bits for x (may be 0.0) * @return sin(xa + xb) */ private static double sinQ(double xa, double xb) { int idx = (int) ((xa * 8.0) + 0.5); final double epsilon = xa - EIGHTHS[idx]; //idx*0.125; // Table lookups final double sintA = SINE_TABLE_A[idx]; final double sintB = SINE_TABLE_B[idx]; final double costA = COSINE_TABLE_A[idx]; final double costB = COSINE_TABLE_B[idx]; // Polynomial eval of sin(epsilon), cos(epsilon) double sinEpsA = epsilon; double sinEpsB = polySine(epsilon); final double cosEpsA = 1.0; final double cosEpsB = polyCosine(epsilon); // Split epsilon xa + xb = x final double temp = sinEpsA * HEX_40000000; double temp2 = (sinEpsA + temp) - temp; sinEpsB += sinEpsA - temp2; sinEpsA = temp2; /* Compute sin(x) by angle addition formula */ double result; /* Compute the following sum: * * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + * sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; * * Ranges of elements * * xxxtA 0 PI/2 * xxxtB -1.5e-9 1.5e-9 * sinEpsA -0.0625 0.0625 * sinEpsB -6e-11 6e-11 * cosEpsA 1.0 * cosEpsB 0 -0.0625 * */ //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + // sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB; //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB; double a = 0; double b = 0; double t = sintA; double c = a + t; double d = -(c - a - t); a = c; b = b + d; t = costA * sinEpsA; c = a + t; d = -(c - a - t); a = c; b = b + d; b = b + sintA * cosEpsB + costA * sinEpsB; /* t = sintA*cosEpsB; c = a + t; d = -(c - a - t); a = c; b = b + d; t = costA*sinEpsB; c = a + t; d = -(c - a - t); a = c; b = b + d; */ b = b + sintB + costB * sinEpsA + sintB * cosEpsB + costB * sinEpsB; /* t = sintB; c = a + t; d = -(c - a - t); a = c; b = b + d; t = costB*sinEpsA; c = a + t; d = -(c - a - t); a = c; b = b + d; t = sintB*cosEpsB; c = a + t; d = -(c - a - t); a = c; b = b + d; t = costB*sinEpsB; c = a + t; d = -(c - a - t); a = c; b = b + d; */ if (xb != 0.0) { t = ((costA + costB) * (cosEpsA + cosEpsB) - (sintA + sintB) * (sinEpsA + sinEpsB)) * xb; // approximate cosine*xb c = a + t; d = -(c - a - t); a = c; b = b + d; } result = a + b; return result; } /** * Compute cosine in the first quadrant by subtracting input from PI/2 and * then calling sinQ. This is more accurate as the input approaches PI/2. * @param xa number from which cosine is requested * @param xb extra bits for x (may be 0.0) * @return cos(xa + xb) */ private static double cosQ(double xa, double xb) { final double pi2a = 1.5707963267948966; final double pi2b = 6.123233995736766E-17; final double a = pi2a - xa; double b = -(a - pi2a + xa); b += pi2b - xb; return sinQ(a, b); } /** * Compute tangent (or cotangent) over the first quadrant. 0 < x < pi/2 * Use combination of table lookup and rational polynomial expansion. * @param xa number from which sine is requested * @param xb extra bits for x (may be 0.0) * @param cotanFlag if true, compute the cotangent instead of the tangent * @return tan(xa+xb) (or cotangent, depending on cotanFlag) */ private static double tanQ(double xa, double xb, boolean cotanFlag) { int idx = (int) ((xa * 8.0) + 0.5); final double epsilon = xa - EIGHTHS[idx]; //idx*0.125; // Table lookups final double sintA = SINE_TABLE_A[idx]; final double sintB = SINE_TABLE_B[idx]; final double costA = COSINE_TABLE_A[idx]; final double costB = COSINE_TABLE_B[idx]; // Polynomial eval of sin(epsilon), cos(epsilon) double sinEpsA = epsilon; double sinEpsB = polySine(epsilon); final double cosEpsA = 1.0; final double cosEpsB = polyCosine(epsilon); // Split epsilon xa + xb = x double temp = sinEpsA * HEX_40000000; double temp2 = (sinEpsA + temp) - temp; sinEpsB += sinEpsA - temp2; sinEpsA = temp2; /* Compute sin(x) by angle addition formula */ /* Compute the following sum: * * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + * sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; * * Ranges of elements * * xxxtA 0 PI/2 * xxxtB -1.5e-9 1.5e-9 * sinEpsA -0.0625 0.0625 * sinEpsB -6e-11 6e-11 * cosEpsA 1.0 * cosEpsB 0 -0.0625 * */ //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB + // sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB; //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB; double a = 0; double b = 0; // Compute sine double t = sintA; double c = a + t; double d = -(c - a - t); a = c; b = b + d; t = costA*sinEpsA; c = a + t; d = -(c - a - t); a = c; b = b + d; b = b + sintA*cosEpsB + costA*sinEpsB; b = b + sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB; double sina = a + b; double sinb = -(sina - a - b); // Compute cosine a = b = c = d = 0.0; t = costA*cosEpsA; c = a + t; d = -(c - a - t); a = c; b = b + d; t = -sintA*sinEpsA; c = a + t; d = -(c - a - t); a = c; b = b + d; b = b + costB*cosEpsA + costA*cosEpsB + costB*cosEpsB; b = b - (sintB*sinEpsA + sintA*sinEpsB + sintB*sinEpsB); double cosa = a + b; double cosb = -(cosa - a - b); if (cotanFlag) { double tmp; tmp = cosa; cosa = sina; sina = tmp; tmp = cosb; cosb = sinb; sinb = tmp; } /* estimate and correct, compute 1.0/(cosa+cosb) */ /* double est = (sina+sinb)/(cosa+cosb); double err = (sina - cosa*est) + (sinb - cosb*est); est += err/(cosa+cosb); err = (sina - cosa*est) + (sinb - cosb*est); */ // f(x) = 1/x, f'(x) = -1/x^2 double est = sina/cosa; /* Split the estimate to get more accurate read on division rounding */ temp = est * HEX_40000000; double esta = (est + temp) - temp; double estb = est - esta; temp = cosa * HEX_40000000; double cosaa = (cosa + temp) - temp; double cosab = cosa - cosaa; //double err = (sina - est*cosa)/cosa; // Correction for division rounding double err = (sina - esta*cosaa - esta*cosab - estb*cosaa - estb*cosab)/cosa; // Correction for division rounding err += sinb/cosa; // Change in est due to sinb err += -sina * cosb / cosa / cosa; // Change in est due to cosb if (xb != 0.0) { // tan' = 1 + tan^2 cot' = -(1 + cot^2) // Approximate impact of xb double xbadj = xb + est*est*xb; if (cotanFlag) { xbadj = -xbadj; } err += xbadj; } return est+err; } /** Reduce the input argument using the Payne and Hanek method. * This is good for all inputs 0.0 < x < inf * Output is remainder after dividing by PI/2 * The result array should contain 3 numbers. * result[0] is the integer portion, so mod 4 this gives the quadrant. * result[1] is the upper bits of the remainder * result[2] is the lower bits of the remainder * * @param x number to reduce * @param result placeholder where to put the result */ private static void reducePayneHanek(double x, double result[]) { /* Convert input double to bits */ long inbits = Double.doubleToLongBits(x); int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; /* Convert to fixed point representation */ inbits &= 0x000fffffffffffffL; inbits |= 0x0010000000000000L; /* Normalize input to be between 0.5 and 1.0 */ exponent++; inbits <<= 11; /* Based on the exponent, get a shifted copy of recip2pi */ long shpi0; long shpiA; long shpiB; int idx = exponent >> 6; int shift = exponent - (idx << 6); if (shift != 0) { shpi0 = (idx == 0) ? 0 : (RECIP_2PI[idx-1] << shift); shpi0 |= RECIP_2PI[idx] >>> (64-shift); shpiA = (RECIP_2PI[idx] << shift) | (RECIP_2PI[idx+1] >>> (64-shift)); shpiB = (RECIP_2PI[idx+1] << shift) | (RECIP_2PI[idx+2] >>> (64-shift)); } else { shpi0 = (idx == 0) ? 0 : RECIP_2PI[idx-1]; shpiA = RECIP_2PI[idx]; shpiB = RECIP_2PI[idx+1]; } /* Multiply input by shpiA */ long a = inbits >>> 32; long b = inbits & 0xffffffffL; long c = shpiA >>> 32; long d = shpiA & 0xffffffffL; long ac = a * c; long bd = b * d; long bc = b * c; long ad = a * d; long prodB = bd + (ad << 32); long prodA = ac + (ad >>> 32); boolean bita = (bd & 0x8000000000000000L) != 0; boolean bitb = (ad & 0x80000000L ) != 0; boolean bitsum = (prodB & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prodA++; } bita = (prodB & 0x8000000000000000L) != 0; bitb = (bc & 0x80000000L ) != 0; prodB = prodB + (bc << 32); prodA = prodA + (bc >>> 32); bitsum = (prodB & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prodA++; } /* Multiply input by shpiB */ c = shpiB >>> 32; d = shpiB & 0xffffffffL; ac = a * c; bc = b * c; ad = a * d; /* Collect terms */ ac = ac + ((bc + ad) >>> 32); bita = (prodB & 0x8000000000000000L) != 0; bitb = (ac & 0x8000000000000000L ) != 0; prodB += ac; bitsum = (prodB & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prodA++; } /* Multiply by shpi0 */ c = shpi0 >>> 32; d = shpi0 & 0xffffffffL; bd = b * d; bc = b * c; ad = a * d; prodA += bd + ((bc + ad) << 32); /* * prodA, prodB now contain the remainder as a fraction of PI. We want this as a fraction of * PI/2, so use the following steps: * 1.) multiply by 4. * 2.) do a fixed point muliply by PI/4. * 3.) Convert to floating point. * 4.) Multiply by 2 */ /* This identifies the quadrant */ int intPart = (int)(prodA >>> 62); /* Multiply by 4 */ prodA <<= 2; prodA |= prodB >>> 62; prodB <<= 2; /* Multiply by PI/4 */ a = prodA >>> 32; b = prodA & 0xffffffffL; c = PI_O_4_BITS[0] >>> 32; d = PI_O_4_BITS[0] & 0xffffffffL; ac = a * c; bd = b * d; bc = b * c; ad = a * d; long prod2B = bd + (ad << 32); long prod2A = ac + (ad >>> 32); bita = (bd & 0x8000000000000000L) != 0; bitb = (ad & 0x80000000L ) != 0; bitsum = (prod2B & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prod2A++; } bita = (prod2B & 0x8000000000000000L) != 0; bitb = (bc & 0x80000000L ) != 0; prod2B = prod2B + (bc << 32); prod2A = prod2A + (bc >>> 32); bitsum = (prod2B & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prod2A++; } /* Multiply input by pio4bits[1] */ c = PI_O_4_BITS[1] >>> 32; d = PI_O_4_BITS[1] & 0xffffffffL; ac = a * c; bc = b * c; ad = a * d; /* Collect terms */ ac = ac + ((bc + ad) >>> 32); bita = (prod2B & 0x8000000000000000L) != 0; bitb = (ac & 0x8000000000000000L ) != 0; prod2B += ac; bitsum = (prod2B & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prod2A++; } /* Multiply inputB by pio4bits[0] */ a = prodB >>> 32; b = prodB & 0xffffffffL; c = PI_O_4_BITS[0] >>> 32; d = PI_O_4_BITS[0] & 0xffffffffL; ac = a * c; bc = b * c; ad = a * d; /* Collect terms */ ac = ac + ((bc + ad) >>> 32); bita = (prod2B & 0x8000000000000000L) != 0; bitb = (ac & 0x8000000000000000L ) != 0; prod2B += ac; bitsum = (prod2B & 0x8000000000000000L) != 0; /* Carry */ if ( (bita && bitb) || ((bita || bitb) && !bitsum) ) { prod2A++; } /* Convert to double */ double tmpA = (prod2A >>> 12) / TWO_POWER_52; // High order 52 bits double tmpB = (((prod2A & 0xfffL) << 40) + (prod2B >>> 24)) / TWO_POWER_52 / TWO_POWER_52; // Low bits double sumA = tmpA + tmpB; double sumB = -(sumA - tmpA - tmpB); /* Multiply by PI/2 and return */ result[0] = intPart; result[1] = sumA * 2.0; result[2] = sumB * 2.0; } /** * Sine function. * @param x a number * @return sin(x) */ public static double sin(double x) { boolean negative = false; int quadrant = 0; double xa; double xb = 0.0; /* Take absolute value of the input */ xa = x; if (x < 0) { negative = true; xa = -xa; } /* Check for zero and negative zero */ if (xa == 0.0) { long bits = Double.doubleToLongBits(x); if (bits < 0) { return -0.0; } return 0.0; } if (xa != xa || xa == Double.POSITIVE_INFINITY) { return Double.NaN; } /* Perform any argument reduction */ if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double reduceResults[] = new double[3]; reducePayneHanek(xa, reduceResults); quadrant = ((int) reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { /* Inline the Cody/Waite reduction for performance */ // Estimate k //k = (int)(xa / 1.5707963267948966); int k = (int)(xa * 0.6366197723675814); // Compute remainder double remA; double remB; while (true) { double a = -k * 1.570796251296997; remA = xa + a; remB = -(remA - xa - a); a = -k * 7.549789948768648E-8; double b = remA; remA = a + b; remB += -(remA - b - a); a = -k * 6.123233995736766E-17; b = remA; remA = a + b; remB += -(remA - b - a); if (remA > 0.0) break; // Remainder is negative, so decrement k and try again. // This should only happen if the input is very close // to an even multiple of pi/2 k--; } quadrant = k & 3; xa = remA; xb = remB; } if (negative) { quadrant ^= 2; // Flip bit 1 } switch (quadrant) { case 0: return sinQ(xa, xb); case 1: return cosQ(xa, xb); case 2: return -sinQ(xa, xb); case 3: return -cosQ(xa, xb); default: return Double.NaN; } } /** * Cosine function * @param x a number * @return cos(x) */ public static double cos(double x) { int quadrant = 0; /* Take absolute value of the input */ double xa = x; if (x < 0) { xa = -xa; } if (xa != xa || xa == Double.POSITIVE_INFINITY) { return Double.NaN; } /* Perform any argument reduction */ double xb = 0; if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double reduceResults[] = new double[3]; reducePayneHanek(xa, reduceResults); quadrant = ((int) reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { /* Inline the Cody/Waite reduction for performance */ // Estimate k //k = (int)(xa / 1.5707963267948966); int k = (int)(xa * 0.6366197723675814); // Compute remainder double remA; double remB; while (true) { double a = -k * 1.570796251296997; remA = xa + a; remB = -(remA - xa - a); a = -k * 7.549789948768648E-8; double b = remA; remA = a + b; remB += -(remA - b - a); a = -k * 6.123233995736766E-17; b = remA; remA = a + b; remB += -(remA - b - a); if (remA > 0.0) break; // Remainder is negative, so decrement k and try again. // This should only happen if the input is very close // to an even multiple of pi/2 k--; } quadrant = k & 3; xa = remA; xb = remB; } //if (negative) // quadrant = (quadrant + 2) % 4; switch (quadrant) { case 0: return cosQ(xa, xb); case 1: return -sinQ(xa, xb); case 2: return -cosQ(xa, xb); case 3: return sinQ(xa, xb); default: return Double.NaN; } } /** * Tangent function * @param x a number * @return tan(x) */ public static double tan(double x) { boolean negative = false; int quadrant = 0; /* Take absolute value of the input */ double xa = x; if (x < 0) { negative = true; xa = -xa; } /* Check for zero and negative zero */ if (xa == 0.0) { long bits = Double.doubleToLongBits(x); if (bits < 0) { return -0.0; } return 0.0; } if (xa != xa || xa == Double.POSITIVE_INFINITY) { return Double.NaN; } /* Perform any argument reduction */ double xb = 0; if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double reduceResults[] = new double[3]; reducePayneHanek(xa, reduceResults); quadrant = ((int) reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { /* Inline the Cody/Waite reduction for performance */ // Estimate k //k = (int)(xa / 1.5707963267948966); int k = (int)(xa * 0.6366197723675814); // Compute remainder double remA; double remB; while (true) { double a = -k * 1.570796251296997; remA = xa + a; remB = -(remA - xa - a); a = -k * 7.549789948768648E-8; double b = remA; remA = a + b; remB += -(remA - b - a); a = -k * 6.123233995736766E-17; b = remA; remA = a + b; remB += -(remA - b - a); if (remA > 0.0) break; // Remainder is negative, so decrement k and try again. // This should only happen if the input is very close // to an even multiple of pi/2 k--; } quadrant = k & 3; xa = remA; xb = remB; } if (xa > 1.5) { // Accurracy suffers between 1.5 and PI/2 final double pi2a = 1.5707963267948966; final double pi2b = 6.123233995736766E-17; final double a = pi2a - xa; double b = -(a - pi2a + xa); b += pi2b - xb; xa = a + b; xb = -(xa - a - b); quadrant ^= 1; negative ^= true; } double result; if ((quadrant & 1) == 0) { result = tanQ(xa, xb, false); } else { result = -tanQ(xa, xb, true); } if (negative) { result = -result; } return result; } /** * Arctangent function * @param x a number * @return atan(x) */ public static double atan(double x) { return atan(x, 0.0, false); } /** Internal helper function to compute arctangent. * @param xa number from which arctangent is requested * @param xb extra bits for x (may be 0.0) * @param leftPlane if true, result angle must be put in the left half plane * @return atan(xa + xb) (or angle shifted by {@code PI} if leftPlane is true) */ private static double atan(double xa, double xb, boolean leftPlane) { boolean negate = false; int idx; if (xa == 0.0) { // Matches +/- 0.0; return correct sign return leftPlane ? copySign(Math.PI, xa) : xa; } if (xa < 0) { // negative xa = -xa; xb = -xb; negate = true; } if (xa > 1.633123935319537E16) { // Very large input return (negate ^ leftPlane) ? (-Math.PI/2.0) : (Math.PI/2.0); } /* Estimate the closest tabulated arctan value, compute eps = xa-tangentTable */ if (xa < 1.0) { idx = (int) (((-1.7168146928204136 * xa * xa + 8.0) * xa) + 0.5); } else { double temp = 1.0/xa; idx = (int) (-((-1.7168146928204136 * temp * temp + 8.0) * temp) + 13.07); } double epsA = xa - TANGENT_TABLE_A[idx]; double epsB = -(epsA - xa + TANGENT_TABLE_A[idx]); epsB += xb - TANGENT_TABLE_B[idx]; double temp = epsA + epsB; epsB = -(temp - epsA - epsB); epsA = temp; /* Compute eps = eps / (1.0 + xa*tangent) */ temp = xa * HEX_40000000; double ya = xa + temp - temp; double yb = xb + xa - ya; xa = ya; xb += yb; //if (idx > 8 || idx == 0) if (idx == 0) { /* If the slope of the arctan is gentle enough (< 0.45), this approximation will suffice */ //double denom = 1.0 / (1.0 + xa*tangentTableA[idx] + xb*tangentTableA[idx] + xa*tangentTableB[idx] + xb*tangentTableB[idx]); double denom = 1.0 / (1.0 + (xa + xb) * (TANGENT_TABLE_A[idx] + TANGENT_TABLE_B[idx])); //double denom = 1.0 / (1.0 + xa*tangentTableA[idx]); ya = epsA * denom; yb = epsB * denom; } else { double temp2 = xa * TANGENT_TABLE_A[idx]; double za = 1.0 + temp2; double zb = -(za - 1.0 - temp2); temp2 = xb * TANGENT_TABLE_A[idx] + xa * TANGENT_TABLE_B[idx]; temp = za + temp2; zb += -(temp - za - temp2); za = temp; zb += xb * TANGENT_TABLE_B[idx]; ya = epsA / za; temp = ya * HEX_40000000; final double yaa = (ya + temp) - temp; final double yab = ya - yaa; temp = za * HEX_40000000; final double zaa = (za + temp) - temp; final double zab = za - zaa; /* Correct for rounding in division */ yb = (epsA - yaa * zaa - yaa * zab - yab * zaa - yab * zab) / za; yb += -epsA * zb / za / za; yb += epsB / za; } epsA = ya; epsB = yb; /* Evaluate polynomial */ double epsA2 = epsA*epsA; /* yb = -0.09001346640161823; yb = yb * epsA2 + 0.11110718400605211; yb = yb * epsA2 + -0.1428571349122913; yb = yb * epsA2 + 0.19999999999273194; yb = yb * epsA2 + -0.33333333333333093; yb = yb * epsA2 * epsA; */ yb = 0.07490822288864472; yb = yb * epsA2 + -0.09088450866185192; yb = yb * epsA2 + 0.11111095942313305; yb = yb * epsA2 + -0.1428571423679182; yb = yb * epsA2 + 0.19999999999923582; yb = yb * epsA2 + -0.33333333333333287; yb = yb * epsA2 * epsA; ya = epsA; temp = ya + yb; yb = -(temp - ya - yb); ya = temp; /* Add in effect of epsB. atan'(x) = 1/(1+x^2) */ yb += epsB / (1.0 + epsA * epsA); double result; double resultb; //result = yb + eighths[idx] + ya; double za = EIGHTHS[idx] + ya; double zb = -(za - EIGHTHS[idx] - ya); temp = za + yb; zb += -(temp - za - yb); za = temp; result = za + zb; resultb = -(result - za - zb); if (leftPlane) { // Result is in the left plane final double pia = 1.5707963267948966*2.0; final double pib = 6.123233995736766E-17*2.0; za = pia - result; zb = -(za - pia + result); zb += pib - resultb; result = za + zb; resultb = -(result - za - zb); } if (negate ^ leftPlane) { result = -result; } return result; } /** * Two arguments arctangent function * @param y ordinate * @param x abscissa * @return phase angle of point (x,y) between {@code -PI} and {@code PI} */ public static double atan2(double y, double x) { if (x !=x || y != y) { return Double.NaN; } if (y == 0.0) { double result = x*y; double invx = 1.0/x; double invy = 1.0/y; if (invx == 0.0) { // X is infinite if (x > 0) { return y; // return +/- 0.0 } else { return copySign(Math.PI, y); } } if (x < 0.0 || invx < 0.0) { if (y < 0.0 || invy < 0.0) { return -Math.PI; } else { return Math.PI; } } else { return result; } } // y cannot now be zero if (y == Double.POSITIVE_INFINITY) { if (x == Double.POSITIVE_INFINITY) { return Math.PI/4.0; } if (x == Double.NEGATIVE_INFINITY) { return Math.PI*3.0/4.0; } return Math.PI/2.0; } if (y == Double.NEGATIVE_INFINITY) { if (x == Double.POSITIVE_INFINITY) { return -Math.PI/4.0; } if (x == Double.NEGATIVE_INFINITY) { return -Math.PI*3.0/4.0; } return -Math.PI/2.0; } if (x == Double.POSITIVE_INFINITY) { if (y > 0.0 || 1/y > 0.0) { return 0.0; } if (y < 0.0 || 1/y < 0.0) { return -0.0; } } if (x == Double.NEGATIVE_INFINITY) { if (y > 0.0 || 1/y > 0.0) { return Math.PI; } if (y < 0.0 || 1/y < 0.0) { return -Math.PI; } } // Neither y nor x can be infinite or NAN here if (x == 0) { if (y > 0.0 || 1/y > 0.0) { return Math.PI/2.0; } if (y < 0.0 || 1/y < 0.0) { return -Math.PI/2.0; } } // Compute ratio r = y/x final double r = y/x; if (Double.isInfinite(r)) { // bypass calculations that can create NaN return atan(r, 0, x < 0); } double ra = doubleHighPart(r); double rb = r - ra; // Split x final double xa = doubleHighPart(x); final double xb = x - xa; rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x; double temp = ra + rb; rb = -(temp - ra - rb); ra = temp; if (ra == 0) { // Fix up the sign so atan works correctly ra = copySign(0.0, y); } // Call atan double result = atan(ra, rb, x < 0); return result; } /** Compute the arc sine of a number. * @param x number on which evaluation is done * @return arc sine of x */ public static double asin(double x) { if (x != x) { return Double.NaN; } if (x > 1.0 || x < -1.0) { return Double.NaN; } if (x == 1.0) { return Math.PI/2.0; } if (x == -1.0) { return -Math.PI/2.0; } if (x == 0.0) { // Matches +/- 0.0; return correct sign return x; } /* Compute asin(x) = atan(x/sqrt(1-x*x)) */ /* Split x */ double temp = x * HEX_40000000; final double xa = x + temp - temp; final double xb = x - xa; /* Square it */ double ya = xa*xa; double yb = xa*xb*2.0 + xb*xb; /* Subtract from 1 */ ya = -ya; yb = -yb; double za = 1.0 + ya; double zb = -(za - 1.0 - ya); temp = za + yb; zb += -(temp - za - yb); za = temp; /* Square root */ double y; y = sqrt(za); temp = y * HEX_40000000; ya = y + temp - temp; yb = y - ya; /* Extend precision of sqrt */ yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y); /* Contribution of zb to sqrt */ double dx = zb / (2.0*y); // Compute ratio r = x/y double r = x/y; temp = r * HEX_40000000; double ra = r + temp - temp; double rb = r - ra; rb += (x - ra*ya - ra*yb - rb*ya - rb*yb) / y; // Correct for rounding in division rb += -x * dx / y / y; // Add in effect additional bits of sqrt. temp = ra + rb; rb = -(temp - ra - rb); ra = temp; return atan(ra, rb, false); } /** Compute the arc cosine of a number. * @param x number on which evaluation is done * @return arc cosine of x */ public static double acos(double x) { if (x != x) { return Double.NaN; } if (x > 1.0 || x < -1.0) { return Double.NaN; } if (x == -1.0) { return Math.PI; } if (x == 1.0) { return 0.0; } if (x == 0) { return Math.PI/2.0; } /* Compute acos(x) = atan(sqrt(1-x*x)/x) */ /* Split x */ double temp = x * HEX_40000000; final double xa = x + temp - temp; final double xb = x - xa; /* Square it */ double ya = xa*xa; double yb = xa*xb*2.0 + xb*xb; /* Subtract from 1 */ ya = -ya; yb = -yb; double za = 1.0 + ya; double zb = -(za - 1.0 - ya); temp = za + yb; zb += -(temp - za - yb); za = temp; /* Square root */ double y = sqrt(za); temp = y * HEX_40000000; ya = y + temp - temp; yb = y - ya; /* Extend precision of sqrt */ yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y); /* Contribution of zb to sqrt */ yb += zb / (2.0*y); y = ya+yb; yb = -(y - ya - yb); // Compute ratio r = y/x double r = y/x; // Did r overflow? if (Double.isInfinite(r)) { // x is effectively zero return Math.PI/2; // so return the appropriate value } double ra = doubleHighPart(r); double rb = r - ra; rb += (y - ra*xa - ra*xb - rb*xa - rb*xb) / x; // Correct for rounding in division rb += yb / x; // Add in effect additional bits of sqrt. temp = ra + rb; rb = -(temp - ra - rb); ra = temp; return atan(ra, rb, x<0); } /** Compute the cubic root of a number. * @param x number on which evaluation is done * @return cubic root of x */ public static double cbrt(double x) { /* Convert input double to bits */ long inbits = Double.doubleToLongBits(x); int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; boolean subnormal = false; if (exponent == -1023) { if (x == 0) { return x; } /* Subnormal, so normalize */ subnormal = true; x *= 1.8014398509481984E16; // 2^54 inbits = Double.doubleToLongBits(x); exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; } if (exponent == 1024) { // Nan or infinity. Don't care which. return x; } /* Divide the exponent by 3 */ int exp3 = exponent / 3; /* p2 will be the nearest power of 2 to x with its exponent divided by 3 */ double p2 = Double.longBitsToDouble((inbits & 0x8000000000000000L) | (long)(((exp3 + 1023) & 0x7ff)) << 52); /* This will be a number between 1 and 2 */ final double mant = Double.longBitsToDouble((inbits & 0x000fffffffffffffL) | 0x3ff0000000000000L); /* Estimate the cube root of mant by polynomial */ double est = -0.010714690733195933; est = est * mant + 0.0875862700108075; est = est * mant + -0.3058015757857271; est = est * mant + 0.7249995199969751; est = est * mant + 0.5039018405998233; est *= CBRTTWO[exponent % 3 + 2]; // est should now be good to about 15 bits of precision. Do 2 rounds of // Newton's method to get closer, this should get us full double precision // Scale down x for the purpose of doing newtons method. This avoids over/under flows. final double xs = x / (p2*p2*p2); est += (xs - est*est*est) / (3*est*est); est += (xs - est*est*est) / (3*est*est); // Do one round of Newton's method in extended precision to get the last bit right. double temp = est * HEX_40000000; double ya = est + temp - temp; double yb = est - ya; double za = ya * ya; double zb = ya * yb * 2.0 + yb * yb; temp = za * HEX_40000000; double temp2 = za + temp - temp; zb += za - temp2; za = temp2; zb = za * yb + ya * zb + zb * yb; za = za * ya; double na = xs - za; double nb = -(na - xs + za); nb -= zb; est += (na+nb)/(3*est*est); /* Scale by a power of two, so this is exact. */ est *= p2; if (subnormal) { est *= 3.814697265625E-6; // 2^-18 } return est; } /** * Convert degrees to radians, with error of less than 0.5 ULP * @param x angle in degrees * @return x converted into radians */ public static double toRadians(double x) { if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign return x; } // These are PI/180 split into high and low order bits final double facta = 0.01745329052209854; final double factb = 1.997844754509471E-9; double xa = doubleHighPart(x); double xb = x - xa; double result = xb * factb + xb * facta + xa * factb + xa * facta; if (result == 0) { result = result * x; // ensure correct sign if calculation underflows } return result; } /** * Convert radians to degrees, with error of less than 0.5 ULP * @param x angle in radians * @return x converted into degrees */ public static double toDegrees(double x) { if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign return x; } // These are 180/PI split into high and low order bits final double facta = 57.2957763671875; final double factb = 3.145894820876798E-6; double xa = doubleHighPart(x); double xb = x - xa; return xb * factb + xb * facta + xa * factb + xa * facta; } /** * Absolute value. * @param x number from which absolute value is requested * @return abs(x) */ public static int abs(final int x) { return (x < 0) ? -x : x; } /** * Absolute value. * @param x number from which absolute value is requested * @return abs(x) */ public static long abs(final long x) { return (x < 0l) ? -x : x; } /** * Absolute value. * @param x number from which absolute value is requested * @return abs(x) */ public static float abs(final float x) { return (x < 0.0f) ? -x : (x == 0.0f) ? 0.0f : x; // -0.0 => +0.0 } /** * Absolute value. * @param x number from which absolute value is requested * @return abs(x) */ public static double abs(double x) { return (x < 0.0) ? -x : (x == 0.0) ? 0.0 : x; // -0.0 => +0.0 } /** * Compute least significant bit (Unit in Last Position) for a number. * @param x number from which ulp is requested * @return ulp(x) */ public static double ulp(double x) { if (Double.isInfinite(x)) { return Double.POSITIVE_INFINITY; } return abs(x - Double.longBitsToDouble(Double.doubleToLongBits(x) ^ 1)); } /** * Compute least significant bit (Unit in Last Position) for a number. * @param x number from which ulp is requested * @return ulp(x) */ public static float ulp(float x) { if (Float.isInfinite(x)) { return Float.POSITIVE_INFINITY; } return abs(x - Float.intBitsToFloat(Float.floatToIntBits(x) ^ 1)); } /** * Multiply a double number by a power of 2. * @param d number to multiply * @param n power of 2 * @return d × 2n */ public static double scalb(final double d, final int n) { // first simple and fast handling when 2^n can be represented using normal numbers if ((n > -1023) && (n < 1024)) { return d * Double.longBitsToDouble(((long) (n + 1023)) << 52); } // handle special cases if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) { return d; } if (n < -2098) { return (d > 0) ? 0.0 : -0.0; } if (n > 2097) { return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } // decompose d final long bits = Double.doubleToLongBits(d); final long sign = bits & 0x8000000000000000L; int exponent = ((int) (bits >>> 52)) & 0x7ff; long mantissa = bits & 0x000fffffffffffffL; // compute scaled exponent int scaledExponent = exponent + n; if (n < 0) { // we are really in the case n <= -1023 if (scaledExponent > 0) { // both the input and the result are normal numbers, we only adjust the exponent return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else if (scaledExponent > -53) { // the input is a normal number and the result is a subnormal number // recover the hidden mantissa bit mantissa = mantissa | (1L << 52); // scales down complete mantissa, hence losing least significant bits final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent)); mantissa = mantissa >>> (1 - scaledExponent); if (mostSignificantLostBit != 0) { // we need to add 1 bit to round up the result mantissa++; } return Double.longBitsToDouble(sign | mantissa); } else { // no need to compute the mantissa, the number scales down to 0 return (sign == 0L) ? 0.0 : -0.0; } } else { // we are really in the case n >= 1024 if (exponent == 0) { // the input number is subnormal, normalize it while ((mantissa >>> 52) != 1) { mantissa = mantissa << 1; --scaledExponent; } ++scaledExponent; mantissa = mantissa & 0x000fffffffffffffL; if (scaledExponent < 2047) { return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else { return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } } else if (scaledExponent < 2047) { return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else { return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } } } /** * Multiply a float number by a power of 2. * @param f number to multiply * @param n power of 2 * @return f × 2n */ public static float scalb(final float f, final int n) { // first simple and fast handling when 2^n can be represented using normal numbers if ((n > -127) && (n < 128)) { return f * Float.intBitsToFloat((n + 127) << 23); } // handle special cases if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) { return f; } if (n < -277) { return (f > 0) ? 0.0f : -0.0f; } if (n > 276) { return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; } // decompose f final int bits = Float.floatToIntBits(f); final int sign = bits & 0x80000000; int exponent = (bits >>> 23) & 0xff; int mantissa = bits & 0x007fffff; // compute scaled exponent int scaledExponent = exponent + n; if (n < 0) { // we are really in the case n <= -127 if (scaledExponent > 0) { // both the input and the result are normal numbers, we only adjust the exponent return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); } else if (scaledExponent > -24) { // the input is a normal number and the result is a subnormal number // recover the hidden mantissa bit mantissa = mantissa | (1 << 23); // scales down complete mantissa, hence losing least significant bits final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent)); mantissa = mantissa >>> (1 - scaledExponent); if (mostSignificantLostBit != 0) { // we need to add 1 bit to round up the result mantissa++; } return Float.intBitsToFloat(sign | mantissa); } else { // no need to compute the mantissa, the number scales down to 0 return (sign == 0) ? 0.0f : -0.0f; } } else { // we are really in the case n >= 128 if (exponent == 0) { // the input number is subnormal, normalize it while ((mantissa >>> 23) != 1) { mantissa = mantissa << 1; --scaledExponent; } ++scaledExponent; mantissa = mantissa & 0x007fffff; if (scaledExponent < 255) { return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); } else { return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; } } else if (scaledExponent < 255) { return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa); } else { return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY; } } } /** * Get the next machine representable number after a number, moving * in the direction of another number. *

                        * The ordering is as follows (increasing): *

                          *
                        • -INFINITY
                        • *
                        • -MAX_VALUE
                        • *
                        • -MIN_VALUE
                        • *
                        • -0.0
                        • *
                        • +0.0
                        • *
                        • +MIN_VALUE
                        • *
                        • +MAX_VALUE
                        • *
                        • +INFINITY
                        • *
                        • *

                          * If arguments compare equal, then the second argument is returned. *

                          * If {@code direction} is greater than {@code d}, * the smallest machine representable number strictly greater than * {@code d} is returned; if less, then the largest representable number * strictly less than {@code d} is returned.

                          *

                          * If {@code d} is infinite and direction does not * bring it back to finite numbers, it is returned unchanged.

                          * * @param d base number * @param direction (the only important thing is whether * {@code direction} is greater or smaller than {@code d}) * @return the next machine representable number in the specified direction */ public static double nextAfter(double d, double direction) { // handling of some important special cases if (Double.isNaN(d) || Double.isNaN(direction)) { return Double.NaN; } else if (d == direction) { return direction; } else if (Double.isInfinite(d)) { return (d < 0) ? -Double.MAX_VALUE : Double.MAX_VALUE; } else if (d == 0) { return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; } // special cases MAX_VALUE to infinity and MIN_VALUE to 0 // are handled just as normal numbers final long bits = Double.doubleToLongBits(d); final long sign = bits & 0x8000000000000000L; if ((direction < d) ^ (sign == 0L)) { return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1)); } else { return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) - 1)); } } /** * Get the next machine representable number after a number, moving * in the direction of another number. *

                          * The ordering is as follows (increasing): *

                            *
                          • -INFINITY
                          • *
                          • -MAX_VALUE
                          • *
                          • -MIN_VALUE
                          • *
                          • -0.0
                          • *
                          • +0.0
                          • *
                          • +MIN_VALUE
                          • *
                          • +MAX_VALUE
                          • *
                          • +INFINITY
                          • *
                          • *

                            * If arguments compare equal, then the second argument is returned. *

                            * If {@code direction} is greater than {@code f}, * the smallest machine representable number strictly greater than * {@code f} is returned; if less, then the largest representable number * strictly less than {@code f} is returned.

                            *

                            * If {@code f} is infinite and direction does not * bring it back to finite numbers, it is returned unchanged.

                            * * @param f base number * @param direction (the only important thing is whether * {@code direction} is greater or smaller than {@code f}) * @return the next machine representable number in the specified direction */ public static float nextAfter(final float f, final double direction) { // handling of some important special cases if (Double.isNaN(f) || Double.isNaN(direction)) { return Float.NaN; } else if (f == direction) { return (float) direction; } else if (Float.isInfinite(f)) { return (f < 0f) ? -Float.MAX_VALUE : Float.MAX_VALUE; } else if (f == 0f) { return (direction < 0) ? -Float.MIN_VALUE : Float.MIN_VALUE; } // special cases MAX_VALUE to infinity and MIN_VALUE to 0 // are handled just as normal numbers final int bits = Float.floatToIntBits(f); final int sign = bits & 0x80000000; if ((direction < f) ^ (sign == 0)) { return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) + 1)); } else { return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) - 1)); } } /** Get the largest whole number smaller than x. * @param x number from which floor is requested * @return a double number f such that f is an integer f <= x < f + 1.0 */ public static double floor(double x) { long y; if (x != x) { // NaN return x; } if (x >= TWO_POWER_52 || x <= -TWO_POWER_52) { return x; } y = (long) x; if (x < 0 && y != x) { y--; } if (y == 0) { return x*y; } return y; } /** Get the smallest whole number larger than x. * @param x number from which ceil is requested * @return a double number c such that c is an integer c - 1.0 < x <= c */ public static double ceil(double x) { double y; if (x != x) { // NaN return x; } y = floor(x); if (y == x) { return y; } y += 1.0; if (y == 0) { return x*y; } return y; } /** Get the whole number that is the nearest to x, or the even one if x is exactly half way between two integers. * @param x number from which nearest whole number is requested * @return a double number r such that r is an integer r - 0.5 <= x <= r + 0.5 */ public static double rint(double x) { double y = floor(x); double d = x - y; if (d > 0.5) { if (y == -1.0) { return -0.0; // Preserve sign of operand } return y+1.0; } if (d < 0.5) { return y; } /* half way, round to even */ long z = (long) y; return (z & 1) == 0 ? y : y + 1.0; } /** Get the closest long to x. * @param x number from which closest long is requested * @return closest long to x */ public static long round(double x) { return (long) floor(x + 0.5); } /** Get the closest int to x. * @param x number from which closest int is requested * @return closest int to x */ public static int round(final float x) { return (int) floor(x + 0.5f); } /** Compute the minimum of two values * @param a first value * @param b second value * @return a if a is lesser or equal to b, b otherwise */ public static int min(final int a, final int b) { return (a <= b) ? a : b; } /** Compute the minimum of two values * @param a first value * @param b second value * @return a if a is lesser or equal to b, b otherwise */ public static long min(final long a, final long b) { return (a <= b) ? a : b; } /** Compute the minimum of two values * @param a first value * @param b second value * @return a if a is lesser or equal to b, b otherwise */ public static float min(final float a, final float b) { if (a > b) { return b; } if (a < b) { return a; } /* if either arg is NaN, return NaN */ if (a != b) { return Float.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */ int bits = Float.floatToRawIntBits(a); if (bits == 0x80000000) { return a; } return b; } /** Compute the minimum of two values * @param a first value * @param b second value * @return a if a is lesser or equal to b, b otherwise */ public static double min(final double a, final double b) { if (a > b) { return b; } if (a < b) { return a; } /* if either arg is NaN, return NaN */ if (a != b) { return Double.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */ long bits = Double.doubleToRawLongBits(a); if (bits == 0x8000000000000000L) { return a; } return b; } /** Compute the maximum of two values * @param a first value * @param b second value * @return b if a is lesser or equal to b, a otherwise */ public static int max(final int a, final int b) { return (a <= b) ? b : a; } /** Compute the maximum of two values * @param a first value * @param b second value * @return b if a is lesser or equal to b, a otherwise */ public static long max(final long a, final long b) { return (a <= b) ? b : a; } /** Compute the maximum of two values * @param a first value * @param b second value * @return b if a is lesser or equal to b, a otherwise */ public static float max(final float a, final float b) { if (a > b) { return a; } if (a < b) { return b; } /* if either arg is NaN, return NaN */ if (a != b) { return Float.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */ int bits = Float.floatToRawIntBits(a); if (bits == 0x80000000) { return b; } return a; } /** Compute the maximum of two values * @param a first value * @param b second value * @return b if a is lesser or equal to b, a otherwise */ public static double max(final double a, final double b) { if (a > b) { return a; } if (a < b) { return b; } /* if either arg is NaN, return NaN */ if (a != b) { return Double.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */ long bits = Double.doubleToRawLongBits(a); if (bits == 0x8000000000000000L) { return b; } return a; } /** * Returns the hypotenuse of a triangle with sides {@code x} and {@code y} * - sqrt(x2 +y2)
                            * avoiding intermediate overflow or underflow. * *
                              *
                            • If either argument is infinite, then the result is positive infinity.
                            • *
                            • else, if either argument is NaN then the result is NaN.
                            • *
                            * * @param x a value * @param y a value * @return sqrt(x2 +y2) */ public static double hypot(final double x, final double y) { if (Double.isInfinite(x) || Double.isInfinite(y)) { return Double.POSITIVE_INFINITY; } else if (Double.isNaN(x) || Double.isNaN(y)) { return Double.NaN; } else { final int expX = getExponent(x); final int expY = getExponent(y); if (expX > expY + 27) { // y is neglectible with respect to x return abs(x); } else if (expY > expX + 27) { // x is neglectible with respect to y return abs(y); } else { // find an intermediate scale to avoid both overflow and underflow final int middleExp = (expX + expY) / 2; // scale parameters without losing precision final double scaledX = scalb(x, -middleExp); final double scaledY = scalb(y, -middleExp); // compute scaled hypotenuse final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY); // remove scaling return scalb(scaledH, middleExp); } } } /** * Computes the remainder as prescribed by the IEEE 754 standard. * The remainder value is mathematically equal to {@code x - y*n} * where {@code n} is the mathematical integer closest to the exact mathematical value * of the quotient {@code x/y}. * If two mathematical integers are equally close to {@code x/y} then * {@code n} is the integer that is even. *

                            *

                              *
                            • If either operand is NaN, the result is NaN.
                            • *
                            • If the result is not NaN, the sign of the result equals the sign of the dividend.
                            • *
                            • If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
                            • *
                            • If the dividend is finite and the divisor is an infinity, the result equals the dividend.
                            • *
                            • If the dividend is a zero and the divisor is finite, the result equals the dividend.
                            • *
                            *

                            Note: this implementation currently delegates to {@link StrictMath#IEEEremainder} * @param dividend the number to be divided * @param divisor the number by which to divide * @return the remainder, rounded */ public static double IEEEremainder(double dividend, double divisor) { return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation } /** * Returns the first argument with the sign of the second argument. * A NaN {@code sign} argument is treated as positive. * * @param magnitude the value to return * @param sign the sign for the returned value * @return the magnitude with the same sign as the {@code sign} argument */ public static double copySign(double magnitude, double sign){ long m = Double.doubleToLongBits(magnitude); long s = Double.doubleToLongBits(sign); if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK return magnitude; } return -magnitude; // flip sign } /** * Returns the first argument with the sign of the second argument. * A NaN {@code sign} argument is treated as positive. * * @param magnitude the value to return * @param sign the sign for the returned value * @return the magnitude with the same sign as the {@code sign} argument */ public static float copySign(float magnitude, float sign){ int m = Float.floatToIntBits(magnitude); int s = Float.floatToIntBits(sign); if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK return magnitude; } return -magnitude; // flip sign } /** * Return the exponent of a double number, removing the bias. *

                            * For double numbers of the form 2x, the unbiased * exponent is exactly x. *

                            * @param d number from which exponent is requested * @return exponent for d in IEEE754 representation, without bias */ public static int getExponent(final double d) { return (int) ((Double.doubleToLongBits(d) >>> 52) & 0x7ff) - 1023; } /** * Return the exponent of a float number, removing the bias. *

                            * For float numbers of the form 2x, the unbiased * exponent is exactly x. *

                            * @param f number from which exponent is requested * @return exponent for d in IEEE754 representation, without bias */ public static int getExponent(final float f) { return ((Float.floatToIntBits(f) >>> 23) & 0xff) - 127; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/CompositeFormat.java100644 1750 1750 17653 11532241247 27335 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.text.FieldPosition; import java.text.Format; import java.text.NumberFormat; import java.text.ParsePosition; import java.util.Locale; /** * Base class for formatters of composite objects (complex numbers, vectors ...). * * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ */ public abstract class CompositeFormat extends Format { /** Serializable version identifier. */ private static final long serialVersionUID = 5358685519349262494L; /** * Create a default number format. The default number format is based on * {@link NumberFormat#getInstance()} with the only customizing that the * maximum number of fraction digits is set to 2. * @return the default number format. */ protected static NumberFormat getDefaultNumberFormat() { return getDefaultNumberFormat(Locale.getDefault()); } /** * Create a default number format. The default number format is based on * {@link NumberFormat#getInstance(java.util.Locale)} with the only * customizing that the maximum number of fraction digits is set to 2. * @param locale the specific locale used by the format. * @return the default number format specific to the given locale. */ protected static NumberFormat getDefaultNumberFormat(final Locale locale) { final NumberFormat nf = NumberFormat.getInstance(locale); nf.setMaximumFractionDigits(2); return nf; } /** * Parses source until a non-whitespace character is found. * * @param source the string to parse * @param pos input/ouput parsing parameter. On output, pos * holds the index of the next non-whitespace character. */ protected void parseAndIgnoreWhitespace(final String source, final ParsePosition pos) { parseNextCharacter(source, pos); pos.setIndex(pos.getIndex() - 1); } /** * Parses source until a non-whitespace character is found. * * @param source the string to parse * @param pos input/ouput parsing parameter. * @return the first non-whitespace character. */ protected char parseNextCharacter(final String source, final ParsePosition pos) { int index = pos.getIndex(); final int n = source.length(); char ret = 0; if (index < n) { char c; do { c = source.charAt(index++); } while (Character.isWhitespace(c) && index < n); pos.setIndex(index); if (index < n) { ret = c; } } return ret; } /** * Parses source for special double values. These values * include Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY. * * @param source the string to parse * @param value the special value to parse. * @param pos input/ouput parsing parameter. * @return the special number. */ private Number parseNumber(final String source, final double value, final ParsePosition pos) { Number ret = null; StringBuilder sb = new StringBuilder(); sb.append('('); sb.append(value); sb.append(')'); final int n = sb.length(); final int startIndex = pos.getIndex(); final int endIndex = startIndex + n; if (endIndex < source.length()) { if (source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) { ret = Double.valueOf(value); pos.setIndex(endIndex); } } return ret; } /** * Parses source for a number. This method can parse normal, * numeric values as well as special values. These special values include * Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY. * * @param source the string to parse * @param format the number format used to parse normal, numeric values. * @param pos input/ouput parsing parameter. * @return the parsed number. */ protected Number parseNumber(final String source, final NumberFormat format, final ParsePosition pos) { final int startIndex = pos.getIndex(); Number number = format.parse(source, pos); final int endIndex = pos.getIndex(); // check for error parsing number if (startIndex == endIndex) { // try parsing special numbers final double[] special = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; for (int i = 0; i < special.length; ++i) { number = parseNumber(source, special[i], pos); if (number != null) { break; } } } return number; } /** * Parse source for an expected fixed string. * @param source the string to parse * @param expected expected string * @param pos input/ouput parsing parameter. * @return true if the expected string was there */ protected boolean parseFixedstring(final String source, final String expected, final ParsePosition pos) { final int startIndex = pos.getIndex(); final int endIndex = startIndex + expected.length(); if ((startIndex >= source.length()) || (endIndex > source.length()) || (source.substring(startIndex, endIndex).compareTo(expected) != 0)) { // set index back to start, error index should be the start index pos.setIndex(startIndex); pos.setErrorIndex(startIndex); return false; } // the string was here pos.setIndex(endIndex); return true; } /** * Formats a double value to produce a string. In general, the value is * formatted using the formatting rules of format. There are * three exceptions to this: *
                              *
                            1. NaN is formatted as '(NaN)'
                            2. *
                            3. Positive infinity is formatted as '(Infinity)'
                            4. *
                            5. Negative infinity is formatted as '(-Infinity)'
                            6. *
                            * * @param value the double to format. * @param format the format used. * @param toAppendTo where the text is to be appended * @param pos On input: an alignment field, if desired. On output: the * offsets of the alignment field * @return the value passed in as toAppendTo. */ protected StringBuffer formatDouble(final double value, final NumberFormat format, final StringBuffer toAppendTo, final FieldPosition pos) { if( Double.isNaN(value) || Double.isInfinite(value) ) { toAppendTo.append('('); toAppendTo.append(value); toAppendTo.append(')'); } else { format.format(value, toAppendTo, pos); } return toAppendTo; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/DefaultTransformer.java100644 1750 1750 5423 11532241247 30001 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.Serializable; import org.apache.commons.math.MathException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * A Default NumberTransformer for java.lang.Numbers and Numeric Strings. This * provides some simple conversion capabilities to turn any java.lang.Number * into a primitive double or to turn a String representation of a Number into * a double. * * @version $Revision: 1073658 $ $Date: 2011-02-23 10:45:42 +0100 (mer. 23 févr. 2011) $ */ public class DefaultTransformer implements NumberTransformer, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 4019938025047800455L; /** * @param o the object that gets transformed. * @return a double primitive representation of the Object o. * @throws MathException if it cannot successfully be transformed. * @see Commons Collections Transformer */ public double transform(Object o) throws MathException { if (o == null) { throw new MathException(LocalizedFormats.OBJECT_TRANSFORMATION); } if (o instanceof Number) { return ((Number)o).doubleValue(); } try { return Double.valueOf(o.toString()).doubleValue(); } catch (NumberFormatException e) { throw new MathException(e, LocalizedFormats.CANNOT_TRANSFORM_TO_DOUBLE, e.getMessage()); } } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other == null) { return false; } return other instanceof DefaultTransformer; } /** {@inheritDoc} */ @Override public int hashCode() { // some arbitrary number ... return 401993047; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/ResizableDoubleArray.java100644 1750 1750 107170 11532241247 30306 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.Serializable; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** *

                            * A variable length {@link DoubleArray} implementation that automatically * handles expanding and contracting its internal storage array as elements * are added and removed. *

                            *

                            * The internal storage array starts with capacity determined by the * initialCapacity property, which can be set by the constructor. * The default initial capacity is 16. Adding elements using * {@link #addElement(double)} appends elements to the end of the array. When * there are no open entries at the end of the internal storage array, the * array is expanded. The size of the expanded array depends on the * expansionMode and expansionFactor properties. * The expansionMode determines whether the size of the array is * multiplied by the expansionFactor (MULTIPLICATIVE_MODE) or if * the expansion is additive (ADDITIVE_MODE -- expansionFactor * storage locations added). The default expansionMode is * MULTIPLICATIVE_MODE and the default expansionFactor * is 2.0. *

                            *

                            * The {@link #addElementRolling(double)} method adds a new element to the end * of the internal storage array and adjusts the "usable window" of the * internal array forward by one position (effectively making what was the * second element the first, and so on). Repeated activations of this method * (or activation of {@link #discardFrontElements(int)}) will effectively orphan * the storage locations at the beginning of the internal storage array. To * reclaim this storage, each time one of these methods is activated, the size * of the internal storage array is compared to the number of addressable * elements (the numElements property) and if the difference * is too large, the internal array is contracted to size * numElements + 1. The determination of when the internal * storage array is "too large" depends on the expansionMode and * contractionFactor properties. If the expansionMode * is MULTIPLICATIVE_MODE, contraction is triggered when the * ratio between storage array length and numElements exceeds * contractionFactor. If the expansionMode * is ADDITIVE_MODE, the number of excess storage locations * is compared to contractionFactor. *

                            *

                            * To avoid cycles of expansions and contractions, the * expansionFactor must not exceed the * contractionFactor. Constructors and mutators for both of these * properties enforce this requirement, throwing IllegalArgumentException if it * is violated. *

                            * @version $Revision: 1073474 $ $Date: 2011-02-22 20:52:17 +0100 (mar. 22 févr. 2011) $ */ public class ResizableDoubleArray implements DoubleArray, Serializable { /** additive expansion mode */ public static final int ADDITIVE_MODE = 1; /** multiplicative expansion mode */ public static final int MULTIPLICATIVE_MODE = 0; /** Serializable version identifier */ private static final long serialVersionUID = -3485529955529426875L; /** * The contraction criteria determines when the internal array will be * contracted to fit the number of elements contained in the element * array + 1. */ protected float contractionCriteria = 2.5f; /** * The expansion factor of the array. When the array needs to be expanded, * the new array size will be * internalArray.length * expansionFactor * if expansionMode is set to MULTIPLICATIVE_MODE, or * internalArray.length + expansionFactor if * expansionMode is set to ADDITIVE_MODE. */ protected float expansionFactor = 2.0f; /** * Determines whether array expansion by expansionFactor * is additive or multiplicative. */ protected int expansionMode = MULTIPLICATIVE_MODE; /** * The initial capacity of the array. Initial capacity is not exposed as a * property as it is only meaningful when passed to a constructor. */ protected int initialCapacity = 16; /** * The internal storage array. */ protected double[] internalArray; /** * The number of addressable elements in the array. Note that this * has nothing to do with the length of the internal storage array. */ protected int numElements = 0; /** * The position of the first addressable element in the internal storage * array. The addressable elements in the array are * internalArray[startIndex],...,internalArray[startIndex + numElements -1] * */ protected int startIndex = 0; /** * Create a ResizableArray with default properties. *
                              *
                            • initialCapacity = 16
                            • *
                            • expansionMode = MULTIPLICATIVE_MODE
                            • *
                            • expansionFactor = 2.5
                            • *
                            • contractionFactor = 2.0
                            • *
                            */ public ResizableDoubleArray() { internalArray = new double[initialCapacity]; } /** * Create a ResizableArray with the specified initial capacity. Other * properties take default values: *
                              *
                            • expansionMode = MULTIPLICATIVE_MODE
                            • *
                            • expansionFactor = 2.5
                            • *
                            • contractionFactor = 2.0
                            • *
                            * @param initialCapacity The initial size of the internal storage array * @throws IllegalArgumentException if initialCapacity is not > 0 */ public ResizableDoubleArray(int initialCapacity) { setInitialCapacity(initialCapacity); internalArray = new double[this.initialCapacity]; } /** * Create a ResizableArray from an existing double[] with the * initial capacity and numElements corresponding to the size of * the supplied double[] array. If the supplied array is null, a * new empty array with the default initial capacity will be created. * The input array is copied, not referenced. * Other properties take default values: *
                              *
                            • initialCapacity = 16
                            • *
                            • expansionMode = MULTIPLICATIVE_MODE
                            • *
                            • expansionFactor = 2.5
                            • *
                            • contractionFactor = 2.0
                            • *
                            * * @param initialArray initial array * @since 2.2 */ public ResizableDoubleArray(double[] initialArray) { if (initialArray == null) { this.internalArray = new double[initialCapacity]; } else { this.internalArray = new double[initialArray.length]; System.arraycopy(initialArray, 0, this.internalArray, 0, initialArray.length); initialCapacity = initialArray.length; numElements = initialArray.length; } } /** *

                            * Create a ResizableArray with the specified initial capacity * and expansion factor. The remaining properties take default * values: *

                              *
                            • expansionMode = MULTIPLICATIVE_MODE
                            • *
                            • contractionFactor = 0.5 + expansionFactor
                            • *

                            *

                            * Throws IllegalArgumentException if the following conditions are * not met: *

                              *
                            • initialCapacity > 0
                            • *
                            • expansionFactor > 1
                            • *

                            * * @param initialCapacity The initial size of the internal storage array * @param expansionFactor the array will be expanded based on this * parameter * @throws IllegalArgumentException if parameters are not valid */ public ResizableDoubleArray(int initialCapacity, float expansionFactor) { this.expansionFactor = expansionFactor; setInitialCapacity(initialCapacity); internalArray = new double[initialCapacity]; setContractionCriteria(expansionFactor +0.5f); } /** *

                            * Create a ResizableArray with the specified initialCapacity, * expansionFactor, and contractionCriteria. The expansionMode * will default to MULTIPLICATIVE_MODE.

                            *

                            * Throws IllegalArgumentException if the following conditions are * not met: *

                              *
                            • initialCapacity > 0
                            • *
                            • expansionFactor > 1
                            • *
                            • contractionFactor >= expansionFactor
                            • *

                            * @param initialCapacity The initial size of the internal storage array * @param expansionFactor the array will be expanded based on this * parameter * @param contractionCriteria The contraction Criteria. * @throws IllegalArgumentException if parameters are not valid */ public ResizableDoubleArray(int initialCapacity, float expansionFactor, float contractionCriteria) { this.expansionFactor = expansionFactor; setContractionCriteria(contractionCriteria); setInitialCapacity(initialCapacity); internalArray = new double[initialCapacity]; } /** *

                            * Create a ResizableArray with the specified properties.

                            *

                            * Throws IllegalArgumentException if the following conditions are * not met: *

                              *
                            • initialCapacity > 0
                            • *
                            • expansionFactor > 1
                            • *
                            • contractionFactor >= expansionFactor
                            • *
                            • expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE} *
                            • *

                            * * @param initialCapacity the initial size of the internal storage array * @param expansionFactor the array will be expanded based on this * parameter * @param contractionCriteria the contraction Criteria * @param expansionMode the expansion mode * @throws IllegalArgumentException if parameters are not valid */ public ResizableDoubleArray(int initialCapacity, float expansionFactor, float contractionCriteria, int expansionMode) { this.expansionFactor = expansionFactor; setContractionCriteria(contractionCriteria); setInitialCapacity(initialCapacity); setExpansionMode(expansionMode); internalArray = new double[initialCapacity]; } /** * Copy constructor. Creates a new ResizableDoubleArray that is a deep, * fresh copy of the original. Needs to acquire synchronization lock * on original. Original may not be null; otherwise a NullPointerException * is thrown. * * @param original array to copy * @since 2.0 */ public ResizableDoubleArray(ResizableDoubleArray original) { copy(original, this); } /** * Adds an element to the end of this expandable array. * * @param value to be added to end of array */ public synchronized void addElement(double value) { numElements++; if ((startIndex + numElements) > internalArray.length) { expand(); } internalArray[startIndex + (numElements - 1)] = value; if (shouldContract()) { contract(); } } /** * Adds several element to the end of this expandable array. * * @param values to be added to end of array * @since 2.2 */ public synchronized void addElements(double[] values) { final double[] tempArray = new double[numElements + values.length + 1]; System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); System.arraycopy(values, 0, tempArray, numElements, values.length); internalArray = tempArray; startIndex = 0; numElements += values.length; } /** *

                            * Adds an element to the end of the array and removes the first * element in the array. Returns the discarded first element. * The effect is similar to a push operation in a FIFO queue. *

                            *

                            * Example: If the array contains the elements 1, 2, 3, 4 (in that order) * and addElementRolling(5) is invoked, the result is an array containing * the entries 2, 3, 4, 5 and the value returned is 1. *

                            * * @param value the value to be added to the array * @return the value which has been discarded or "pushed" out of the array * by this rolling insert */ public synchronized double addElementRolling(double value) { double discarded = internalArray[startIndex]; if ((startIndex + (numElements + 1)) > internalArray.length) { expand(); } // Increment the start index startIndex += 1; // Add the new value internalArray[startIndex + (numElements - 1)] = value; // Check the contraction criteria if (shouldContract()) { contract(); } return discarded; } /** * Substitutes value for the most recently added value. * Returns the value that has been replaced. If the array is empty (i.e. * if {@link #numElements} is zero), a MathRuntimeException is thrown. * * @param value new value to substitute for the most recently added value * @return value that has been replaced in the array * @since 2.0 */ public synchronized double substituteMostRecentElement(double value) { if (numElements < 1) { throw MathRuntimeException.createArrayIndexOutOfBoundsException( LocalizedFormats.CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY); } double discarded = internalArray[startIndex + (numElements - 1)]; internalArray[startIndex + (numElements - 1)] = value; return discarded; } /** * Checks the expansion factor and the contraction criteria and throws an * IllegalArgumentException if the contractionCriteria is less than the * expansionCriteria * * @param expansion factor to be checked * @param contraction criteria to be checked * @throws IllegalArgumentException if the contractionCriteria is less than * the expansionCriteria. */ protected void checkContractExpand(float contraction, float expansion) { if (contraction < expansion) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR, contraction, expansion); } if (contraction <= 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_ONE, contraction); } if (expansion <= 1.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.EXPANSION_FACTOR_SMALLER_THAN_ONE, expansion); } } /** * Clear the array, reset the size to the initialCapacity and the number * of elements to zero. */ public synchronized void clear() { numElements = 0; startIndex = 0; internalArray = new double[initialCapacity]; } /** * Contracts the storage array to the (size of the element set) + 1 - to * avoid a zero length array. This function also resets the startIndex to * zero. */ public synchronized void contract() { double[] tempArray = new double[numElements + 1]; // Copy and swap - copy only the element array from the src array. System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); internalArray = tempArray; // Reset the start index to zero startIndex = 0; } /** * Discards the i initial elements of the array. For example, * if the array contains the elements 1,2,3,4, invoking * discardFrontElements(2) will cause the first two elements * to be discarded, leaving 3,4 in the array. Throws illegalArgumentException * if i exceeds numElements. * * @param i the number of elements to discard from the front of the array * @throws IllegalArgumentException if i is greater than numElements. * @since 2.0 */ public synchronized void discardFrontElements(int i) { discardExtremeElements(i,true); } /** * Discards the i last elements of the array. For example, * if the array contains the elements 1,2,3,4, invoking * discardMostRecentElements(2) will cause the last two elements * to be discarded, leaving 1,2 in the array. Throws illegalArgumentException * if i exceeds numElements. * * @param i the number of elements to discard from the end of the array * @throws IllegalArgumentException if i is greater than numElements. * @since 2.0 */ public synchronized void discardMostRecentElements(int i) { discardExtremeElements(i,false); } /** * Discards the i first or last elements of the array, * depending on the value of front. * For example, if the array contains the elements 1,2,3,4, invoking * discardExtremeElements(2,false) will cause the last two elements * to be discarded, leaving 1,2 in the array. * For example, if the array contains the elements 1,2,3,4, invoking * discardExtremeElements(2,true) will cause the first two elements * to be discarded, leaving 3,4 in the array. * Throws illegalArgumentException * if i exceeds numElements. * * @param i the number of elements to discard from the front/end of the array * @param front true if elements are to be discarded from the front * of the array, false if elements are to be discarded from the end * of the array * @throws IllegalArgumentException if i is greater than numElements. * @since 2.0 */ private synchronized void discardExtremeElements(int i,boolean front) { if (i > numElements) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY, i, numElements); } else if (i < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS, i); } else { // "Subtract" this number of discarded from numElements numElements -= i; if (front) startIndex += i; } if (shouldContract()) { contract(); } } /** * Expands the internal storage array using the expansion factor. *

                            * if expansionMode is set to MULTIPLICATIVE_MODE, * the new array size will be internalArray.length * expansionFactor. * If expansionMode is set to ADDITIVE_MODE, the length * after expansion will be internalArray.length + expansionFactor *

                            */ protected synchronized void expand() { // notice the use of FastMath.ceil(), this guarantees that we will always // have an array of at least currentSize + 1. Assume that the // current initial capacity is 1 and the expansion factor // is 1.000000000000000001. The newly calculated size will be // rounded up to 2 after the multiplication is performed. int newSize = 0; if (expansionMode == MULTIPLICATIVE_MODE) { newSize = (int) FastMath.ceil(internalArray.length * expansionFactor); } else { newSize = internalArray.length + FastMath.round(expansionFactor); } double[] tempArray = new double[newSize]; // Copy and swap System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); internalArray = tempArray; } /** * Expands the internal storage array to the specified size. * * @param size Size of the new internal storage array */ private synchronized void expandTo(int size) { double[] tempArray = new double[size]; // Copy and swap System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); internalArray = tempArray; } /** * The contraction criteria defines when the internal array will contract * to store only the number of elements in the element array. * If the expansionMode is MULTIPLICATIVE_MODE, * contraction is triggered when the ratio between storage array length * and numElements exceeds contractionFactor. * If the expansionMode is ADDITIVE_MODE, the * number of excess storage locations is compared to * contractionFactor. * * @return the contraction criteria used to reclaim memory. */ public float getContractionCriteria() { return contractionCriteria; } /** * Returns the element at the specified index * * @param index index to fetch a value from * @return value stored at the specified index * @throws ArrayIndexOutOfBoundsException if index is less than * zero or is greater than getNumElements() - 1. */ public synchronized double getElement(int index) { if (index >= numElements) { throw MathRuntimeException.createArrayIndexOutOfBoundsException( LocalizedFormats.INDEX_LARGER_THAN_MAX, index, numElements - 1); } else if (index >= 0) { return internalArray[startIndex + index]; } else { throw MathRuntimeException.createArrayIndexOutOfBoundsException( LocalizedFormats.CANNOT_RETRIEVE_AT_NEGATIVE_INDEX, index); } } /** * Returns a double array containing the elements of this * ResizableArray. This method returns a copy, not a * reference to the underlying array, so that changes made to the returned * array have no effect on this ResizableArray. * @return the double array. */ public synchronized double[] getElements() { double[] elementArray = new double[numElements]; System.arraycopy( internalArray, startIndex, elementArray, 0, numElements); return elementArray; } /** * The expansion factor controls the size of a new array when an array * needs to be expanded. The expansionMode * determines whether the size of the array is multiplied by the * expansionFactor (MULTIPLICATIVE_MODE) or if * the expansion is additive (ADDITIVE_MODE -- expansionFactor * storage locations added). The default expansionMode is * MULTIPLICATIVE_MODE and the default expansionFactor * is 2.0. * * @return the expansion factor of this expandable double array */ public float getExpansionFactor() { return expansionFactor; } /** * The expansionMode determines whether the internal storage * array grows additively (ADDITIVE_MODE) or multiplicatively * (MULTIPLICATIVE_MODE) when it is expanded. * * @return Returns the expansionMode. */ public int getExpansionMode() { return expansionMode; } /** * Notice the package scope on this method. This method is simply here * for the JUnit test, it allows us check if the expansion is working * properly after a number of expansions. This is not meant to be a part * of the public interface of this class. * * @return the length of the internal storage array. */ synchronized int getInternalLength() { return internalArray.length; } /** * Returns the number of elements currently in the array. Please note * that this is different from the length of the internal storage array. * * @return number of elements */ public synchronized int getNumElements() { return numElements; } /** * Returns the internal storage array. Note that this method returns * a reference to the internal storage array, not a copy, and to correctly * address elements of the array, the startIndex is * required (available via the {@link #start} method). This method should * only be used in cases where copying the internal array is not practical. * The {@link #getElements} method should be used in all other cases. * * * @return the internal storage array used by this object * @deprecated replaced by {@link #getInternalValues()} as of 2.0 */ @Deprecated public synchronized double[] getValues() { return internalArray; } /** * Returns the internal storage array. Note that this method returns * a reference to the internal storage array, not a copy, and to correctly * address elements of the array, the startIndex is * required (available via the {@link #start} method). This method should * only be used in cases where copying the internal array is not practical. * The {@link #getElements} method should be used in all other cases. * * * @return the internal storage array used by this object * @since 2.0 */ public synchronized double[] getInternalValues() { return internalArray; } /** * Sets the contraction criteria for this ExpandContractDoubleArray. * * @param contractionCriteria contraction criteria */ public void setContractionCriteria(float contractionCriteria) { checkContractExpand(contractionCriteria, getExpansionFactor()); synchronized(this) { this.contractionCriteria = contractionCriteria; } } /** * Sets the element at the specified index. If the specified index is greater than * getNumElements() - 1, the numElements property * is increased to index +1 and additional storage is allocated * (if necessary) for the new element and all (uninitialized) elements * between the new element and the previous end of the array). * * @param index index to store a value in * @param value value to store at the specified index * @throws ArrayIndexOutOfBoundsException if index is less than * zero. */ public synchronized void setElement(int index, double value) { if (index < 0) { throw MathRuntimeException.createArrayIndexOutOfBoundsException( LocalizedFormats.CANNOT_SET_AT_NEGATIVE_INDEX, index); } if (index + 1 > numElements) { numElements = index + 1; } if ((startIndex + index) >= internalArray.length) { expandTo(startIndex + (index + 1)); } internalArray[startIndex + index] = value; } /** * Sets the expansionFactor. Throws IllegalArgumentException if the * the following conditions are not met: *
                              *
                            • expansionFactor > 1
                            • *
                            • contractionFactor >= expansionFactor
                            • *
                            * @param expansionFactor the new expansion factor value. * @throws IllegalArgumentException if expansionFactor is <= 1 or greater * than contractionFactor */ public void setExpansionFactor(float expansionFactor) { checkContractExpand(getContractionCriteria(), expansionFactor); // The check above verifies that the expansion factor is > 1.0; synchronized(this) { this.expansionFactor = expansionFactor; } } /** * Sets the expansionMode. The specified value must be one of * ADDITIVE_MODE, MULTIPLICATIVE_MODE. * * @param expansionMode The expansionMode to set. * @throws IllegalArgumentException if the specified mode value is not valid */ public void setExpansionMode(int expansionMode) { if (expansionMode != MULTIPLICATIVE_MODE && expansionMode != ADDITIVE_MODE) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.UNSUPPORTED_EXPANSION_MODE, expansionMode, MULTIPLICATIVE_MODE, "MULTIPLICATIVE_MODE", ADDITIVE_MODE, "ADDITIVE_MODE"); } synchronized(this) { this.expansionMode = expansionMode; } } /** * Sets the initial capacity. Should only be invoked by constructors. * * @param initialCapacity of the array * @throws IllegalArgumentException if initialCapacity is not * positive. */ protected void setInitialCapacity(int initialCapacity) { if (initialCapacity > 0) { synchronized(this) { this.initialCapacity = initialCapacity; } } else { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INITIAL_CAPACITY_NOT_POSITIVE, initialCapacity); } } /** * This function allows you to control the number of elements contained * in this array, and can be used to "throw out" the last n values in an * array. This function will also expand the internal array as needed. * * @param i a new number of elements * @throws IllegalArgumentException if i is negative. */ public synchronized void setNumElements(int i) { // If index is negative thrown an error if (i < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INDEX_NOT_POSITIVE, i); } // Test the new num elements, check to see if the array needs to be // expanded to accommodate this new number of elements if ((startIndex + i) > internalArray.length) { expandTo(startIndex + i); } // Set the new number of elements to new value numElements = i; } /** * Returns true if the internal storage array has too many unused * storage positions. * * @return true if array satisfies the contraction criteria */ private synchronized boolean shouldContract() { if (expansionMode == MULTIPLICATIVE_MODE) { return (internalArray.length / ((float) numElements)) > contractionCriteria; } else { return (internalArray.length - numElements) > contractionCriteria; } } /** * Returns the starting index of the internal array. The starting index is * the position of the first addressable element in the internal storage * array. The addressable elements in the array are * internalArray[startIndex],...,internalArray[startIndex + numElements -1] * * * @return starting index */ public synchronized int start() { return startIndex; } /** *

                            Copies source to dest, copying the underlying data, so dest is * a new, independent copy of source. Does not contract before * the copy.

                            * *

                            Obtains synchronization locks on both source and dest * (in that order) before performing the copy.

                            * *

                            Neither source nor dest may be null; otherwise a NullPointerException * is thrown

                            * * @param source ResizableDoubleArray to copy * @param dest ResizableArray to replace with a copy of the source array * @since 2.0 * */ public static void copy(ResizableDoubleArray source, ResizableDoubleArray dest) { synchronized(source) { synchronized(dest) { dest.initialCapacity = source.initialCapacity; dest.contractionCriteria = source.contractionCriteria; dest.expansionFactor = source.expansionFactor; dest.expansionMode = source.expansionMode; dest.internalArray = new double[source.internalArray.length]; System.arraycopy(source.internalArray, 0, dest.internalArray, 0, dest.internalArray.length); dest.numElements = source.numElements; dest.startIndex = source.startIndex; } } } /** * Returns a copy of the ResizableDoubleArray. Does not contract before * the copy, so the returned object is an exact copy of this. * * @return a new ResizableDoubleArray with the same data and configuration * properties as this * @since 2.0 */ public synchronized ResizableDoubleArray copy() { ResizableDoubleArray result = new ResizableDoubleArray(); copy(this, result); return result; } /** * Returns true iff object is a ResizableDoubleArray with the same properties * as this and an identical internal storage array. * * @param object object to be compared for equality with this * @return true iff object is a ResizableDoubleArray with the same data and * properties as this * @since 2.0 */ @Override public boolean equals(Object object) { if (object == this ) { return true; } if (object instanceof ResizableDoubleArray == false) { return false; } synchronized(this) { synchronized(object) { boolean result = true; ResizableDoubleArray other = (ResizableDoubleArray) object; result = result && (other.initialCapacity == initialCapacity); result = result && (other.contractionCriteria == contractionCriteria); result = result && (other.expansionFactor == expansionFactor); result = result && (other.expansionMode == expansionMode); result = result && (other.numElements == numElements); result = result && (other.startIndex == startIndex); if (!result) { return false; } else { return Arrays.equals(internalArray, other.internalArray); } } } } /** * Returns a hash code consistent with equals. * * @return hash code representing this ResizableDoubleArray * @since 2.0 */ @Override public synchronized int hashCode() { int[] hashData = new int[7]; hashData[0] = new Float(expansionFactor).hashCode(); hashData[1] = new Float(contractionCriteria).hashCode(); hashData[2] = expansionMode; hashData[3] = Arrays.hashCode(internalArray); hashData[4] = initialCapacity; hashData[5] = numElements; hashData[6] = startIndex; return Arrays.hashCode(hashData); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/package.html100644 1750 1750 1757 11532241247 25616 0ustarlucluc 0 0 Convenience routines and common data structures used throughout the commons-math library. commons-math-2.2-src/src/main/java/org/apache/commons/math/util/MultidimensionalCounter.java100644 1750 1750 22374 11532241247 31073 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.exception.NotStrictlyPositiveException; /** * Converter between unidimensional storage structure and multidimensional * conceptual structure. * This utility will convert from indices in a multidimensional structure * to the corresponding index in a one-dimensional array. For example, * assuming that the ranges (in 3 dimensions) of indices are 2, 4 and 3, * the following correspondences, between 3-tuples indices and unidimensional * indices, will hold: *
                              *
                            • (0, 0, 0) corresponds to 0
                            • *
                            • (0, 0, 1) corresponds to 1
                            • *
                            • (0, 0, 2) corresponds to 2
                            • *
                            • (0, 1, 0) corresponds to 3
                            • *
                            • ...
                            • *
                            • (1, 0, 0) corresponds to 12
                            • *
                            • ...
                            • *
                            • (1, 3, 2) corresponds to 23
                            • *
                            * @version $Revision$ $Date$ * @since 2.2 */ public class MultidimensionalCounter implements Iterable { /** * Number of dimensions. */ private final int dimension; /** * Offset for each dimension. */ private final int[] uniCounterOffset; /** * Counter sizes. */ private final int[] size; /** * Total number of (one-dimensional) slots. */ private final int totalSize; /** * Index of last dimension. */ private final int last; /** * Perform iteration over the multidimensional counter. */ public class Iterator implements java.util.Iterator { /** * Multidimensional counter. */ private final int[] counter = new int[dimension]; /** * Unidimensional counter. */ private int count = -1; /** * Create an iterator * @see #iterator() */ Iterator() { counter[last] = -1; } /** * {@inheritDoc} */ public boolean hasNext() { for (int i = 0; i < dimension; i++) { if (counter[i] != size[i] - 1) { return true; } } return false; } /** * @return the unidimensional count after the counter has been * incremented by {@code 1}. */ public Integer next() { for (int i = last; i >= 0; i--) { if (counter[i] == size[i] - 1) { counter[i] = 0; } else { ++counter[i]; break; } } return ++count; } /** * Get the current unidimensional counter slot. * * @return the index within the unidimensionl counter. */ public int getCount() { return count; } /** * Get the current multidimensional counter slots. * * @return the indices within the multidimensional counter. */ public int[] getCounts() { return /* Arrays.*/ copyOf(counter, dimension); // Java 1.5 does not support Arrays.copyOf() } /** * Get the current count in the selected dimension. * * @param dim Dimension index. * @return the count at the corresponding index for the current state * of the iterator. * @throws IndexOutOfBoundsException if {@code index} is not in the * correct interval (as defined by the length of the argument in the * {@link MultidimensionalCounter#MultidimensionalCounter(int[]) * constructor of the enclosing class}). */ public int getCount(int dim) { return counter[dim]; } /** * @throws UnsupportedOperationException */ public void remove() { throw new UnsupportedOperationException(); } } /** * Create a counter. * * @param size Counter sizes (number of slots in each dimension). * @throws NotStrictlyPositiveException if one of the sizes is * negative or zero. */ public MultidimensionalCounter(int ... size) { dimension = size.length; this.size = /* Arrays.*/ copyOf(size, dimension); // Java 1.5 does not support Arrays.copyOf() uniCounterOffset = new int[dimension]; last = dimension - 1; int tS = size[last]; for (int i = 0; i < last; i++) { int count = 1; for (int j = i + 1; j < dimension; j++) { count *= size[j]; } uniCounterOffset[i] = count; tS *= size[i]; } uniCounterOffset[last] = 0; if (tS <= 0) { throw new NotStrictlyPositiveException(tS); } totalSize = tS; } /** * Create an iterator over this counter. * * @return the iterator. */ public Iterator iterator() { return new Iterator(); } /** * Get the number of dimensions of the multidimensional counter. * * @return the number of dimensions. */ public int getDimension() { return dimension; } /** * Convert to multidimensional counter. * * @param index Index in unidimensional counter. * @return the multidimensional counts. * @throws OutOfRangeException if {@code index} is not between * {@code 0} and the value returned by {@link #getSize()} (excluded). */ public int[] getCounts(int index) { if (index < 0 || index >= totalSize) { throw new OutOfRangeException(index, 0, totalSize); } final int[] indices = new int[dimension]; int count = 0; for (int i = 0; i < last; i++) { int idx = 0; final int offset = uniCounterOffset[i]; while (count <= index) { count += offset; ++idx; } --idx; count -= offset; indices[i] = idx; } int idx = 1; while (count < index) { count += idx; ++idx; } --idx; indices[last] = idx; return indices; } /** * Convert to unidimensional counter. * * @param c Indices in multidimensional counter. * @return the index within the unidimensionl counter. * @throws DimensionMismatchException if the size of {@code c} * does not match the size of the array given in the constructor. * @throws OutOfRangeException if a value of {@code c} is not in * the range of the corresponding dimension, as defined in the * {@link MultidimensionalCounter#MultidimensionalCounter(int...) constructor}. */ public int getCount(int ... c) throws OutOfRangeException { if (c.length != dimension) { throw new DimensionMismatchException(c.length, dimension); } int count = 0; for (int i = 0; i < dimension; i++) { final int index = c[i]; if (index < 0 || index >= size[i]) { throw new OutOfRangeException(index, 0, size[i] - 1); } count += uniCounterOffset[i] * c[i]; } return count + c[last]; } /** * Get the total number of elements. * * @return the total size of the unidimensional counter. */ public int getSize() { return totalSize; } /** * Get the number of multidimensional counter slots in each dimension. * * @return the sizes of the multidimensional counter in each dimension. */ public int[] getSizes() { return /* Arrays.*/ copyOf(size, dimension); // Java 1.5 does not support Arrays.copyOf() } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder sb = new StringBuilder(); for (int i = 0; i < dimension; i++) { sb.append("[").append(getCount(i)).append("]"); } return sb.toString(); } /** * Java 1.5 does not support Arrays.copyOf() * * @param source the array to be copied * @param newLen the length of the copy to be returned * @return the copied array, truncated or padded as necessary. */ private int[] copyOf(int[] source, int newLen) { int[] output = new int[newLen]; System.arraycopy(source, 0, output, 0, Math.min(source.length, newLen)); return output; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/TransformerMap.java100644 1750 1750 13431 11532241247 27150 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.math.MathException; /** * This TansformerMap automates the transformation of mixed object types. * It provides a means to set NumberTransformers that will be selected * based on the Class of the object handed to the Maps * double transform(Object o) method. * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $ */ public class TransformerMap implements NumberTransformer, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 4605318041528645258L; /** * A default Number Transformer for Numbers and numeric Strings. */ private NumberTransformer defaultTransformer = null; /** * The internal Map. */ private Map, NumberTransformer> map = null; /** * Build a map containing only the default transformer. */ public TransformerMap() { map = new HashMap, NumberTransformer>(); defaultTransformer = new DefaultTransformer(); } /** * Tests if a Class is present in the TransformerMap. * @param key Class to check * @return true|false */ public boolean containsClass(Class key) { return map.containsKey(key); } /** * Tests if a NumberTransformer is present in the TransformerMap. * @param value NumberTransformer to check * @return true|false */ public boolean containsTransformer(NumberTransformer value) { return map.containsValue(value); } /** * Returns the Transformer that is mapped to a class * if mapping is not present, this returns null. * @param key The Class of the object * @return the mapped NumberTransformer or null. */ public NumberTransformer getTransformer(Class key) { return map.get(key); } /** * Sets a Class to Transformer Mapping in the Map. If * the Class is already present, this overwrites that * mapping. * @param key The Class * @param transformer The NumberTransformer * @return the replaced transformer if one is present */ public NumberTransformer putTransformer(Class key, NumberTransformer transformer) { return map.put(key, transformer); } /** * Removes a Class to Transformer Mapping in the Map. * @param key The Class * @return the removed transformer if one is present or * null if none was present. */ public NumberTransformer removeTransformer(Class key) { return map.remove(key); } /** * Clears all the Class to Transformer mappings. */ public void clear() { map.clear(); } /** * Returns the Set of Classes used as keys in the map. * @return Set of Classes */ public Set> classes() { return map.keySet(); } /** * Returns the Set of NumberTransformers used as values * in the map. * @return Set of NumberTransformers */ public Collection transformers() { return map.values(); } /** * Attempts to transform the Object against the map of * NumberTransformers. Otherwise it returns Double.NaN. * * @param o the Object to be transformed. * @return the double value of the Object. * @throws MathException if the Object can not be transformed into a Double. * @see org.apache.commons.math.util.NumberTransformer#transform(java.lang.Object) */ public double transform(Object o) throws MathException { double value = Double.NaN; if (o instanceof Number || o instanceof String) { value = defaultTransformer.transform(o); } else { NumberTransformer trans = getTransformer(o.getClass()); if (trans != null) { value = trans.transform(o); } } return value; } /** {@inheritDoc} */ @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof TransformerMap) { TransformerMap rhs = (TransformerMap) other; if (! defaultTransformer.equals(rhs.defaultTransformer)) { return false; } if (map.size() != rhs.map.size()) { return false; } for (Map.Entry, NumberTransformer> entry : map.entrySet()) { if (! entry.getValue().equals(rhs.map.get(entry.getKey()))) { return false; } } return true; } return false; } /** {@inheritDoc} */ @Override public int hashCode() { int hash = defaultTransformer.hashCode(); for (NumberTransformer t : map.values()) { hash = hash * 31 + t.hashCode(); } return hash; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/DoubleArray.java100644 1750 1750 7544 11532241247 26411 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; /** * Provides a standard interface for double arrays. Allows different * array implementations to support various storage mechanisms * such as automatic expansion, contraction, and array "rolling". * * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ */ public interface DoubleArray { /** * Returns the number of elements currently in the array. Please note * that this may be different from the length of the internal storage array. * * @return number of elements */ int getNumElements(); /** * Returns the element at the specified index. Note that if an * out of bounds index is supplied a ArrayIndexOutOfBoundsException * will be thrown. * * @param index index to fetch a value from * @return value stored at the specified index * @throws ArrayIndexOutOfBoundsException if index is less than * zero or is greater than getNumElements() - 1. */ double getElement(int index); /** * Sets the element at the specified index. If the specified index is greater than * getNumElements() - 1, the numElements property * is increased to index +1 and additional storage is allocated * (if necessary) for the new element and all (uninitialized) elements * between the new element and the previous end of the array). * * @param index index to store a value in * @param value value to store at the specified index * @throws ArrayIndexOutOfBoundsException if index is less than * zero. */ void setElement(int index, double value); /** * Adds an element to the end of this expandable array * * @param value to be added to end of array */ void addElement(double value); /** *

                            * Adds an element to the end of the array and removes the first * element in the array. Returns the discarded first element. * The effect is similar to a push operation in a FIFO queue. *

                            *

                            * Example: If the array contains the elements 1, 2, 3, 4 (in that order) * and addElementRolling(5) is invoked, the result is an array containing * the entries 2, 3, 4, 5 and the value returned is 1. *

                            * * @param value the value to be added to the array * @return the value which has been discarded or "pushed" out of the array * by this rolling insert */ double addElementRolling(double value); /** * Returns a double[] array containing the elements of this * DoubleArray. If the underlying implementation is * array-based, this method should always return a copy, rather than a * reference to the underlying array so that changes made to the returned * array have no effect on the DoubleArray. * * @return all elements added to the array */ double[] getElements(); /** * Clear the double array */ void clear(); } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/MathUtils.java100644 1750 1750 234336 11532241247 26153 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.NonMonotonousSequenceException; /** * Some useful additions to the built-in functions in {@link Math}. * @version $Revision: 1073472 $ $Date: 2011-02-22 20:49:07 +0100 (mar. 22 févr. 2011) $ */ public final class MathUtils { /** Smallest positive number such that 1 - EPSILON is not numerically equal to 1. */ public static final double EPSILON = 0x1.0p-53; /** Safe minimum, such that 1 / SAFE_MIN does not overflow. *

                            In IEEE 754 arithmetic, this is also the smallest normalized * number 2-1022.

                            */ public static final double SAFE_MIN = 0x1.0p-1022; /** * 2 π. * @since 2.1 */ public static final double TWO_PI = 2 * FastMath.PI; /** -1.0 cast as a byte. */ private static final byte NB = (byte)-1; /** -1.0 cast as a short. */ private static final short NS = (short)-1; /** 1.0 cast as a byte. */ private static final byte PB = (byte)1; /** 1.0 cast as a short. */ private static final short PS = (short)1; /** 0.0 cast as a byte. */ private static final byte ZB = (byte)0; /** 0.0 cast as a short. */ private static final short ZS = (short)0; /** Gap between NaN and regular numbers. */ private static final int NAN_GAP = 4 * 1024 * 1024; /** Offset to order signed double numbers lexicographically. */ private static final long SGN_MASK = 0x8000000000000000L; /** Offset to order signed double numbers lexicographically. */ private static final int SGN_MASK_FLOAT = 0x80000000; /** All long-representable factorials */ private static final long[] FACTORIALS = new long[] { 1l, 1l, 2l, 6l, 24l, 120l, 720l, 5040l, 40320l, 362880l, 3628800l, 39916800l, 479001600l, 6227020800l, 87178291200l, 1307674368000l, 20922789888000l, 355687428096000l, 6402373705728000l, 121645100408832000l, 2432902008176640000l }; /** * Private Constructor */ private MathUtils() { super(); } /** * Add two integers, checking for overflow. * * @param x an addend * @param y an addend * @return the sum x+y * @throws ArithmeticException if the result can not be represented as an * int * @since 1.1 */ public static int addAndCheck(int x, int y) { long s = (long)x + (long)y; if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y); } return (int)s; } /** * Add two long integers, checking for overflow. * * @param a an addend * @param b an addend * @return the sum a+b * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ public static long addAndCheck(long a, long b) { return addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION); } /** * Add two long integers, checking for overflow. * * @param a an addend * @param b an addend * @param pattern the pattern to use for any thrown exception. * @return the sum a+b * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ private static long addAndCheck(long a, long b, Localizable pattern) { long ret; if (a > b) { // use symmetry to reduce boundary cases ret = addAndCheck(b, a, pattern); } else { // assert a <= b if (a < 0) { if (b < 0) { // check for negative overflow if (Long.MIN_VALUE - b <= a) { ret = a + b; } else { throw MathRuntimeException.createArithmeticException(pattern, a, b); } } else { // opposite sign addition is always safe ret = a + b; } } else { // assert a >= 0 // assert b >= 0 // check for positive overflow if (a <= Long.MAX_VALUE - b) { ret = a + b; } else { throw MathRuntimeException.createArithmeticException(pattern, a, b); } } } return ret; } /** * Returns an exact representation of the Binomial * Coefficient, "n choose k", the number of * k-element subsets that can be selected from an * n-element set. *

                            * Preconditions: *

                              *
                            • 0 <= k <= n (otherwise * IllegalArgumentException is thrown)
                            • *
                            • The result is small enough to fit into a long. The * largest value of n for which all coefficients are * < Long.MAX_VALUE is 66. If the computed value exceeds * Long.MAX_VALUE an ArithMeticException is * thrown.
                            • *

                            * * @param n the size of the set * @param k the size of the subsets to be counted * @return n choose k * @throws IllegalArgumentException if preconditions are not met. * @throws ArithmeticException if the result is too large to be represented * by a long integer. */ public static long binomialCoefficient(final int n, final int k) { checkBinomial(n, k); if ((n == k) || (k == 0)) { return 1; } if ((k == 1) || (k == n - 1)) { return n; } // Use symmetry for large k if (k > n / 2) return binomialCoefficient(n, n - k); // We use the formula // (n choose k) = n! / (n-k)! / k! // (n choose k) == ((n-k+1)*...*n) / (1*...*k) // which could be written // (n choose k) == (n-1 choose k-1) * n / k long result = 1; if (n <= 61) { // For n <= 61, the naive implementation cannot overflow. int i = n - k + 1; for (int j = 1; j <= k; j++) { result = result * i / j; i++; } } else if (n <= 66) { // For n > 61 but n <= 66, the result cannot overflow, // but we must take care not to overflow intermediate values. int i = n - k + 1; for (int j = 1; j <= k; j++) { // We know that (result * i) is divisible by j, // but (result * i) may overflow, so we split j: // Filter out the gcd, d, so j/d and i/d are integer. // result is divisible by (j/d) because (j/d) // is relative prime to (i/d) and is a divisor of // result * (i/d). final long d = gcd(i, j); result = (result / (j / d)) * (i / d); i++; } } else { // For n > 66, a result overflow might occur, so we check // the multiplication, taking care to not overflow // unnecessary. int i = n - k + 1; for (int j = 1; j <= k; j++) { final long d = gcd(i, j); result = mulAndCheck(result / (j / d), i / d); i++; } } return result; } /** * Returns a double representation of the Binomial * Coefficient, "n choose k", the number of * k-element subsets that can be selected from an * n-element set. *

                            * Preconditions: *

                              *
                            • 0 <= k <= n (otherwise * IllegalArgumentException is thrown)
                            • *
                            • The result is small enough to fit into a double. The * largest value of n for which all coefficients are < * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE, * Double.POSITIVE_INFINITY is returned
                            • *

                            * * @param n the size of the set * @param k the size of the subsets to be counted * @return n choose k * @throws IllegalArgumentException if preconditions are not met. */ public static double binomialCoefficientDouble(final int n, final int k) { checkBinomial(n, k); if ((n == k) || (k == 0)) { return 1d; } if ((k == 1) || (k == n - 1)) { return n; } if (k > n/2) { return binomialCoefficientDouble(n, n - k); } if (n < 67) { return binomialCoefficient(n,k); } double result = 1d; for (int i = 1; i <= k; i++) { result *= (double)(n - k + i) / (double)i; } return FastMath.floor(result + 0.5); } /** * Returns the natural log of the Binomial * Coefficient, "n choose k", the number of * k-element subsets that can be selected from an * n-element set. *

                            * Preconditions: *

                              *
                            • 0 <= k <= n (otherwise * IllegalArgumentException is thrown)
                            • *

                            * * @param n the size of the set * @param k the size of the subsets to be counted * @return n choose k * @throws IllegalArgumentException if preconditions are not met. */ public static double binomialCoefficientLog(final int n, final int k) { checkBinomial(n, k); if ((n == k) || (k == 0)) { return 0; } if ((k == 1) || (k == n - 1)) { return FastMath.log(n); } /* * For values small enough to do exact integer computation, * return the log of the exact value */ if (n < 67) { return FastMath.log(binomialCoefficient(n,k)); } /* * Return the log of binomialCoefficientDouble for values that will not * overflow binomialCoefficientDouble */ if (n < 1030) { return FastMath.log(binomialCoefficientDouble(n, k)); } if (k > n / 2) { return binomialCoefficientLog(n, n - k); } /* * Sum logs for values that could overflow */ double logSum = 0; // n!/(n-k)! for (int i = n - k + 1; i <= n; i++) { logSum += FastMath.log(i); } // divide by k! for (int i = 2; i <= k; i++) { logSum -= FastMath.log(i); } return logSum; } /** * Check binomial preconditions. * @param n the size of the set * @param k the size of the subsets to be counted * @exception IllegalArgumentException if preconditions are not met. */ private static void checkBinomial(final int n, final int k) throws IllegalArgumentException { if (n < k) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.BINOMIAL_INVALID_PARAMETERS_ORDER, n, k); } if (n < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.BINOMIAL_NEGATIVE_PARAMETER, n); } } /** * Compares two numbers given some amount of allowed error. * * @param x the first number * @param y the second number * @param eps the amount of error to allow when checking for equality * @return
                            • 0 if {@link #equals(double, double, double) equals(x, y, eps)}
                            • *
                            • < 0 if !{@link #equals(double, double, double) equals(x, y, eps)} && x < y
                            • *
                            • > 0 if !{@link #equals(double, double, double) equals(x, y, eps)} && x > y
                            */ public static int compareTo(double x, double y, double eps) { if (equals(x, y, eps)) { return 0; } else if (x < y) { return -1; } return 1; } /** * Returns the * hyperbolic cosine of x. * * @param x double value for which to find the hyperbolic cosine * @return hyperbolic cosine of x */ public static double cosh(double x) { return (FastMath.exp(x) + FastMath.exp(-x)) / 2.0; } /** * Returns true iff they are strictly equal. * * @param x first value * @param y second value * @return {@code true} if the values are equal. * @deprecated as of 2.2 his method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases wher the old semantics is * useful (see e.g. {@link #equalsIncludingNaN(float,float) * equalsIncludingNaN}. */ @Deprecated public static boolean equals(float x, float y) { return (Float.isNaN(x) && Float.isNaN(y)) || x == y; } /** * Returns true if both arguments are NaN or neither is NaN and they are * equal as defined by {@link #equals(float,float,int) equals(x, y, 1)}. * * @param x first value * @param y second value * @return {@code true} if the values are equal or both are NaN. * @since 2.2 */ public static boolean equalsIncludingNaN(float x, float y) { return (Float.isNaN(x) && Float.isNaN(y)) || equals(x, y, 1); } /** * Returns true if both arguments are equal or within the range of allowed * error (inclusive). * * @param x first value * @param y second value * @param eps the amount of absolute error to allow. * @return {@code true} if the values are equal or within range of each other. * @since 2.2 */ public static boolean equals(float x, float y, float eps) { return equals(x, y, 1) || FastMath.abs(y - x) <= eps; } /** * Returns true if both arguments are NaN or are equal or within the range * of allowed error (inclusive). * * @param x first value * @param y second value * @param eps the amount of absolute error to allow. * @return {@code true} if the values are equal or within range of each other, * or both are NaN. * @since 2.2 */ public static boolean equalsIncludingNaN(float x, float y, float eps) { return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps); } /** * Returns true if both arguments are equal or within the range of allowed * error (inclusive). * Two float numbers are considered equal if there are {@code (maxUlps - 1)} * (or fewer) floating point numbers between them, i.e. two adjacent floating * point numbers are considered equal. * Adapted from * Bruce Dawson * * @param x first value * @param y second value * @param maxUlps {@code (maxUlps - 1)} is the number of floating point * values between {@code x} and {@code y}. * @return {@code true} if there are fewer than {@code maxUlps} floating * point values between {@code x} and {@code y}. * @since 2.2 */ public static boolean equals(float x, float y, int maxUlps) { // Check that "maxUlps" is non-negative and small enough so that // NaN won't compare as equal to anything (except another NaN). assert maxUlps > 0 && maxUlps < NAN_GAP; int xInt = Float.floatToIntBits(x); int yInt = Float.floatToIntBits(y); // Make lexicographically ordered as a two's-complement integer. if (xInt < 0) { xInt = SGN_MASK_FLOAT - xInt; } if (yInt < 0) { yInt = SGN_MASK_FLOAT - yInt; } final boolean isEqual = FastMath.abs(xInt - yInt) <= maxUlps; return isEqual && !Float.isNaN(x) && !Float.isNaN(y); } /** * Returns true if both arguments are NaN or if they are equal as defined * by {@link #equals(float,float,int) equals(x, y, maxUlps)}. * * @param x first value * @param y second value * @param maxUlps {@code (maxUlps - 1)} is the number of floating point * values between {@code x} and {@code y}. * @return {@code true} if both arguments are NaN or if there are less than * {@code maxUlps} floating point values between {@code x} and {@code y}. * @since 2.2 */ public static boolean equalsIncludingNaN(float x, float y, int maxUlps) { return (Float.isNaN(x) && Float.isNaN(y)) || equals(x, y, maxUlps); } /** * Returns true iff both arguments are null or have same dimensions and all * their elements are equal as defined by * {@link #equals(float,float)}. * * @param x first array * @param y second array * @return true if the values are both null or have same dimension * and equal elements. * @deprecated as of 2.2 this method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases where the old semantics is * useful (see e.g. {@link #equalsIncludingNaN(float[],float[]) * equalsIncludingNaN}. */ @Deprecated public static boolean equals(float[] x, float[] y) { if ((x == null) || (y == null)) { return !((x == null) ^ (y == null)); } if (x.length != y.length) { return false; } for (int i = 0; i < x.length; ++i) { if (!equals(x[i], y[i])) { return false; } } return true; } /** * Returns true iff both arguments are null or have same dimensions and all * their elements are equal as defined by * {@link #equalsIncludingNaN(float,float)}. * * @param x first array * @param y second array * @return true if the values are both null or have same dimension and * equal elements * @since 2.2 */ public static boolean equalsIncludingNaN(float[] x, float[] y) { if ((x == null) || (y == null)) { return !((x == null) ^ (y == null)); } if (x.length != y.length) { return false; } for (int i = 0; i < x.length; ++i) { if (!equalsIncludingNaN(x[i], y[i])) { return false; } } return true; } /** * Returns true iff both arguments are NaN or neither is NaN and they are * equal * *

                            This method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases where the old semantics * (w.r.t. NaN) is useful (see e.g. * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}. *

                            * * @param x first value * @param y second value * @return {@code true} if the values are equal. */ public static boolean equals(double x, double y) { return (Double.isNaN(x) && Double.isNaN(y)) || x == y; } /** * Returns true if both arguments are NaN or neither is NaN and they are * equal as defined by {@link #equals(double,double,int) equals(x, y, 1)}. * * @param x first value * @param y second value * @return {@code true} if the values are equal or both are NaN. * @since 2.2 */ public static boolean equalsIncludingNaN(double x, double y) { return (Double.isNaN(x) && Double.isNaN(y)) || equals(x, y, 1); } /** * Returns true if both arguments are equal or within the range of allowed * error (inclusive). *

                            * Two NaNs are considered equals, as are two infinities with same sign. *

                            *

                            This method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases where the old semantics * (w.r.t. NaN) is useful (see e.g. * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}. *

                            * @param x first value * @param y second value * @param eps the amount of absolute error to allow. * @return {@code true} if the values are equal or within range of each other. */ public static boolean equals(double x, double y, double eps) { return equals(x, y) || FastMath.abs(y - x) <= eps; } /** * Returns true if both arguments are NaN or are equal or within the range * of allowed error (inclusive). * * @param x first value * @param y second value * @param eps the amount of absolute error to allow. * @return {@code true} if the values are equal or within range of each other, * or both are NaN. * @since 2.2 */ public static boolean equalsIncludingNaN(double x, double y, double eps) { return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps); } /** * Returns true if both arguments are equal or within the range of allowed * error (inclusive). * Two float numbers are considered equal if there are {@code (maxUlps - 1)} * (or fewer) floating point numbers between them, i.e. two adjacent floating * point numbers are considered equal. * Adapted from * Bruce Dawson * *

                            This method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases where the old semantics * (w.r.t. NaN) is useful (see e.g. * {@link #equalsIncludingNaN(double,double, int) equalsIncludingNaN}. *

                            * * @param x first value * @param y second value * @param maxUlps {@code (maxUlps - 1)} is the number of floating point * values between {@code x} and {@code y}. * @return {@code true} if there are fewer than {@code maxUlps} floating * point values between {@code x} and {@code y}. */ public static boolean equals(double x, double y, int maxUlps) { // Check that "maxUlps" is non-negative and small enough so that // NaN won't compare as equal to anything (except another NaN). assert maxUlps > 0 && maxUlps < NAN_GAP; long xInt = Double.doubleToLongBits(x); long yInt = Double.doubleToLongBits(y); // Make lexicographically ordered as a two's-complement integer. if (xInt < 0) { xInt = SGN_MASK - xInt; } if (yInt < 0) { yInt = SGN_MASK - yInt; } return FastMath.abs(xInt - yInt) <= maxUlps; } /** * Returns true if both arguments are NaN or if they are equal as defined * by {@link #equals(double,double,int) equals(x, y, maxUlps}. * * @param x first value * @param y second value * @param maxUlps {@code (maxUlps - 1)} is the number of floating point * values between {@code x} and {@code y}. * @return {@code true} if both arguments are NaN or if there are less than * {@code maxUlps} floating point values between {@code x} and {@code y}. * @since 2.2 */ public static boolean equalsIncludingNaN(double x, double y, int maxUlps) { return (Double.isNaN(x) && Double.isNaN(y)) || equals(x, y, maxUlps); } /** * Returns true iff both arguments are null or have same dimensions and all * their elements are equal as defined by * {@link #equals(double,double)}. * *

                            This method considers that {@code NaN == NaN}. In release * 3.0, the semantics will change in order to comply with IEEE754 where it * is specified that {@code NaN != NaN}. * New methods have been added for those cases wher the old semantics is * useful (see e.g. {@link #equalsIncludingNaN(double[],double[]) * equalsIncludingNaN}. *

                            * @param x first array * @param y second array * @return true if the values are both null or have same dimension * and equal elements. */ public static boolean equals(double[] x, double[] y) { if ((x == null) || (y == null)) { return !((x == null) ^ (y == null)); } if (x.length != y.length) { return false; } for (int i = 0; i < x.length; ++i) { if (!equals(x[i], y[i])) { return false; } } return true; } /** * Returns true iff both arguments are null or have same dimensions and all * their elements are equal as defined by * {@link #equalsIncludingNaN(double,double)}. * * @param x first array * @param y second array * @return true if the values are both null or have same dimension and * equal elements * @since 2.2 */ public static boolean equalsIncludingNaN(double[] x, double[] y) { if ((x == null) || (y == null)) { return !((x == null) ^ (y == null)); } if (x.length != y.length) { return false; } for (int i = 0; i < x.length; ++i) { if (!equalsIncludingNaN(x[i], y[i])) { return false; } } return true; } /** * Returns n!. Shorthand for n Factorial, the * product of the numbers 1,...,n. *

                            * Preconditions: *

                              *
                            • n >= 0 (otherwise * IllegalArgumentException is thrown)
                            • *
                            • The result is small enough to fit into a long. The * largest value of n for which n! < * Long.MAX_VALUE is 20. If the computed value exceeds Long.MAX_VALUE * an ArithMeticException is thrown.
                            • *
                            *

                            * * @param n argument * @return n! * @throws ArithmeticException if the result is too large to be represented * by a long integer. * @throws IllegalArgumentException if n < 0 */ public static long factorial(final int n) { if (n < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER, n); } if (n > 20) { throw new ArithmeticException( "factorial value is too large to fit in a long"); } return FACTORIALS[n]; } /** * Returns n!. Shorthand for n Factorial, the * product of the numbers 1,...,n as a double. *

                            * Preconditions: *

                              *
                            • n >= 0 (otherwise * IllegalArgumentException is thrown)
                            • *
                            • The result is small enough to fit into a double. The * largest value of n for which n! < * Double.MAX_VALUE is 170. If the computed value exceeds * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned
                            • *
                            *

                            * * @param n argument * @return n! * @throws IllegalArgumentException if n < 0 */ public static double factorialDouble(final int n) { if (n < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER, n); } if (n < 21) { return factorial(n); } return FastMath.floor(FastMath.exp(factorialLog(n)) + 0.5); } /** * Returns the natural logarithm of n!. *

                            * Preconditions: *

                              *
                            • n >= 0 (otherwise * IllegalArgumentException is thrown)
                            • *

                            * * @param n argument * @return n! * @throws IllegalArgumentException if preconditions are not met. */ public static double factorialLog(final int n) { if (n < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER, n); } if (n < 21) { return FastMath.log(factorial(n)); } double logSum = 0; for (int i = 2; i <= n; i++) { logSum += FastMath.log(i); } return logSum; } /** *

                            * Gets the greatest common divisor of the absolute value of two numbers, * using the "binary gcd" method which avoids division and modulo * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef * Stein (1961). *

                            * Special cases: *
                              *
                            • The invocations * gcd(Integer.MIN_VALUE, Integer.MIN_VALUE), * gcd(Integer.MIN_VALUE, 0) and * gcd(0, Integer.MIN_VALUE) throw an * ArithmeticException, because the result would be 2^31, which * is too large for an int value.
                            • *
                            • The result of gcd(x, x), gcd(0, x) and * gcd(x, 0) is the absolute value of x, except * for the special cases above. *
                            • The invocation gcd(0, 0) is the only one which returns * 0.
                            • *
                            * * @param p any number * @param q any number * @return the greatest common divisor, never negative * @throws ArithmeticException if the result cannot be represented as a * nonnegative int value * @since 1.1 */ public static int gcd(final int p, final int q) { int u = p; int v = q; if ((u == 0) || (v == 0)) { if ((u == Integer.MIN_VALUE) || (v == Integer.MIN_VALUE)) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.GCD_OVERFLOW_32_BITS, p, q); } return FastMath.abs(u) + FastMath.abs(v); } // keep u and v negative, as negative integers range down to // -2^31, while positive numbers can only be as large as 2^31-1 // (i.e. we can't necessarily negate a negative number without // overflow) /* assert u!=0 && v!=0; */ if (u > 0) { u = -u; } // make u negative if (v > 0) { v = -v; } // make v negative // B1. [Find power of 2] int k = 0; while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are // both even... u /= 2; v /= 2; k++; // cast out twos. } if (k == 31) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.GCD_OVERFLOW_32_BITS, p, q); } // B2. Initialize: u and v have been divided by 2^k and at least // one is odd. int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; // t negative: u was odd, v may be even (t replaces v) // t positive: u was even, v is odd (t replaces u) do { /* assert u<0 && v<0; */ // B4/B3: cast out twos from t. while ((t & 1) == 0) { // while t is even.. t /= 2; // cast out twos } // B5 [reset max(u,v)] if (t > 0) { u = -t; } else { v = t; } // B6/B3. at this point both u and v should be odd. t = (v - u) / 2; // |u| larger: t positive (replace u) // |v| larger: t negative (replace v) } while (t != 0); return -u * (1 << k); // gcd is u*2^k } /** *

                            * Gets the greatest common divisor of the absolute value of two numbers, * using the "binary gcd" method which avoids division and modulo * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef * Stein (1961). *

                            * Special cases: *
                              *
                            • The invocations * gcd(Long.MIN_VALUE, Long.MIN_VALUE), * gcd(Long.MIN_VALUE, 0L) and * gcd(0L, Long.MIN_VALUE) throw an * ArithmeticException, because the result would be 2^63, which * is too large for a long value.
                            • *
                            • The result of gcd(x, x), gcd(0L, x) and * gcd(x, 0L) is the absolute value of x, except * for the special cases above. *
                            • The invocation gcd(0L, 0L) is the only one which returns * 0L.
                            • *
                            * * @param p any number * @param q any number * @return the greatest common divisor, never negative * @throws ArithmeticException if the result cannot be represented as a nonnegative long * value * @since 2.1 */ public static long gcd(final long p, final long q) { long u = p; long v = q; if ((u == 0) || (v == 0)) { if ((u == Long.MIN_VALUE) || (v == Long.MIN_VALUE)){ throw MathRuntimeException.createArithmeticException( LocalizedFormats.GCD_OVERFLOW_64_BITS, p, q); } return FastMath.abs(u) + FastMath.abs(v); } // keep u and v negative, as negative integers range down to // -2^63, while positive numbers can only be as large as 2^63-1 // (i.e. we can't necessarily negate a negative number without // overflow) /* assert u!=0 && v!=0; */ if (u > 0) { u = -u; } // make u negative if (v > 0) { v = -v; } // make v negative // B1. [Find power of 2] int k = 0; while ((u & 1) == 0 && (v & 1) == 0 && k < 63) { // while u and v are // both even... u /= 2; v /= 2; k++; // cast out twos. } if (k == 63) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.GCD_OVERFLOW_64_BITS, p, q); } // B2. Initialize: u and v have been divided by 2^k and at least // one is odd. long t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; // t negative: u was odd, v may be even (t replaces v) // t positive: u was even, v is odd (t replaces u) do { /* assert u<0 && v<0; */ // B4/B3: cast out twos from t. while ((t & 1) == 0) { // while t is even.. t /= 2; // cast out twos } // B5 [reset max(u,v)] if (t > 0) { u = -t; } else { v = t; } // B6/B3. at this point both u and v should be odd. t = (v - u) / 2; // |u| larger: t positive (replace u) // |v| larger: t negative (replace v) } while (t != 0); return -u * (1L << k); // gcd is u*2^k } /** * Returns an integer hash code representing the given double value. * * @param value the value to be hashed * @return the hash code */ public static int hash(double value) { return new Double(value).hashCode(); } /** * Returns an integer hash code representing the given double array. * * @param value the value to be hashed (may be null) * @return the hash code * @since 1.2 */ public static int hash(double[] value) { return Arrays.hashCode(value); } /** * For a byte value x, this method returns (byte)(+1) if x >= 0 and * (byte)(-1) if x < 0. * * @param x the value, a byte * @return (byte)(+1) or (byte)(-1), depending on the sign of x */ public static byte indicator(final byte x) { return (x >= ZB) ? PB : NB; } /** * For a double precision value x, this method returns +1.0 if x >= 0 and * -1.0 if x < 0. Returns NaN if x is * NaN. * * @param x the value, a double * @return +1.0 or -1.0, depending on the sign of x */ public static double indicator(final double x) { if (Double.isNaN(x)) { return Double.NaN; } return (x >= 0.0) ? 1.0 : -1.0; } /** * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x < * 0. Returns NaN if x is NaN. * * @param x the value, a float * @return +1.0F or -1.0F, depending on the sign of x */ public static float indicator(final float x) { if (Float.isNaN(x)) { return Float.NaN; } return (x >= 0.0F) ? 1.0F : -1.0F; } /** * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0. * * @param x the value, an int * @return +1 or -1, depending on the sign of x */ public static int indicator(final int x) { return (x >= 0) ? 1 : -1; } /** * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0. * * @param x the value, a long * @return +1L or -1L, depending on the sign of x */ public static long indicator(final long x) { return (x >= 0L) ? 1L : -1L; } /** * For a short value x, this method returns (short)(+1) if x >= 0 and * (short)(-1) if x < 0. * * @param x the value, a short * @return (short)(+1) or (short)(-1), depending on the sign of x */ public static short indicator(final short x) { return (x >= ZS) ? PS : NS; } /** *

                            * Returns the least common multiple of the absolute value of two numbers, * using the formula lcm(a,b) = (a / gcd(a,b)) * b. *

                            * Special cases: *
                              *
                            • The invocations lcm(Integer.MIN_VALUE, n) and * lcm(n, Integer.MIN_VALUE), where abs(n) is a * power of 2, throw an ArithmeticException, because the result * would be 2^31, which is too large for an int value.
                            • *
                            • The result of lcm(0, x) and lcm(x, 0) is * 0 for any x. *
                            * * @param a any number * @param b any number * @return the least common multiple, never negative * @throws ArithmeticException * if the result cannot be represented as a nonnegative int * value * @since 1.1 */ public static int lcm(int a, int b) { if (a==0 || b==0){ return 0; } int lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b)); if (lcm == Integer.MIN_VALUE) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.LCM_OVERFLOW_32_BITS, a, b); } return lcm; } /** *

                            * Returns the least common multiple of the absolute value of two numbers, * using the formula lcm(a,b) = (a / gcd(a,b)) * b. *

                            * Special cases: *
                              *
                            • The invocations lcm(Long.MIN_VALUE, n) and * lcm(n, Long.MIN_VALUE), where abs(n) is a * power of 2, throw an ArithmeticException, because the result * would be 2^63, which is too large for an int value.
                            • *
                            • The result of lcm(0L, x) and lcm(x, 0L) is * 0L for any x. *
                            * * @param a any number * @param b any number * @return the least common multiple, never negative * @throws ArithmeticException if the result cannot be represented as a nonnegative long * value * @since 2.1 */ public static long lcm(long a, long b) { if (a==0 || b==0){ return 0; } long lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b)); if (lcm == Long.MIN_VALUE){ throw MathRuntimeException.createArithmeticException( LocalizedFormats.LCM_OVERFLOW_64_BITS, a, b); } return lcm; } /** *

                            Returns the * logarithm * for base b of x. *

                            *

                            Returns NaN if either argument is negative. If * base is 0 and x is positive, 0 is returned. * If base is positive and x is 0, * Double.NEGATIVE_INFINITY is returned. If both arguments * are 0, the result is NaN.

                            * * @param base the base of the logarithm, must be greater than 0 * @param x argument, must be greater than 0 * @return the value of the logarithm - the number y such that base^y = x. * @since 1.2 */ public static double log(double base, double x) { return FastMath.log(x)/FastMath.log(base); } /** * Multiply two integers, checking for overflow. * * @param x a factor * @param y a factor * @return the product x*y * @throws ArithmeticException if the result can not be represented as an * int * @since 1.1 */ public static int mulAndCheck(int x, int y) { long m = ((long)x) * ((long)y); if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) { throw new ArithmeticException("overflow: mul"); } return (int)m; } /** * Multiply two long integers, checking for overflow. * * @param a first value * @param b second value * @return the product a * b * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ public static long mulAndCheck(long a, long b) { long ret; String msg = "overflow: multiply"; if (a > b) { // use symmetry to reduce boundary cases ret = mulAndCheck(b, a); } else { if (a < 0) { if (b < 0) { // check for positive overflow with negative a, negative b if (a >= Long.MAX_VALUE / b) { ret = a * b; } else { throw new ArithmeticException(msg); } } else if (b > 0) { // check for negative overflow with negative a, positive b if (Long.MIN_VALUE / b <= a) { ret = a * b; } else { throw new ArithmeticException(msg); } } else { // assert b == 0 ret = 0; } } else if (a > 0) { // assert a > 0 // assert b > 0 // check for positive overflow with positive a, positive b if (a <= Long.MAX_VALUE / b) { ret = a * b; } else { throw new ArithmeticException(msg); } } else { // assert a == 0 ret = 0; } } return ret; } /** * Get the next machine representable number after a number, moving * in the direction of another number. *

                            * If direction is greater than or equal tod, * the smallest machine representable number strictly greater than * d is returned; otherwise the largest representable number * strictly less than d is returned.

                            *

                            * If d is NaN or Infinite, it is returned unchanged.

                            * * @param d base number * @param direction (the only important thing is whether * direction is greater or smaller than d) * @return the next machine representable number in the specified direction * @since 1.2 * @deprecated as of 2.2, replaced by {@link FastMath#nextAfter(double, double)} * which handles Infinities differently, and returns direction if d and direction compare equal. */ @Deprecated public static double nextAfter(double d, double direction) { // handling of some important special cases if (Double.isNaN(d) || Double.isInfinite(d)) { return d; } else if (d == 0) { return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; } // special cases MAX_VALUE to infinity and MIN_VALUE to 0 // are handled just as normal numbers // split the double in raw components long bits = Double.doubleToLongBits(d); long sign = bits & 0x8000000000000000L; long exponent = bits & 0x7ff0000000000000L; long mantissa = bits & 0x000fffffffffffffL; if (d * (direction - d) >= 0) { // we should increase the mantissa if (mantissa == 0x000fffffffffffffL) { return Double.longBitsToDouble(sign | (exponent + 0x0010000000000000L)); } else { return Double.longBitsToDouble(sign | exponent | (mantissa + 1)); } } else { // we should decrease the mantissa if (mantissa == 0L) { return Double.longBitsToDouble(sign | (exponent - 0x0010000000000000L) | 0x000fffffffffffffL); } else { return Double.longBitsToDouble(sign | exponent | (mantissa - 1)); } } } /** * Scale a number by 2scaleFactor. *

                            If d is 0 or NaN or Infinite, it is returned unchanged.

                            * * @param d base number * @param scaleFactor power of two by which d should be multiplied * @return d × 2scaleFactor * @since 2.0 * @deprecated as of 2.2, replaced by {@link FastMath#scalb(double, int)} */ @Deprecated public static double scalb(final double d, final int scaleFactor) { return FastMath.scalb(d, scaleFactor); } /** * Normalize an angle in a 2&pi wide interval around a center value. *

                            This method has three main uses:

                            *
                              *
                            • normalize an angle between 0 and 2π:
                              * a = MathUtils.normalizeAngle(a, FastMath.PI);
                            • *
                            • normalize an angle between -π and +π
                              * a = MathUtils.normalizeAngle(a, 0.0);
                            • *
                            • compute the angle between two defining angular positions:
                              * angle = MathUtils.normalizeAngle(end, start) - start;
                            • *
                            *

                            Note that due to numerical accuracy and since π cannot be represented * exactly, the result interval is closed, it cannot be half-closed * as would be more satisfactory in a purely mathematical view.

                            * @param a angle to normalize * @param center center of the desired 2π interval for the result * @return a-2kπ with integer k and center-π <= a-2kπ <= center+π * @since 1.2 */ public static double normalizeAngle(double a, double center) { return a - TWO_PI * FastMath.floor((a + FastMath.PI - center) / TWO_PI); } /** *

                            Normalizes an array to make it sum to a specified value. * Returns the result of the transformation

                                  *    x |-> x * normalizedSum / sum
                                  * 
                            * applied to each non-NaN element x of the input array, where sum is the * sum of the non-NaN entries in the input array.

                            * *

                            Throws IllegalArgumentException if normalizedSum is infinite * or NaN and ArithmeticException if the input array contains any infinite elements * or sums to 0

                            * *

                            Ignores (i.e., copies unchanged to the output array) NaNs in the input array.

                            * * @param values input array to be normalized * @param normalizedSum target sum for the normalized array * @return normalized array * @throws ArithmeticException if the input array contains infinite elements or sums to zero * @throws IllegalArgumentException if the target sum is infinite or NaN * @since 2.1 */ public static double[] normalizeArray(double[] values, double normalizedSum) throws ArithmeticException, IllegalArgumentException { if (Double.isInfinite(normalizedSum)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NORMALIZE_INFINITE); } if (Double.isNaN(normalizedSum)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NORMALIZE_NAN); } double sum = 0d; final int len = values.length; double[] out = new double[len]; for (int i = 0; i < len; i++) { if (Double.isInfinite(values[i])) { throw MathRuntimeException.createArithmeticException( LocalizedFormats.INFINITE_ARRAY_ELEMENT, values[i], i); } if (!Double.isNaN(values[i])) { sum += values[i]; } } if (sum == 0) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ARRAY_SUMS_TO_ZERO); } for (int i = 0; i < len; i++) { if (Double.isNaN(values[i])) { out[i] = Double.NaN; } else { out[i] = values[i] * normalizedSum / sum; } } return out; } /** * Round the given value to the specified number of decimal places. The * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @return the rounded value. * @since 1.1 */ public static double round(double x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } /** * Round the given value to the specified number of decimal places. The * value is rounded using the given method which is any method defined in * {@link BigDecimal}. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ public static double round(double x, int scale, int roundingMethod) { try { return (new BigDecimal (Double.toString(x)) .setScale(scale, roundingMethod)) .doubleValue(); } catch (NumberFormatException ex) { if (Double.isInfinite(x)) { return x; } else { return Double.NaN; } } } /** * Round the given value to the specified number of decimal places. The * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @return the rounded value. * @since 1.1 */ public static float round(float x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } /** * Round the given value to the specified number of decimal places. The * value is rounded using the given method which is any method defined in * {@link BigDecimal}. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ public static float round(float x, int scale, int roundingMethod) { float sign = indicator(x); float factor = (float)FastMath.pow(10.0f, scale) * sign; return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor; } /** * Round the given non-negative, value to the "nearest" integer. Nearest is * determined by the rounding method specified. Rounding methods are defined * in {@link BigDecimal}. * * @param unscaled the value to round. * @param sign the sign of the original, scaled value. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ private static double roundUnscaled(double unscaled, double sign, int roundingMethod) { switch (roundingMethod) { case BigDecimal.ROUND_CEILING : if (sign == -1) { unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); } else { unscaled = FastMath.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); } break; case BigDecimal.ROUND_DOWN : unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); break; case BigDecimal.ROUND_FLOOR : if (sign == -1) { unscaled = FastMath.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); } else { unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); } break; case BigDecimal.ROUND_HALF_DOWN : { unscaled = nextAfter(unscaled, Double.NEGATIVE_INFINITY); double fraction = unscaled - FastMath.floor(unscaled); if (fraction > 0.5) { unscaled = FastMath.ceil(unscaled); } else { unscaled = FastMath.floor(unscaled); } break; } case BigDecimal.ROUND_HALF_EVEN : { double fraction = unscaled - FastMath.floor(unscaled); if (fraction > 0.5) { unscaled = FastMath.ceil(unscaled); } else if (fraction < 0.5) { unscaled = FastMath.floor(unscaled); } else { // The following equality test is intentional and needed for rounding purposes if (FastMath.floor(unscaled) / 2.0 == FastMath.floor(Math .floor(unscaled) / 2.0)) { // even unscaled = FastMath.floor(unscaled); } else { // odd unscaled = FastMath.ceil(unscaled); } } break; } case BigDecimal.ROUND_HALF_UP : { unscaled = nextAfter(unscaled, Double.POSITIVE_INFINITY); double fraction = unscaled - FastMath.floor(unscaled); if (fraction >= 0.5) { unscaled = FastMath.ceil(unscaled); } else { unscaled = FastMath.floor(unscaled); } break; } case BigDecimal.ROUND_UNNECESSARY : if (unscaled != FastMath.floor(unscaled)) { throw new ArithmeticException("Inexact result from rounding"); } break; case BigDecimal.ROUND_UP : unscaled = FastMath.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); break; default : throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.INVALID_ROUNDING_METHOD, roundingMethod, "ROUND_CEILING", BigDecimal.ROUND_CEILING, "ROUND_DOWN", BigDecimal.ROUND_DOWN, "ROUND_FLOOR", BigDecimal.ROUND_FLOOR, "ROUND_HALF_DOWN", BigDecimal.ROUND_HALF_DOWN, "ROUND_HALF_EVEN", BigDecimal.ROUND_HALF_EVEN, "ROUND_HALF_UP", BigDecimal.ROUND_HALF_UP, "ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY, "ROUND_UP", BigDecimal.ROUND_UP); } return unscaled; } /** * Returns the sign * for byte value x. *

                            * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if * x = 0, and (byte)(-1) if x < 0.

                            * * @param x the value, a byte * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x */ public static byte sign(final byte x) { return (x == ZB) ? ZB : (x > ZB) ? PB : NB; } /** * Returns the sign * for double precision x. *

                            * For a double value x, this method returns * +1.0 if x > 0, 0.0 if * x = 0.0, and -1.0 if x < 0. * Returns NaN if x is NaN.

                            * * @param x the value, a double * @return +1.0, 0.0, or -1.0, depending on the sign of x */ public static double sign(final double x) { if (Double.isNaN(x)) { return Double.NaN; } return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; } /** * Returns the sign * for float value x. *

                            * For a float value x, this method returns +1.0F if x > 0, 0.0F if x = * 0.0F, and -1.0F if x < 0. Returns NaN if x * is NaN.

                            * * @param x the value, a float * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x */ public static float sign(final float x) { if (Float.isNaN(x)) { return Float.NaN; } return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; } /** * Returns the sign * for int value x. *

                            * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1 * if x < 0.

                            * * @param x the value, an int * @return +1, 0, or -1, depending on the sign of x */ public static int sign(final int x) { return (x == 0) ? 0 : (x > 0) ? 1 : -1; } /** * Returns the sign * for long value x. *

                            * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and * -1L if x < 0.

                            * * @param x the value, a long * @return +1L, 0L, or -1L, depending on the sign of x */ public static long sign(final long x) { return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; } /** * Returns the sign * for short value x. *

                            * For a short value x, this method returns (short)(+1) if x > 0, (short)(0) * if x = 0, and (short)(-1) if x < 0.

                            * * @param x the value, a short * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of * x */ public static short sign(final short x) { return (x == ZS) ? ZS : (x > ZS) ? PS : NS; } /** * Returns the * hyperbolic sine of x. * * @param x double value for which to find the hyperbolic sine * @return hyperbolic sine of x */ public static double sinh(double x) { return (FastMath.exp(x) - FastMath.exp(-x)) / 2.0; } /** * Subtract two integers, checking for overflow. * * @param x the minuend * @param y the subtrahend * @return the difference x-y * @throws ArithmeticException if the result can not be represented as an * int * @since 1.1 */ public static int subAndCheck(int x, int y) { long s = (long)x - (long)y; if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, x, y); } return (int)s; } /** * Subtract two long integers, checking for overflow. * * @param a first value * @param b second value * @return the difference a-b * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ public static long subAndCheck(long a, long b) { long ret; String msg = "overflow: subtract"; if (b == Long.MIN_VALUE) { if (a < 0) { ret = a - b; } else { throw new ArithmeticException(msg); } } else { // use additive inverse ret = addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION); } return ret; } /** * Raise an int to an int power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static int pow(final int k, int e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } int result = 1; int k2p = k; while (e != 0) { if ((e & 0x1) != 0) { result *= k2p; } k2p *= k2p; e = e >> 1; } return result; } /** * Raise an int to a long power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static int pow(final int k, long e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } int result = 1; int k2p = k; while (e != 0) { if ((e & 0x1) != 0) { result *= k2p; } k2p *= k2p; e = e >> 1; } return result; } /** * Raise a long to an int power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static long pow(final long k, int e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } long result = 1l; long k2p = k; while (e != 0) { if ((e & 0x1) != 0) { result *= k2p; } k2p *= k2p; e = e >> 1; } return result; } /** * Raise a long to a long power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static long pow(final long k, long e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } long result = 1l; long k2p = k; while (e != 0) { if ((e & 0x1) != 0) { result *= k2p; } k2p *= k2p; e = e >> 1; } return result; } /** * Raise a BigInteger to an int power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static BigInteger pow(final BigInteger k, int e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } return k.pow(e); } /** * Raise a BigInteger to a long power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static BigInteger pow(final BigInteger k, long e) throws IllegalArgumentException { if (e < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } BigInteger result = BigInteger.ONE; BigInteger k2p = k; while (e != 0) { if ((e & 0x1) != 0) { result = result.multiply(k2p); } k2p = k2p.multiply(k2p); e = e >> 1; } return result; } /** * Raise a BigInteger to a BigInteger power. * @param k number to raise * @param e exponent (must be positive or null) * @return ke * @exception IllegalArgumentException if e is negative */ public static BigInteger pow(final BigInteger k, BigInteger e) throws IllegalArgumentException { if (e.compareTo(BigInteger.ZERO) < 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.POWER_NEGATIVE_PARAMETERS, k, e); } BigInteger result = BigInteger.ONE; BigInteger k2p = k; while (!BigInteger.ZERO.equals(e)) { if (e.testBit(0)) { result = result.multiply(k2p); } k2p = k2p.multiply(k2p); e = e.shiftRight(1); } return result; } /** * Calculates the L1 (sum of abs) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L1 distance between the two points */ public static double distance1(double[] p1, double[] p2) { double sum = 0; for (int i = 0; i < p1.length; i++) { sum += FastMath.abs(p1[i] - p2[i]); } return sum; } /** * Calculates the L1 (sum of abs) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L1 distance between the two points */ public static int distance1(int[] p1, int[] p2) { int sum = 0; for (int i = 0; i < p1.length; i++) { sum += FastMath.abs(p1[i] - p2[i]); } return sum; } /** * Calculates the L2 (Euclidean) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L2 distance between the two points */ public static double distance(double[] p1, double[] p2) { double sum = 0; for (int i = 0; i < p1.length; i++) { final double dp = p1[i] - p2[i]; sum += dp * dp; } return FastMath.sqrt(sum); } /** * Calculates the L2 (Euclidean) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L2 distance between the two points */ public static double distance(int[] p1, int[] p2) { double sum = 0; for (int i = 0; i < p1.length; i++) { final double dp = p1[i] - p2[i]; sum += dp * dp; } return FastMath.sqrt(sum); } /** * Calculates the L (max of abs) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L distance between the two points */ public static double distanceInf(double[] p1, double[] p2) { double max = 0; for (int i = 0; i < p1.length; i++) { max = FastMath.max(max, FastMath.abs(p1[i] - p2[i])); } return max; } /** * Calculates the L (max of abs) distance between two points. * * @param p1 the first point * @param p2 the second point * @return the L distance between the two points */ public static int distanceInf(int[] p1, int[] p2) { int max = 0; for (int i = 0; i < p1.length; i++) { max = FastMath.max(max, FastMath.abs(p1[i] - p2[i])); } return max; } /** * Specification of ordering direction. */ public static enum OrderDirection { /** Constant for increasing direction. */ INCREASING, /** Constant for decreasing direction. */ DECREASING } /** * Checks that the given array is sorted. * * @param val Values. * @param dir Ordering direction. * @param strict Whether the order should be strict. * @throws NonMonotonousSequenceException if the array is not sorted. * @since 2.2 */ public static void checkOrder(double[] val, OrderDirection dir, boolean strict) { double previous = val[0]; boolean ok = true; int max = val.length; for (int i = 1; i < max; i++) { switch (dir) { case INCREASING: if (strict) { if (val[i] <= previous) { ok = false; } } else { if (val[i] < previous) { ok = false; } } break; case DECREASING: if (strict) { if (val[i] >= previous) { ok = false; } } else { if (val[i] > previous) { ok = false; } } break; default: // Should never happen. throw new IllegalArgumentException(); } if (!ok) { throw new NonMonotonousSequenceException(val[i], previous, i, dir, strict); } previous = val[i]; } } /** * Checks that the given array is sorted in strictly increasing order. * * @param val Values. * @throws NonMonotonousSequenceException if the array is not sorted. * @since 2.2 */ public static void checkOrder(double[] val) { checkOrder(val, OrderDirection.INCREASING, true); } /** * Checks that the given array is sorted. * * @param val Values * @param dir Order direction (-1 for decreasing, 1 for increasing) * @param strict Whether the order should be strict * @throws NonMonotonousSequenceException if the array is not sorted. * @deprecated as of 2.2 (please use the new {@link #checkOrder(double[],OrderDirection,boolean) * checkOrder} method). To be removed in 3.0. */ @Deprecated public static void checkOrder(double[] val, int dir, boolean strict) { if (dir > 0) { checkOrder(val, OrderDirection.INCREASING, strict); } else { checkOrder(val, OrderDirection.DECREASING, strict); } } /** * Returns the Cartesian norm (2-norm), handling both overflow and underflow. * Translation of the minpack enorm subroutine. * * The redistribution policy for MINPACK is available here, for convenience, it * is reproduced below.

                            * * * * *
                            * Minpack Copyright Notice (1999) University of Chicago. * All rights reserved *
                            * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *
                              *
                            1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
                            2. *
                            3. 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.
                            4. *
                            5. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: * This product includes software developed by the University of * Chicago, as Operator of Argonne National Laboratory. * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear.
                            6. *
                            7. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL * BE CORRECTED.
                            8. *
                            9. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE * POSSIBILITY OF SUCH LOSS OR DAMAGES.
                            10. *
                              * * @param v vector of doubles * @return the 2-norm of the vector * @since 2.2 */ public static double safeNorm(double[] v) { double rdwarf = 3.834e-20; double rgiant = 1.304e+19; double s1=0.0; double s2=0.0; double s3=0.0; double x1max = 0.0; double x3max = 0.0; double floatn = (double)v.length; double agiant = rgiant/floatn; for (int i=0;iagiant) { if (xabs>rdwarf) { if (xabs>x1max) { double r=x1max/xabs; s1=1.0+s1*r*r; x1max=xabs; } else { double r=xabs/x1max; s1+=r*r; } } else { if (xabs>x3max) { double r=x3max/xabs; s3=1.0+s3*r*r; x3max=xabs; } else { if (xabs!=0.0) { double r=xabs/x3max; s3+=r*r; } } } } else { s2+=xabs*xabs; } } double norm; if (s1!=0.0) { norm = x1max*Math.sqrt(s1+(s2/x1max)/x1max); } else { if (s2==0.0) { norm = x3max*Math.sqrt(s3); } else { if (s2>=x3max) { norm = Math.sqrt(s2*(1.0+(x3max/s2)*(x3max*s3))); } else { norm = Math.sqrt(x3max*((s2/x3max)+(x3max*s3))); } } } return norm; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/ContinuedFraction.java100644 1750 1750 17067 11532241247 27637 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.MathException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Provides a generic means to evaluate continued fractions. Subclasses simply * provided the a and b coefficients to evaluate the continued fraction. * *

                              * References: *

                              *

                              * * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ */ public abstract class ContinuedFraction { /** Maximum allowed numerical error. */ private static final double DEFAULT_EPSILON = 10e-9; /** * Default constructor. */ protected ContinuedFraction() { super(); } /** * Access the n-th a coefficient of the continued fraction. Since a can be * a function of the evaluation point, x, that is passed in as well. * @param n the coefficient index to retrieve. * @param x the evaluation point. * @return the n-th a coefficient. */ protected abstract double getA(int n, double x); /** * Access the n-th b coefficient of the continued fraction. Since b can be * a function of the evaluation point, x, that is passed in as well. * @param n the coefficient index to retrieve. * @param x the evaluation point. * @return the n-th b coefficient. */ protected abstract double getB(int n, double x); /** * Evaluates the continued fraction at the value x. * @param x the evaluation point. * @return the value of the continued fraction evaluated at x. * @throws MathException if the algorithm fails to converge. */ public double evaluate(double x) throws MathException { return evaluate(x, DEFAULT_EPSILON, Integer.MAX_VALUE); } /** * Evaluates the continued fraction at the value x. * @param x the evaluation point. * @param epsilon maximum error allowed. * @return the value of the continued fraction evaluated at x. * @throws MathException if the algorithm fails to converge. */ public double evaluate(double x, double epsilon) throws MathException { return evaluate(x, epsilon, Integer.MAX_VALUE); } /** * Evaluates the continued fraction at the value x. * @param x the evaluation point. * @param maxIterations maximum number of convergents * @return the value of the continued fraction evaluated at x. * @throws MathException if the algorithm fails to converge. */ public double evaluate(double x, int maxIterations) throws MathException { return evaluate(x, DEFAULT_EPSILON, maxIterations); } /** *

                              * Evaluates the continued fraction at the value x. *

                              * *

                              * The implementation of this method is based on equations 14-17 of: *

                              * The recurrence relationship defined in those equations can result in * very large intermediate results which can result in numerical overflow. * As a means to combat these overflow conditions, the intermediate results * are scaled whenever they threaten to become numerically unstable.

                              * * @param x the evaluation point. * @param epsilon maximum error allowed. * @param maxIterations maximum number of convergents * @return the value of the continued fraction evaluated at x. * @throws MathException if the algorithm fails to converge. */ public double evaluate(double x, double epsilon, int maxIterations) throws MathException { double p0 = 1.0; double p1 = getA(0, x); double q0 = 0.0; double q1 = 1.0; double c = p1 / q1; int n = 0; double relativeError = Double.MAX_VALUE; while (n < maxIterations && relativeError > epsilon) { ++n; double a = getA(n, x); double b = getB(n, x); double p2 = a * p1 + b * p0; double q2 = a * q1 + b * q0; boolean infinite = false; if (Double.isInfinite(p2) || Double.isInfinite(q2)) { /* * Need to scale. Try successive powers of the larger of a or b * up to 5th power. Throw ConvergenceException if one or both * of p2, q2 still overflow. */ double scaleFactor = 1d; double lastScaleFactor = 1d; final int maxPower = 5; final double scale = FastMath.max(a,b); if (scale <= 0) { // Can't scale throw new ConvergenceException( LocalizedFormats.CONTINUED_FRACTION_INFINITY_DIVERGENCE, x); } infinite = true; for (int i = 0; i < maxPower; i++) { lastScaleFactor = scaleFactor; scaleFactor *= scale; if (a != 0.0 && a > b) { p2 = p1 / lastScaleFactor + (b / scaleFactor * p0); q2 = q1 / lastScaleFactor + (b / scaleFactor * q0); } else if (b != 0) { p2 = (a / scaleFactor * p1) + p0 / lastScaleFactor; q2 = (a / scaleFactor * q1) + q0 / lastScaleFactor; } infinite = Double.isInfinite(p2) || Double.isInfinite(q2); if (!infinite) { break; } } } if (infinite) { // Scaling failed throw new ConvergenceException( LocalizedFormats.CONTINUED_FRACTION_INFINITY_DIVERGENCE, x); } double r = p2 / q2; if (Double.isNaN(r)) { throw new ConvergenceException( LocalizedFormats.CONTINUED_FRACTION_NAN_DIVERGENCE, x); } relativeError = FastMath.abs(r / c - 1.0); // prepare for next iteration c = p2 / q2; p0 = p1; p1 = p2; q0 = q1; q1 = q2; } if (n >= maxIterations) { throw new MaxIterationsExceededException(maxIterations, LocalizedFormats.NON_CONVERGENT_CONTINUED_FRACTION, x); } return c; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/BigRealField.java100644 1750 1750 4471 11532241247 26445 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.Serializable; import org.apache.commons.math.Field; /** * Representation of real numbers with arbitrary precision field. *

                              * This class is a singleton. *

                              * @see BigReal * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $ * @since 2.0 */ public class BigRealField implements Field, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 4756431066541037559L; /** Private constructor for the singleton. */ private BigRealField() { } /** Get the unique instance. * @return the unique instance */ public static BigRealField getInstance() { return LazyHolder.INSTANCE; } /** {@inheritDoc} */ public BigReal getOne() { return BigReal.ONE; } /** {@inheritDoc} */ public BigReal getZero() { return BigReal.ZERO; } // CHECKSTYLE: stop HideUtilityClassConstructor /** Holder for the instance. *

                              We use here the Initialization On Demand Holder Idiom.

                              */ private static class LazyHolder { /** Cached field instance. */ private static final BigRealField INSTANCE = new BigRealField(); } // CHECKSTYLE: resume HideUtilityClassConstructor /** Handle deserialization of the singleton. * @return the singleton instance */ private Object readResolve() { // return the singleton instance return LazyHolder.INSTANCE; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java100644 1750 1750 45752 11532241247 30310 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.lang.reflect.Array; import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; import org.apache.commons.math.Field; import org.apache.commons.math.FieldElement; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Open addressed map from int to FieldElement. *

                              This class provides a dedicated map from integers to FieldElements with a * much smaller memory overhead than standard java.util.Map.

                              *

                              This class is not synchronized. The specialized iterators returned by * {@link #iterator()} are fail-fast: they throw a * ConcurrentModificationException when they detect the map has been * modified during iteration.

                              * @param the type of the field elements * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ * @since 2.0 */ public class OpenIntToFieldHashMap> implements Serializable { /** Status indicator for free table entries. */ protected static final byte FREE = 0; /** Status indicator for full table entries. */ protected static final byte FULL = 1; /** Status indicator for removed table entries. */ protected static final byte REMOVED = 2; /** Serializable version identifier. */ private static final long serialVersionUID = -9179080286849120720L; /** Load factor for the map. */ private static final float LOAD_FACTOR = 0.5f; /** Default starting size. *

                              This must be a power of two for bit mask to work properly.

                              */ private static final int DEFAULT_EXPECTED_SIZE = 16; /** Multiplier for size growth when map fills up. *

                              This must be a power of two for bit mask to work properly.

                              */ private static final int RESIZE_MULTIPLIER = 2; /** Number of bits to perturb the index when probing for collision resolution. */ private static final int PERTURB_SHIFT = 5; /** Field to which the elements belong. */ private final Field field; /** Keys table. */ private int[] keys; /** Values table. */ private T[] values; /** States table. */ private byte[] states; /** Return value for missing entries. */ private final T missingEntries; /** Current size of the map. */ private int size; /** Bit mask for hash values. */ private int mask; /** Modifications count. */ private transient int count; /** * Build an empty map with default size and using zero for missing entries. * @param field field to which the elements belong */ public OpenIntToFieldHashMap(final Fieldfield) { this(field, DEFAULT_EXPECTED_SIZE, field.getZero()); } /** * Build an empty map with default size * @param field field to which the elements belong * @param missingEntries value to return when a missing entry is fetched */ public OpenIntToFieldHashMap(final Fieldfield, final T missingEntries) { this(field,DEFAULT_EXPECTED_SIZE, missingEntries); } /** * Build an empty map with specified size and using zero for missing entries. * @param field field to which the elements belong * @param expectedSize expected number of elements in the map */ public OpenIntToFieldHashMap(final Field field,final int expectedSize) { this(field,expectedSize, field.getZero()); } /** * Build an empty map with specified size. * @param field field to which the elements belong * @param expectedSize expected number of elements in the map * @param missingEntries value to return when a missing entry is fetched */ public OpenIntToFieldHashMap(final Field field,final int expectedSize, final T missingEntries) { this.field = field; final int capacity = computeCapacity(expectedSize); keys = new int[capacity]; values = buildArray(capacity); states = new byte[capacity]; this.missingEntries = missingEntries; mask = capacity - 1; } /** * Copy constructor. * @param source map to copy */ public OpenIntToFieldHashMap(final OpenIntToFieldHashMap source) { field = source.field; final int length = source.keys.length; keys = new int[length]; System.arraycopy(source.keys, 0, keys, 0, length); values = buildArray(length); System.arraycopy(source.values, 0, values, 0, length); states = new byte[length]; System.arraycopy(source.states, 0, states, 0, length); missingEntries = source.missingEntries; size = source.size; mask = source.mask; count = source.count; } /** * Compute the capacity needed for a given size. * @param expectedSize expected size of the map * @return capacity to use for the specified size */ private static int computeCapacity(final int expectedSize) { if (expectedSize == 0) { return 1; } final int capacity = (int) FastMath.ceil(expectedSize / LOAD_FACTOR); final int powerOfTwo = Integer.highestOneBit(capacity); if (powerOfTwo == capacity) { return capacity; } return nextPowerOfTwo(capacity); } /** * Find the smallest power of two greater than the input value * @param i input value * @return smallest power of two greater than the input value */ private static int nextPowerOfTwo(final int i) { return Integer.highestOneBit(i) << 1; } /** * Get the stored value associated with the given key * @param key key associated with the data * @return data associated with the key */ public T get(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return values[index]; } if (states[index] == FREE) { return missingEntries; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return values[index]; } } return missingEntries; } /** * Check if a value is associated with a key. * @param key key to check * @return true if a value is associated with key */ public boolean containsKey(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return true; } if (states[index] == FREE) { return false; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return true; } } return false; } /** * Get an iterator over map elements. *

                              The specialized iterators returned are fail-fast: they throw a * ConcurrentModificationException when they detect the map * has been modified during iteration.

                              * @return iterator over the map elements */ public Iterator iterator() { return new Iterator(); } /** * Perturb the hash for starting probing. * @param hash initial hash * @return perturbed hash */ private static int perturb(final int hash) { return hash & 0x7fffffff; } /** * Find the index at which a key should be inserted * @param key key to lookup * @return index at which key should be inserted */ private int findInsertionIndex(final int key) { return findInsertionIndex(keys, states, key, mask); } /** * Find the index at which a key should be inserted * @param keys keys table * @param states states table * @param key key to lookup * @param mask bit mask for hash values * @return index at which key should be inserted */ private static int findInsertionIndex(final int[] keys, final byte[] states, final int key, final int mask) { final int hash = hashOf(key); int index = hash & mask; if (states[index] == FREE) { return index; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index); } int perturb = perturb(hash); int j = index; if (states[index] == FULL) { while (true) { j = probe(perturb, j); index = j & mask; perturb >>= PERTURB_SHIFT; if (states[index] != FULL || keys[index] == key) { break; } } } if (states[index] == FREE) { return index; } else if (states[index] == FULL) { // due to the loop exit condition, // if (states[index] == FULL) then keys[index] == key return changeIndexSign(index); } final int firstRemoved = index; while (true) { j = probe(perturb, j); index = j & mask; if (states[index] == FREE) { return firstRemoved; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index); } perturb >>= PERTURB_SHIFT; } } /** * Compute next probe for collision resolution * @param perturb perturbed hash * @param j previous probe * @return next probe */ private static int probe(final int perturb, final int j) { return (j << 2) + j + perturb + 1; } /** * Change the index sign * @param index initial index * @return changed index */ private static int changeIndexSign(final int index) { return -index - 1; } /** * Get the number of elements stored in the map. * @return number of elements stored in the map */ public int size() { return size; } /** * Remove the value associated with a key. * @param key key to which the value is associated * @return removed value */ public T remove(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return doRemove(index); } if (states[index] == FREE) { return missingEntries; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return doRemove(index); } } return missingEntries; } /** * Check if the tables contain an element associated with specified key * at specified index. * @param key key to check * @param index index to check * @return true if an element is associated with key at index */ private boolean containsKey(final int key, final int index) { return (key != 0 || states[index] == FULL) && keys[index] == key; } /** * Remove an element at specified index. * @param index index of the element to remove * @return removed value */ private T doRemove(int index) { keys[index] = 0; states[index] = REMOVED; final T previous = values[index]; values[index] = missingEntries; --size; ++count; return previous; } /** * Put a value associated with a key in the map. * @param key key to which value is associated * @param value value to put in the map * @return previous value associated with the key */ public T put(final int key, final T value) { int index = findInsertionIndex(key); T previous = missingEntries; boolean newMapping = true; if (index < 0) { index = changeIndexSign(index); previous = values[index]; newMapping = false; } keys[index] = key; states[index] = FULL; values[index] = value; if (newMapping) { ++size; if (shouldGrowTable()) { growTable(); } ++count; } return previous; } /** * Grow the tables. */ private void growTable() { final int oldLength = states.length; final int[] oldKeys = keys; final T[] oldValues = values; final byte[] oldStates = states; final int newLength = RESIZE_MULTIPLIER * oldLength; final int[] newKeys = new int[newLength]; final T[] newValues = buildArray(newLength); final byte[] newStates = new byte[newLength]; final int newMask = newLength - 1; for (int i = 0; i < oldLength; ++i) { if (oldStates[i] == FULL) { final int key = oldKeys[i]; final int index = findInsertionIndex(newKeys, newStates, key, newMask); newKeys[index] = key; newValues[index] = oldValues[i]; newStates[index] = FULL; } } mask = newMask; keys = newKeys; values = newValues; states = newStates; } /** * Check if tables should grow due to increased size. * @return true if tables should grow */ private boolean shouldGrowTable() { return size > (mask + 1) * LOAD_FACTOR; } /** * Compute the hash value of a key * @param key key to hash * @return hash value of the key */ private static int hashOf(final int key) { final int h = key ^ ((key >>> 20) ^ (key >>> 12)); return h ^ (h >>> 7) ^ (h >>> 4); } /** Iterator class for the map. */ public class Iterator { /** Reference modification count. */ private final int referenceCount; /** Index of current element. */ private int current; /** Index of next element. */ private int next; /** * Simple constructor. */ private Iterator() { // preserve the modification count of the map to detect concurrent modifications later referenceCount = count; // initialize current index next = -1; try { advance(); } catch (NoSuchElementException nsee) { // ignored } } /** * Check if there is a next element in the map. * @return true if there is a next element */ public boolean hasNext() { return next >= 0; } /** * Get the key of current entry. * @return key of current entry * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public int key() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } return keys[current]; } /** * Get the value of current entry. * @return value of current entry * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public T value() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } return values[current]; } /** * Advance iterator one step further. * @exception ConcurrentModificationException if the map is modified during iteration * @exception NoSuchElementException if there is no element left in the map */ public void advance() throws ConcurrentModificationException, NoSuchElementException { if (referenceCount != count) { throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING); } // advance on step current = next; // prepare next step try { while (states[++next] != FULL) { // nothing to do } } catch (ArrayIndexOutOfBoundsException e) { next = -2; if (current < 0) { throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED); } } } } /** * Read a serialized object. * @param stream input stream * @throws IOException if object cannot be read * @throws ClassNotFoundException if the class corresponding * to the serialized object cannot be found */ private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); count = 0; } /** Build an array of elements. * @param length size of the array to build * @return a new array */ @SuppressWarnings("unchecked") // field is of type T private T[] buildArray(final int length) { return (T[]) Array.newInstance(field.getZero().getClass(), length); } } commons-math-2.2-src/src/main/java/org/apache/commons/math/util/NumberTransformer.java100644 1750 1750 2733 11532241247 27646 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.util; import org.apache.commons.math.MathException; /** * Subclasses implementing this interface can transform Objects to doubles. * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ * * No longer extends Serializable since 2.0 * */ public interface NumberTransformer { /** * Implementing this interface provides a facility to transform * from Object to Double. * * @param o the Object to be transformed. * @return the double value of the Object. * @throws MathException if the Object can not be transformed into a Double. */ double transform(Object o) throws MathException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java100644 1750 1750 102427 11532241245 31744 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import java.io.Serializable; import java.lang.reflect.Array; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the * Fast Fourier Transform for transformation of one-dimensional data sets. * For reference, see Applied Numerical Linear Algebra, ISBN 0898713897, * chapter 6. *

                              * There are several conventions for the definition of FFT and inverse FFT, * mainly on different coefficient and exponent. Here the equations are listed * in the comments of the corresponding methods.

                              *

                              * We require the length of data set to be power of 2, this greatly simplifies * and speeds up the code. Users can pad the data with zeros to meet this * requirement. There are other flavors of FFT, for reference, see S. Winograd, * On computing the discrete Fourier transform, Mathematics of Computation, * 32 (1978), 175 - 199.

                              * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class FastFourierTransformer implements Serializable { /** Serializable version identifier. */ static final long serialVersionUID = 5138259215438106000L; /** roots of unity */ private RootsOfUnity roots = new RootsOfUnity(); /** * Construct a default transformer. */ public FastFourierTransformer() { super(); } /** * Transform the given real data set. *

                              * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ *

                              * * @param f the real data array to be transformed * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform(double f[]) throws IllegalArgumentException { return fft(f, false); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the complex transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = sample(f, min, max, n); return fft(data, false); } /** * Transform the given complex data set. *

                              * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ *

                              * * @param f the complex data array to be transformed * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform(Complex f[]) throws IllegalArgumentException { roots.computeOmega(f.length); return fft(f); } /** * Transform the given real data set. *

                              * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ *

                              * * @param f the real data array to be transformed * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform2(double f[]) throws IllegalArgumentException { double scaling_coefficient = 1.0 / FastMath.sqrt(f.length); return scaleArray(fft(f, false), scaling_coefficient); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the complex transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = sample(f, min, max, n); double scaling_coefficient = 1.0 / FastMath.sqrt(n); return scaleArray(fft(data, false), scaling_coefficient); } /** * Transform the given complex data set. *

                              * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ *

                              * * @param f the complex data array to be transformed * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] transform2(Complex f[]) throws IllegalArgumentException { roots.computeOmega(f.length); double scaling_coefficient = 1.0 / FastMath.sqrt(f.length); return scaleArray(fft(f), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ *

                              * * @param f the real data array to be inversely transformed * @return the complex inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform(double f[]) throws IllegalArgumentException { double scaling_coefficient = 1.0 / f.length; return scaleArray(fft(f, true), scaling_coefficient); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the complex inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = sample(f, min, max, n); double scaling_coefficient = 1.0 / n; return scaleArray(fft(data, true), scaling_coefficient); } /** * Inversely transform the given complex data set. *

                              * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ *

                              * * @param f the complex data array to be inversely transformed * @return the complex inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform(Complex f[]) throws IllegalArgumentException { roots.computeOmega(-f.length); // pass negative argument double scaling_coefficient = 1.0 / f.length; return scaleArray(fft(f), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ *

                              * * @param f the real data array to be inversely transformed * @return the complex inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform2(double f[]) throws IllegalArgumentException { double scaling_coefficient = 1.0 / FastMath.sqrt(f.length); return scaleArray(fft(f, true), scaling_coefficient); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the complex inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = sample(f, min, max, n); double scaling_coefficient = 1.0 / FastMath.sqrt(n); return scaleArray(fft(data, true), scaling_coefficient); } /** * Inversely transform the given complex data set. *

                              * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ *

                              * * @param f the complex data array to be inversely transformed * @return the complex inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public Complex[] inversetransform2(Complex f[]) throws IllegalArgumentException { roots.computeOmega(-f.length); // pass negative argument double scaling_coefficient = 1.0 / FastMath.sqrt(f.length); return scaleArray(fft(f), scaling_coefficient); } /** * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse). * * @param f the real data array to be transformed * @param isInverse the indicator of forward or inverse transform * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ protected Complex[] fft(double f[], boolean isInverse) throws IllegalArgumentException { verifyDataSet(f); Complex F[] = new Complex[f.length]; if (f.length == 1) { F[0] = new Complex(f[0], 0.0); return F; } // Rather than the naive real to complex conversion, pack 2N // real numbers into N complex numbers for better performance. int N = f.length >> 1; Complex c[] = new Complex[N]; for (int i = 0; i < N; i++) { c[i] = new Complex(f[2*i], f[2*i+1]); } roots.computeOmega(isInverse ? -N : N); Complex z[] = fft(c); // reconstruct the FFT result for the original array roots.computeOmega(isInverse ? -2*N : 2*N); F[0] = new Complex(2 * (z[0].getReal() + z[0].getImaginary()), 0.0); F[N] = new Complex(2 * (z[0].getReal() - z[0].getImaginary()), 0.0); for (int i = 1; i < N; i++) { Complex A = z[N-i].conjugate(); Complex B = z[i].add(A); Complex C = z[i].subtract(A); //Complex D = roots.getOmega(i).multiply(Complex.I); Complex D = new Complex(-roots.getOmegaImaginary(i), roots.getOmegaReal(i)); F[i] = B.subtract(C.multiply(D)); F[2*N-i] = F[i].conjugate(); } return scaleArray(F, 0.5); } /** * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse). * * @param data the complex data array to be transformed * @return the complex transformed array * @throws IllegalArgumentException if any parameters are invalid */ protected Complex[] fft(Complex data[]) throws IllegalArgumentException { final int n = data.length; final Complex f[] = new Complex[n]; // initial simple cases verifyDataSet(data); if (n == 1) { f[0] = data[0]; return f; } if (n == 2) { f[0] = data[0].add(data[1]); f[1] = data[0].subtract(data[1]); return f; } // permute original data array in bit-reversal order int ii = 0; for (int i = 0; i < n; i++) { f[i] = data[ii]; int k = n >> 1; while (ii >= k && k > 0) { ii -= k; k >>= 1; } ii += k; } // the bottom base-4 round for (int i = 0; i < n; i += 4) { final Complex a = f[i].add(f[i+1]); final Complex b = f[i+2].add(f[i+3]); final Complex c = f[i].subtract(f[i+1]); final Complex d = f[i+2].subtract(f[i+3]); final Complex e1 = c.add(d.multiply(Complex.I)); final Complex e2 = c.subtract(d.multiply(Complex.I)); f[i] = a.add(b); f[i+2] = a.subtract(b); // omegaCount indicates forward or inverse transform f[i+1] = roots.isForward() ? e2 : e1; f[i+3] = roots.isForward() ? e1 : e2; } // iterations from bottom to top take O(N*logN) time for (int i = 4; i < n; i <<= 1) { final int m = n / (i<<1); for (int j = 0; j < n; j += i<<1) { for (int k = 0; k < i; k++) { //z = f[i+j+k].multiply(roots.getOmega(k*m)); final int k_times_m = k*m; final double omega_k_times_m_real = roots.getOmegaReal(k_times_m); final double omega_k_times_m_imaginary = roots.getOmegaImaginary(k_times_m); //z = f[i+j+k].multiply(omega[k*m]); final Complex z = new Complex( f[i+j+k].getReal() * omega_k_times_m_real - f[i+j+k].getImaginary() * omega_k_times_m_imaginary, f[i+j+k].getReal() * omega_k_times_m_imaginary + f[i+j+k].getImaginary() * omega_k_times_m_real); f[i+j+k] = f[j+k].subtract(z); f[j+k] = f[j+k].add(z); } } } return f; } /** * Sample the given univariate real function on the given interval. *

                              * The interval is divided equally into N sections and sample points * are taken from min to max-(max-min)/N. Usually f(x) is periodic * such that f(min) = f(max) (note max is not sampled), but we don't * require that.

                              * * @param f the function to be sampled * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the samples array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public static double[] sample(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { if (n <= 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POSITIVE_NUMBER_OF_SAMPLES, n); } verifyInterval(min, max); double s[] = new double[n]; double h = (max - min) / n; for (int i = 0; i < n; i++) { s[i] = f.value(min + i * h); } return s; } /** * Multiply every component in the given real array by the * given real number. The change is made in place. * * @param f the real array to be scaled * @param d the real scaling coefficient * @return a reference to the scaled array */ public static double[] scaleArray(double f[], double d) { for (int i = 0; i < f.length; i++) { f[i] *= d; } return f; } /** * Multiply every component in the given complex array by the * given real number. The change is made in place. * * @param f the complex array to be scaled * @param d the real scaling coefficient * @return a reference to the scaled array */ public static Complex[] scaleArray(Complex f[], double d) { for (int i = 0; i < f.length; i++) { f[i] = new Complex(d * f[i].getReal(), d * f[i].getImaginary()); } return f; } /** * Returns true if the argument is power of 2. * * @param n the number to test * @return true if the argument is power of 2 */ public static boolean isPowerOf2(long n) { return (n > 0) && ((n & (n - 1)) == 0); } /** * Verifies that the data set has length of power of 2. * * @param d the data array * @throws IllegalArgumentException if array length is not power of 2 */ public static void verifyDataSet(double d[]) throws IllegalArgumentException { if (!isPowerOf2(d.length)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POWER_OF_TWO_CONSIDER_PADDING, d.length); } } /** * Verifies that the data set has length of power of 2. * * @param o the data array * @throws IllegalArgumentException if array length is not power of 2 */ public static void verifyDataSet(Object o[]) throws IllegalArgumentException { if (!isPowerOf2(o.length)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POWER_OF_TWO_CONSIDER_PADDING, o.length); } } /** * Verifies that the endpoints specify an interval. * * @param lower lower endpoint * @param upper upper endpoint * @throws IllegalArgumentException if not interval */ public static void verifyInterval(double lower, double upper) throws IllegalArgumentException { if (lower >= upper) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL, lower, upper); } } /** * Performs a multi-dimensional Fourier transform on a given array. * Use {@link #inversetransform2(Complex[])} and * {@link #transform2(Complex[])} in a row-column implementation * in any number of dimensions with O(N×log(N)) complexity with * N=n1×n2×n3×...×nd, * nx=number of elements in dimension x, * and d=total number of dimensions. * * @param mdca Multi-Dimensional Complex Array id est Complex[][][][] * @param forward inverseTransform2 is preformed if this is false * @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][] * @throws IllegalArgumentException if any dimension is not a power of two */ public Object mdfft(Object mdca, boolean forward) throws IllegalArgumentException { MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix) new MultiDimensionalComplexMatrix(mdca).clone(); int[] dimensionSize = mdcm.getDimensionSizes(); //cycle through each dimension for (int i = 0; i < dimensionSize.length; i++) { mdfft(mdcm, forward, i, new int[0]); } return mdcm.getArray(); } /** * Performs one dimension of a multi-dimensional Fourier transform. * * @param mdcm input matrix * @param forward inverseTransform2 is preformed if this is false * @param d index of the dimension to process * @param subVector recursion subvector * @throws IllegalArgumentException if any dimension is not a power of two */ private void mdfft(MultiDimensionalComplexMatrix mdcm, boolean forward, int d, int[] subVector) throws IllegalArgumentException { int[] dimensionSize = mdcm.getDimensionSizes(); //if done if (subVector.length == dimensionSize.length) { Complex[] temp = new Complex[dimensionSize[d]]; for (int i = 0; i < dimensionSize[d]; i++) { //fft along dimension d subVector[d] = i; temp[i] = mdcm.get(subVector); } if (forward) temp = transform2(temp); else temp = inversetransform2(temp); for (int i = 0; i < dimensionSize[d]; i++) { subVector[d] = i; mdcm.set(temp[i], subVector); } } else { int[] vector = new int[subVector.length + 1]; System.arraycopy(subVector, 0, vector, 0, subVector.length); if (subVector.length == d) { //value is not important once the recursion is done. //then an fft will be applied along the dimension d. vector[d] = 0; mdfft(mdcm, forward, d, vector); } else { for (int i = 0; i < dimensionSize[subVector.length]; i++) { vector[subVector.length] = i; //further split along the next dimension mdfft(mdcm, forward, d, vector); } } } return; } /** * Complex matrix implementation. * Not designed for synchronized access * may eventually be replaced by jsr-83 of the java community process * http://jcp.org/en/jsr/detail?id=83 * may require additional exception throws for other basic requirements. */ private static class MultiDimensionalComplexMatrix implements Cloneable { /** Size in all dimensions. */ protected int[] dimensionSize; /** Storage array. */ protected Object multiDimensionalComplexArray; /** Simple constructor. * @param multiDimensionalComplexArray array containing the matrix elements */ public MultiDimensionalComplexMatrix(Object multiDimensionalComplexArray) { this.multiDimensionalComplexArray = multiDimensionalComplexArray; // count dimensions int numOfDimensions = 0; for (Object lastDimension = multiDimensionalComplexArray; lastDimension instanceof Object[];) { final Object[] array = (Object[]) lastDimension; numOfDimensions++; lastDimension = array[0]; } // allocate array with exact count dimensionSize = new int[numOfDimensions]; // fill array numOfDimensions = 0; for (Object lastDimension = multiDimensionalComplexArray; lastDimension instanceof Object[];) { final Object[] array = (Object[]) lastDimension; dimensionSize[numOfDimensions++] = array.length; lastDimension = array[0]; } } /** * Get a matrix element. * @param vector indices of the element * @return matrix element * @exception IllegalArgumentException if dimensions do not match */ public Complex get(int... vector) throws IllegalArgumentException { if (vector == null) { if (dimensionSize.length > 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, 0, dimensionSize.length); } return null; } if (vector.length != dimensionSize.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, vector.length, dimensionSize.length); } Object lastDimension = multiDimensionalComplexArray; for (int i = 0; i < dimensionSize.length; i++) { lastDimension = ((Object[]) lastDimension)[vector[i]]; } return (Complex) lastDimension; } /** * Set a matrix element. * @param magnitude magnitude of the element * @param vector indices of the element * @return the previous value * @exception IllegalArgumentException if dimensions do not match */ public Complex set(Complex magnitude, int... vector) throws IllegalArgumentException { if (vector == null) { if (dimensionSize.length > 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, 0, dimensionSize.length); } return null; } if (vector.length != dimensionSize.length) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, vector.length,dimensionSize.length); } Object[] lastDimension = (Object[]) multiDimensionalComplexArray; for (int i = 0; i < dimensionSize.length - 1; i++) { lastDimension = (Object[]) lastDimension[vector[i]]; } Complex lastValue = (Complex) lastDimension[vector[dimensionSize.length - 1]]; lastDimension[vector[dimensionSize.length - 1]] = magnitude; return lastValue; } /** * Get the size in all dimensions. * @return size in all dimensions */ public int[] getDimensionSizes() { return dimensionSize.clone(); } /** * Get the underlying storage array * @return underlying storage array */ public Object getArray() { return multiDimensionalComplexArray; } /** {@inheritDoc} */ @Override public Object clone() { MultiDimensionalComplexMatrix mdcm = new MultiDimensionalComplexMatrix(Array.newInstance( Complex.class, dimensionSize)); clone(mdcm); return mdcm; } /** * Copy contents of current array into mdcm. * @param mdcm array where to copy data */ private void clone(MultiDimensionalComplexMatrix mdcm) { int[] vector = new int[dimensionSize.length]; int size = 1; for (int i = 0; i < dimensionSize.length; i++) { size *= dimensionSize[i]; } int[][] vectorList = new int[size][dimensionSize.length]; for (int[] nextVector: vectorList) { System.arraycopy(vector, 0, nextVector, 0, dimensionSize.length); for (int i = 0; i < dimensionSize.length; i++) { vector[i]++; if (vector[i] < dimensionSize[i]) { break; } else { vector[i] = 0; } } } for (int[] nextVector: vectorList) { mdcm.set(get(nextVector), nextVector); } } } /** Computes the nth roots of unity. * A cache of already computed values is maintained. */ private static class RootsOfUnity implements Serializable { /** Serializable version id. */ private static final long serialVersionUID = 6404784357747329667L; /** Number of roots of unity. */ private int omegaCount; /** Real part of the roots. */ private double[] omegaReal; /** Imaginary part of the roots for forward transform. */ private double[] omegaImaginaryForward; /** Imaginary part of the roots for reverse transform. */ private double[] omegaImaginaryInverse; /** Forward/reverse indicator. */ private boolean isForward; /** * Build an engine for computing then th roots of unity */ public RootsOfUnity() { omegaCount = 0; omegaReal = null; omegaImaginaryForward = null; omegaImaginaryInverse = null; isForward = true; } /** * Check if computation has been done for forward or reverse transform. * @return true if computation has been done for forward transform * @throws IllegalStateException if no roots of unity have been computed yet */ public synchronized boolean isForward() throws IllegalStateException { if (omegaCount == 0) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET); } return isForward; } /** Computes the nth roots of unity. *

                              The computed omega[] = { 1, w, w2, ... w(n-1) } where * w = exp(-2 π i / n), i = &sqrt;(-1).

                              *

                              Note that n is positive for * forward transform and negative for inverse transform.

                              * @param n number of roots of unity to compute, * positive for forward transform, negative for inverse transform * @throws IllegalArgumentException if n = 0 */ public synchronized void computeOmega(int n) throws IllegalArgumentException { if (n == 0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.CANNOT_COMPUTE_0TH_ROOT_OF_UNITY); } isForward = n > 0; // avoid repetitive calculations final int absN = FastMath.abs(n); if (absN == omegaCount) { return; } // calculate everything from scratch, for both forward and inverse versions final double t = 2.0 * FastMath.PI / absN; final double cosT = FastMath.cos(t); final double sinT = FastMath.sin(t); omegaReal = new double[absN]; omegaImaginaryForward = new double[absN]; omegaImaginaryInverse = new double[absN]; omegaReal[0] = 1.0; omegaImaginaryForward[0] = 0.0; omegaImaginaryInverse[0] = 0.0; for (int i = 1; i < absN; i++) { omegaReal[i] = omegaReal[i-1] * cosT + omegaImaginaryForward[i-1] * sinT; omegaImaginaryForward[i] = omegaImaginaryForward[i-1] * cosT - omegaReal[i-1] * sinT; omegaImaginaryInverse[i] = -omegaImaginaryForward[i]; } omegaCount = absN; } /** * Get the real part of the kth nth root of unity * @param k index of the nth root of unity * @return real part of the kth nth root of unity * @throws IllegalStateException if no roots of unity have been computed yet * @throws IllegalArgumentException if k is out of range */ public synchronized double getOmegaReal(int k) throws IllegalStateException, IllegalArgumentException { if (omegaCount == 0) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET); } if ((k < 0) || (k >= omegaCount)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX, k, 0, omegaCount - 1); } return omegaReal[k]; } /** * Get the imaginary part of the kth nth root of unity * @param k index of the nth root of unity * @return imaginary part of the kth nth root of unity * @throws IllegalStateException if no roots of unity have been computed yet * @throws IllegalArgumentException if k is out of range */ public synchronized double getOmegaImaginary(int k) throws IllegalStateException, IllegalArgumentException { if (omegaCount == 0) { throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET); } if ((k < 0) || (k >= omegaCount)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX, k, 0, omegaCount - 1); } return isForward ? omegaImaginaryForward[k] : omegaImaginaryInverse[k]; } } } commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/FastHadamardTransformer.java100644 1750 1750 26153 11532241245 32013 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.exception.util.LocalizedFormats; /** * Implements the Fast Hadamard Transform (FHT). * Transformation of an input vector x to the output vector y. *

                              In addition to transformation of real vectors, the Hadamard transform can * transform integer vectors into integer vectors. However, this integer transform * cannot be inverted directly. Due to a scaling factor it may lead to rational results. * As an example, the inverse transform of integer vector (0, 1, 0, 1) is rational * vector (1/2, -1/2, 0, 0).

                              * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public class FastHadamardTransformer implements RealTransformer { /** {@inheritDoc} */ public double[] transform(double f[]) throws IllegalArgumentException { return fht(f); } /** {@inheritDoc} */ public double[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { return fht(FastFourierTransformer.sample(f, min, max, n)); } /** {@inheritDoc} */ public double[] inversetransform(double f[]) throws IllegalArgumentException { return FastFourierTransformer.scaleArray(fht(f), 1.0 / f.length); } /** {@inheritDoc} */ public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { final double[] unscaled = fht(FastFourierTransformer.sample(f, min, max, n)); return FastFourierTransformer.scaleArray(unscaled, 1.0 / n); } /** * Transform the given real data set. *

                              The integer transform cannot be inverted directly, due to a scaling * factor it may lead to double results.

                              * @param f the integer data array to be transformed (signal) * @return the integer transformed array (spectrum) * @throws IllegalArgumentException if any parameters are invalid */ public int[] transform(int f[]) throws IllegalArgumentException { return fht(f); } /** * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition. *
                              * Requires Nlog2N = n2n additions. *
                              *
                              * Short Table of manual calculation for N=8: *
                                *
                              1. x is the input vector we want to transform
                              2. *
                              3. y is the output vector which is our desired result
                              4. *
                              5. a and b are just helper rows
                              6. *
                              *
                                   * 
                                   * +----+----------+---------+----------+
                                   * | x  |    a     |    b    |    y     |
                                   * +----+----------+---------+----------+
                                   * | x0 | a0=x0+x1 | b0=a0+a1 | y0=b0+b1 |
                                   * +----+----------+---------+----------+
                                   * | x1 | a1=x2+x3 | b0=a2+a3 | y0=b2+b3 |
                                   * +----+----------+---------+----------+
                                   * | x2 | a2=x4+x5 | b0=a4+a5 | y0=b4+b5 |
                                   * +----+----------+---------+----------+
                                   * | x3 | a3=x6+x7 | b0=a6+a7 | y0=b6+b7 |
                                   * +----+----------+---------+----------+
                                   * | x4 | a0=x0-x1 | b0=a0-a1 | y0=b0-b1 |
                                   * +----+----------+---------+----------+
                                   * | x5 | a1=x2-x3 | b0=a2-a3 | y0=b2-b3 |
                                   * +----+----------+---------+----------+
                                   * | x6 | a2=x4-x5 | b0=a4-a5 | y0=b4-b5 |
                                   * +----+----------+---------+----------+
                                   * | x7 | a3=x6-x7 | b0=a6-a7 | y0=b6-b7 |
                                   * +----+----------+---------+----------+
                                   * 
                                   * 
                              * * How it works *
                                *
                              1. Construct a matrix with N rows and n+1 columns
                                hadm[n+1][N] *
                                (If I use [x][y] it always means [row-offset][column-offset] of a Matrix with n rows and m columns. Its entries go from M[0][0] to M[n][m])
                              2. *
                              3. Place the input vector x[N] in the first column of the matrix hadm
                              4. *
                              5. The entries of the submatrix Dtop are calculated as follows. *
                                Dtop goes from entry [0][1] to [N/2-1][n+1]. *
                                The columns of Dtop are the pairwise mutually exclusive sums of the previous column *
                              6. *
                              7. The entries of the submatrix Dbottom are calculated as follows. *
                                Dbottom goes from entry [N/2][1] to [N][n+1]. *
                                The columns of Dbottom are the pairwise differences of the previous column *
                              8. *
                              9. How Dtop and Dbottom you can understand best with the example for N=8 above. *
                              10. The output vector y is now in the last column of hadm
                              11. *
                              12. Algorithm from: http://www.archive.chipcenter.com/dsp/DSP000517F1.html
                              13. *
                              *
                              * Visually *
                                   *        +--------+---+---+---+-----+---+
                                   *        |   0    | 1 | 2 | 3 | ... |n+1|
                                   * +------+--------+---+---+---+-----+---+
                                   * |0     | x0     |       /\            |
                                   * |1     | x1     |       ||            |
                                   * |2     | x2     |   <= Dtop  =>       |
                                   * |...   | ...    |       ||            |
                                   * |N/2-1 | xN/2-1  |       \/            |
                                   * +------+--------+---+---+---+-----+---+
                                   * |N/2   | xN/2   |       /\            |
                                   * |N/2+1 | xN/2+1  |       ||            |
                                   * |N/2+2 | xN/2+2  |  <= Dbottom  =>      | which is in the last column of the matrix
                                   * |...   | ...    |       ||            |
                                   * |N     | xN/2   |        \/           |
                                   * +------+--------+---+---+---+-----+---+
                                   * 
                              * * @param x input vector * @return y output vector * @exception IllegalArgumentException if input array is not a power of 2 */ protected double[] fht(double x[]) throws IllegalArgumentException { // n is the row count of the input vector x final int n = x.length; final int halfN = n / 2; // n has to be of the form n = 2^p !! if (!FastFourierTransformer.isPowerOf2(n)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POWER_OF_TWO, n); } // Instead of creating a matrix with p+1 columns and n rows // we will use two single dimension arrays which we will use in an alternating way. double[] yPrevious = new double[n]; double[] yCurrent = x.clone(); // iterate from left to right (column) for (int j = 1; j < n; j <<= 1) { // switch columns final double[] yTmp = yCurrent; yCurrent = yPrevious; yPrevious = yTmp; // iterate from top to bottom (row) for (int i = 0; i < halfN; ++i) { // Dtop // The top part works with addition final int twoI = 2 * i; yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; } for (int i = halfN; i < n; ++i) { // Dbottom // The bottom part works with subtraction final int twoI = 2 * i; yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; } } // return the last computed output vector y return yCurrent; } /** * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition. * @param x input vector * @return y output vector * @exception IllegalArgumentException if input array is not a power of 2 */ protected int[] fht(int x[]) throws IllegalArgumentException { // n is the row count of the input vector x final int n = x.length; final int halfN = n / 2; // n has to be of the form n = 2^p !! if (!FastFourierTransformer.isPowerOf2(n)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POWER_OF_TWO, n); } // Instead of creating a matrix with p+1 columns and n rows // we will use two single dimension arrays which we will use in an alternating way. int[] yPrevious = new int[n]; int[] yCurrent = x.clone(); // iterate from left to right (column) for (int j = 1; j < n; j <<= 1) { // switch columns final int[] yTmp = yCurrent; yCurrent = yPrevious; yPrevious = yTmp; // iterate from top to bottom (row) for (int i = 0; i < halfN; ++i) { // Dtop // The top part works with addition final int twoI = 2 * i; yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; } for (int i = halfN; i < n; ++i) { // Dbottom // The bottom part works with subtraction final int twoI = 2 * i; yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; } } // return the last computed output vector y return yCurrent; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/RealTransformer.java100644 1750 1750 7053 11532241245 30335 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; /** * Interface for one-dimensional data sets transformations producing real results. *

                              Such transforms include {@link FastSineTransformer sine transform}, * {@link FastCosineTransformer cosine transform} or {@link * FastHadamardTransformer Hadamard transform}. {@link FastFourierTransformer * Fourier transform} is of a different kind and does not implement this * interface since it produces {@link org.apache.commons.math.complex.Complex complex} * results instead of real ones. *

                              * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 2.0 */ public interface RealTransformer { /** * Transform the given real data set. * @param f the real data array to be transformed (signal) * @return the real transformed array (spectrum) * @throws IllegalArgumentException if any parameters are invalid */ double[] transform(double f[]) throws IllegalArgumentException; /** * Transform the given real function, sampled on the given interval. * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ double[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException; /** * Inversely transform the given real data set. * @param f the real data array to be inversely transformed (spectrum) * @return the real inversely transformed array (signal) * @throws IllegalArgumentException if any parameters are invalid */ double[] inversetransform(double f[]) throws IllegalArgumentException; /** * Inversely transform the given real function, sampled on the given interval. * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException; } commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java100644 1750 1750 25516 11532241245 31534 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the Fast Cosine Transform * for transformation of one-dimensional data sets. For reference, see * Fast Fourier Transforms, ISBN 0849371635, chapter 3. *

                              * FCT is its own inverse, up to a multiplier depending on conventions. * The equations are listed in the comments of the corresponding methods.

                              *

                              * Different from FFT and FST, FCT requires the length of data set to be * power of 2 plus one. Users should especially pay attention to the * function transformation on how this affects the sampling.

                              *

                              As of version 2.0 this no longer implements Serializable

                              * * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $ * @since 1.2 */ public class FastCosineTransformer implements RealTransformer { /** * Construct a default transformer. */ public FastCosineTransformer() { super(); } /** * Transform the given real data set. *

                              * The formula is Fn = (1/2) [f0 + (-1)n fN] + * ∑k=1N-1 fk cos(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(double f[]) throws IllegalArgumentException { return fct(f); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = (1/2) [f0 + (-1)n fN] + * ∑k=1N-1 fk cos(π nk/N) *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); return fct(data); } /** * Transform the given real data set. *

                              * The formula is Fn = √(1/2N) [f0 + (-1)n fN] + * √(2/N) ∑k=1N-1 fk cos(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2(double f[]) throws IllegalArgumentException { double scaling_coefficient = FastMath.sqrt(2.0 / (f.length-1)); return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = √(1/2N) [f0 + (-1)n fN] + * √(2/N) ∑k=1N-1 fk cos(π nk/N) * *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); double scaling_coefficient = FastMath.sqrt(2.0 / (n-1)); return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = (1/N) [F0 + (-1)k FN] + * (2/N) ∑n=1N-1 Fn cos(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(double f[]) throws IllegalArgumentException { double scaling_coefficient = 2.0 / (f.length - 1); return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = (1/N) [F0 + (-1)k FN] + * (2/N) ∑n=1N-1 Fn cos(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); double scaling_coefficient = 2.0 / (n - 1); return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = √(1/2N) [F0 + (-1)k FN] + * √(2/N) ∑n=1N-1 Fn cos(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(double f[]) throws IllegalArgumentException { return transform2(f); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = √(1/2N) [F0 + (-1)k FN] + * √(2/N) ∑n=1N-1 Fn cos(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { return transform2(f, min, max, n); } /** * Perform the FCT algorithm (including inverse). * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ protected double[] fct(double f[]) throws IllegalArgumentException { final double transformed[] = new double[f.length]; final int n = f.length - 1; if (!FastFourierTransformer.isPowerOf2(n)) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.NOT_POWER_OF_TWO_PLUS_ONE, f.length); } if (n == 1) { // trivial case transformed[0] = 0.5 * (f[0] + f[1]); transformed[1] = 0.5 * (f[0] - f[1]); return transformed; } // construct a new array and perform FFT on it final double[] x = new double[n]; x[0] = 0.5 * (f[0] + f[n]); x[n >> 1] = f[n >> 1]; double t1 = 0.5 * (f[0] - f[n]); // temporary variable for transformed[1] for (int i = 1; i < (n >> 1); i++) { final double a = 0.5 * (f[i] + f[n-i]); final double b = FastMath.sin(i * FastMath.PI / n) * (f[i] - f[n-i]); final double c = FastMath.cos(i * FastMath.PI / n) * (f[i] - f[n-i]); x[i] = a - b; x[n-i] = a + b; t1 += c; } FastFourierTransformer transformer = new FastFourierTransformer(); Complex y[] = transformer.transform(x); // reconstruct the FCT result for the original array transformed[0] = y[0].getReal(); transformed[1] = t1; for (int i = 1; i < (n >> 1); i++) { transformed[2 * i] = y[i].getReal(); transformed[2 * i + 1] = transformed[2 * i - 1] - y[i].getImaginary(); } transformed[n] = y[n >> 1].getReal(); return transformed; } } commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/package.html100644 1750 1750 1753 11532241245 26646 0ustarlucluc 0 0 Implementations of transform methods, including Fast Fourier transforms. commons-math-2.2-src/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java100644 1750 1750 23421 11532241245 31203 0ustarlucluc 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math.transform; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.complex.Complex; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the Fast Sine Transform * for transformation of one-dimensional data sets. For reference, see * Fast Fourier Transforms, ISBN 0849371635, chapter 3. *

                              * FST is its own inverse, up to a multiplier depending on conventions. * The equations are listed in the comments of the corresponding methods.

                              *

                              * Similar to FFT, we also require the length of data set to be power of 2. * In addition, the first element must be 0 and it's enforced in function * transformation after sampling.

                              *

                              As of version 2.0 this no longer implements Serializable

                              * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class FastSineTransformer implements RealTransformer { /** * Construct a default transformer. */ public FastSineTransformer() { super(); } /** * Transform the given real data set. *

                              * The formula is Fn = ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(double f[]) throws IllegalArgumentException { return fst(f); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; return fst(data); } /** * Transform the given real data set. *

                              * The formula is Fn = √(2/N) ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2(double f[]) throws IllegalArgumentException { double scaling_coefficient = FastMath.sqrt(2.0 / f.length); return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = √(2/N) ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2( UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; double scaling_coefficient = FastMath.sqrt(2.0 / n); return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = (2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(double f[]) throws IllegalArgumentException { double scaling_coefficient = 2.0 / f.length; return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = (2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; double scaling_coefficient = 2.0 / n; return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = √(2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(double f[]) throws IllegalArgumentException { return transform2(f); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = √(2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { return transform2(f, min, max, n); } /** * Perform the FST algorithm (including inverse). * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ protected double[] fst(double f[]) throws IllegalArgumentException { final double transformed[] = new double[f.length]; FastFourierTransformer.verifyDataSet(f); if (f[0] != 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.FIRST_ELEMENT_NOT_ZERO, f[0]); } final int n = f.length; if (n == 1) { // trivial case transformed[0] = 0.0; return transformed; } // construct a new array and perform FFT on it final double[] x = new double[n]; x[0] = 0.0; x[n >> 1] = 2.0 * f[n >> 1]; for (int i = 1; i < (n >> 1); i++) { final double a = FastMath.sin(i * FastMath.PI / n) * (f[i] + f[n-i]); final double b = 0.5 * (f[i] - f[n-i]); x[i] = a + b; x[n - i] = a - b; } FastFourierTransformer transformer = new FastFourierTransformer(); Complex y[] = transformer.transform(x); // reconstruct the FST result for the original array transformed[0] = 0.0; transformed[1] = 0.5 * y[0].getReal(); for (int i = 1; i < (n >> 1); i++) { transformed[2 * i] = -y[i].getImaginary(); transformed[2 * i + 1] = y[i].getReal() + transformed[2 * i - 1]; } return transformed; } } import org.apache.commons.math.complex.Complex; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; /** * Implements the Fast Sine Transform * for transformation of one-dimensional data sets. For reference, see * Fast Fourier Transforms, ISBN 0849371635, chapter 3. *

                              * FST is its own inverse, up to a multiplier depending on conventions. * The equations are listed in the comments of the corresponding methods.

                              *

                              * Similar to FFT, we also require the length of data set to be power of 2. * In addition, the first element must be 0 and it's enforced in function * transformation after sampling.

                              *

                              As of version 2.0 this no longer implements Serializable

                              * * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ * @since 1.2 */ public class FastSineTransformer implements RealTransformer { /** * Construct a default transformer. */ public FastSineTransformer() { super(); } /** * Transform the given real data set. *

                              * The formula is Fn = ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(double f[]) throws IllegalArgumentException { return fst(f); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; return fst(data); } /** * Transform the given real data set. *

                              * The formula is Fn = √(2/N) ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2(double f[]) throws IllegalArgumentException { double scaling_coefficient = FastMath.sqrt(2.0 / f.length); return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); } /** * Transform the given real function, sampled on the given interval. *

                              * The formula is Fn = √(2/N) ∑k=0N-1 fk sin(π nk/N) *

                              * * @param f the function to be sampled and transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real transformed array * @throws FunctionEvaluationException if function cannot be evaluated * at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] transform2( UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; double scaling_coefficient = FastMath.sqrt(2.0 / n); return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = (2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(double f[]) throws IllegalArgumentException { double scaling_coefficient = 2.0 / f.length; return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = (2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { double data[] = FastFourierTransformer.sample(f, min, max, n); data[0] = 0.0; double scaling_coefficient = 2.0 / n; return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); } /** * Inversely transform the given real data set. *

                              * The formula is fk = √(2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the real data array to be inversely transformed * @return the real inversely transformed array * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(double f[]) throws IllegalArgumentException { return transform2(f); } /** * Inversely transform the given real function, sampled on the given interval. *

                              * The formula is fk = √(2/N) ∑n=0N-1 Fn sin(π nk/N) *

                              * * @param f the function to be sampled and inversely transformed * @param min the lower bound for the interval * @param max the upper bound for the interval * @param n the number of sample points * @return the real inversely transformed array * @throws FunctionEvaluationException if function cannot be evaluated at some point * @throws IllegalArgumentException if any parameters are invalid */ public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n) throws FunctionEvaluationException, IllegalArgumentException { return transform2(f, min, max, n); } /** * Perform the FST algorithm (including inverse). * * @param f the real data array to be transformed * @return the real transformed array * @throws IllegalArgumentException if any parameters are invalid */ protected double[] fst(double f[]) throws IllegalArgumentException { final double transformed[] = new double[f.length]; FastFourierTransformer.verifyDataSet(f); if (f[0] != 0.0) { throw MathRuntimeException.createIllegalArgumentException( LocalizedFormats.FIRST_ELEMENT_NOT_ZERO, f[0]); } final int n = f.length; if (n == 1) { // trivial case transformed[0] = 0.0; return transformed; } // construct a new array and perform FFT on it final double[] x = new double[n]; x[0] = 0.0; x[n >> 1] = 2.0 * f[n >> 1]; for (int i = 1; i < (n >> 1); i++) { final double a = FastMath.sin(i * FastMath.PI / n) * (f[i] + f[n-i]); final double b = 0.5 * (f[i] - f[n-i]); x[i] = a + b; x[n - i] = a - b; } FastFourierTransformer transformer = new FastFourierTransformer(); Complex y[] = transformer.transform(x); // reconstruct the FST result for the original array transformed[0] = 0.0; transformed[1] = 0.5 * y[0].getReal(); for (int i = 1; i < (n >> 1); i++) { transformed[2 * i] = -y[i].getImaginary(); transformed[2 * i + 1] = y[i].getReal() + transformed[2 * i - 1]; } return transformed; } }